响应式布局和自适应

写网页时,经常要求要适配不同屏幕,要求可以在大屏幕,ipad,手机上可以显示正常。对于公司的官网这是很重要的。那么,这就涉及到了响应式布局和自适应。



文章目录

  • 响应式布局和自适应
  • 前言
  • 一、响应式布局
  • 二、自适应
  • 根字体大小rem
  • 方案一:postcss-px2rem+setRem()
  • 方案二:flexible和 postcss-px2rem
  • 总结



前言

如果对网站的适应方面要求多的话,例如移动端的排版要求变动比较大,可以做成两个版本:pc版本和h5版本(移动端),可以参考京东。
pc版本显示如下(jd.com):

h5 rem 响应式根元素_自适应


当你切换到移动端显示的时候,如下图:

h5 rem 响应式根元素_响应式布局_02

今天,讲讲怎么做适应

一、响应式布局

h5 rem 响应式根元素_vue.js_03

像这种,随着屏幕宽度做出不同的布局的,就是响应式布局,即响应不同屏幕大小的布局。
响应式屏幕的断点有以下几种:

Breakpoint

Class infix

Dimensions

X-Samll(超小屏幕)

None

<576px

Samll(小屏幕)

sm

>=576px

Medium(平板)

md

>=768px

Large(电脑小屏幕)

lg

>=992px

Extra large(电脑大屏幕)

xl

>=1200px

Extra extra large(电脑超大屏幕)

xxl

>=1400px

h5 rem 响应式根元素_自适应_04


根据需求,通过媒体查询不同屏幕宽度时,对界面样式的宽高,边距等进行改动

//以屏幕最小值作为媒体查询时:
// Extra small devices (portrait phones, less than 576px)
// No media query for `xs` since this is the default in Bootstrap

// Small devices (landscape phones, 576px and up)
@media (min-width: 576px) { ... }

// Medium devices (tablets, 768px and up)
@media (min-width: 768px) { ... }

// Large devices (desktops, 992px and up)
@media (min-width: 992px) { ... }

// Extra large devices (large desktops, 1200px and up)
@media (min-width: 1200px) { ... }
//以屏幕最大值作为媒体查询时:
// Extra small devices (portrait phones, less than 576px)
@media (max-width: 575.98px) { ... }

// Small devices (landscape phones, less than 768px)
@media (max-width: 767.98px) { ... }

// Medium devices (tablets, less than 992px)
@media (max-width: 991.98px) { ... }

// Large devices (desktops, less than 1200px)
@media (max-width: 1199.98px) { ... }

// Extra large devices (large desktops)
// No media query since the extra-large breakpoint has no upper bound on its width

利用Boostrap的Display的样式,对于不同屏幕时的dom元素可以进行隐藏。

//例如中等屏幕时,隐藏;其他屏幕时,显示
.d-md-none .d-lg-block

还可以使用里面的grid布局,针对不同屏幕表现不同的宽

<div class="container">
  <div class="row justify-content-md-center">
    <div class="col col-lg-2">
      1 of 3
    </div>
    <div class="col-md-auto">
      Variable width content
    </div>
    <div class="col col-lg-2">
      3 of 3
    </div>
  </div>
  <div class="row">
    <div class="col">
      1 of 3
    </div>
    <div class="col-md-auto">
      Variable width content
    </div>
    <div class="col col-lg-2">
      3 of 3
    </div>
  </div>
</div>

综上,响应式布局用boostrap的css文件样式就够用了

二、自适应

当在移动端显示时,要求适应不同的手机屏幕,一般叫做自适应。可以说自适应是响应式布局的超集。但是两者的偏重点有所不同,自适应多指移动端,响应式多种pc端。
当pc端的版式宽高与手机端的版式宽高差别较大时,频繁的媒体查询更改样式会特别繁琐,相当于把所有元素的宽高都改了一遍。这时何不做一个h5版本的自适应网页呢?

根字体大小rem

rem就是html的字体大小,假设所有元素的宽高根据rem来设定,那么只要改变rem的大小,就可以实现全部元素的等比缩放。

方案一:postcss-px2rem+setRem()

PostCSS 的一个插件,可以从像素单位生成 rem 单位

//使用postcss-plugin-px2rem,推荐
npm i --save postcss-plugin-px2rem
//vue-cli3的配置文件中
  css: {
    loaderOptions: {
      postcss: {
        plugins: [
            require('postcss-plugin-px2rem')({  //配置postcss-plugin-px2rem适配
                rootValue:75, //换算基数,设置根字体75px,可以设为设计稿的十分之一(假设750px)。这样子写页面样式就直接写设计稿的宽高
                unitPrecision: 5, //允许REM单位增长到的十进制数字。
                //propWhiteList: [],  //默认值是一个空数组,这意味着禁用白名单并启用所有属性。
                // propBlackList: [], //黑名单
                exclude: /(node_module)/,  //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
                // selectorBlackList: [], //要忽略并保留为px的选择器
                // ignoreIdentifier: false,  //(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
                // replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
                mediaQuery: false,  //(布尔值)允许在媒体查询中转换px。
                // minPixelValue: 3 //设置要替换的最小像素值(3px会被转rem)。 默认 0
            }),
        ]
    }
    }

  },

//使用postcss-px2rem,这个插件没有排除node_module的选项
npm i postcss-px2rem --save -dev
//vue-cli3的配置文件中
   postcss: {
      plugins: [
        //假如设计图给的宽度是750,我们通常就会把remUnit设置为75,这样我们写样式时,可以直接按照设计图标注的宽高来1:1还原开发。
        require('postcss-px2rem')({
          remUnit: 75
        })
      ]
    }

配合js文件,动态计算:

// REM是根据根结点来计算各个子节点的值,所以根结点也要做响应式变化。utils/setRem.js
export default function setRem() {
 const baseWidth = 750;//设计稿大小
  const dpr = window.devicePixelRatio;
  const currentWidth = document.documentElement.clientWidth;
  // 屏幕宽度大于780px,不再放大字体
 currentWidth = currentWidth < 780 ? currentWidth : 780;
  let remSize = 0;
  let scale = 0;
  scale = currentWidth / baseWidth;
  //当我们在iphone6上显示时,满屏宽度是375px,即currentWidth是375px,最终得到的rem是37.5px。所以页面元素进行收缩
  remSize = baseWidth / 10;
  remSize = remSize * scale;
  document.documentElement.style.fontSize = remSize + 'px';
  document.documentElement.setAttribute('data-dpr', `${dpr}`);
}
setRem()
window.addEventListener("resize", setRem, false);//窗口大小发生改变
window.addEventListener("orientationchange", setRem, false); //移动端翻转屏幕

然后在main.js引入即可

方案二:flexible和 postcss-px2rem

postcss-px2rem可以换成postcss-plugin-px2rem
点击此处查看详情flexible和 postcss-px2rem

npm install lib-flexible --save-dev
npm i --save postcss-plugin-px2rem

可以看到在iphone6/7/8 375x667下,lib-flexible插件设置的根字体大小是它的物理像素750、10=75,然后缩小一半来适配逻辑像素375

h5 rem 响应式根元素_响应式布局_05


方案三:vw适配

这种方案不需要额外的js,更加简单明了。更多人使用。

postcss-px-to-viewport

postcss:{
        plugins:[
          require('postcss-px-to-viewport')({
            unitToConvert: 'px',//(String) 需要转换的单位,默认为"px"
          viewportWidth: 375, // (Number) 设计稿的视口宽度,一般是750
          unitPrecision: 3, //  (Number) 单位转换后保留的精度(很多时候无法整除)
          viewportUnit: 'vw', // (String) 希望使用的视口单位
          selectorBlackList: ['.ignore', '.hairlines'], //需要忽略的CSS选择器
          minPixelValue: 1, // (Number) 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
          mediaQuery: true, // (Boolean) 媒体查询里的单位是否需要转换单位
          exclude:[/^node_modules$/],// (Array or Regexp) 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
          //include:/\/src\/mobile\//  
          landscapeUnit:'vw' , //横屏时使用的单位
          landscapeWidth:750  //横屏时使用的视口宽度
          })
        ]
        
      }

总结

本文讲解了响应式布局和移动端自适应,其中移动端自适应有三种方案,自行根据需要添加