移动端布局rem与vw的区别

目录

1. rem 

2. rem的弊端与优点

3. rem布局前注意点

4. vw

5. vw单位和%单位对比

6. vw布局前注意点

7. vue项目中使用vw


1. rem 

先简单说下rem,官当文档是这样说的:

rem是css中的长度单位,1rem = 根元素html的font-size值。当页面中所有元素都使用rem单位时,你只需要改变根元素 font-size 值,所有元素就会按比例放大或者缩小。因此我们只需要写一小段js代码,根据屏幕宽度改变 html 的 font-size 值,就可以做到弹性布局。这种方法确实便捷,兼容性也很好,是目前非常主流的弹性布局方案。

这里提供一篇完整的、动态的、改变html标签的 font-size 大小的js代码:

(function flexible (window, document) {
  var docEl = document.documentElement
  var dpr = window.devicePixelRatio || 1

  // adjust body font size
  function setBodyFontSize () {
    if (document.body) {
      document.body.style.fontSize = (12 * dpr) + 'px'
    }
    else {
      document.addEventListener('DOMContentLoaded', setBodyFontSize)
    }
  }
  setBodyFontSize();

  // set 1rem = viewWidth / 10
  function setRemUnit () {
    var rem = docEl.clientWidth / 10
    docEl.style.fontSize = rem + 'px'
  }

  setRemUnit()

  // reset rem unit on page resize
  window.addEventListener('resize', setRemUnit)
  window.addEventListener('pageshow', function (e) {
    if (e.persisted) {
      setRemUnit()
    }
  })

  // detect 0.5px supports
  if (dpr >= 2) {
    var fakeBody = document.createElement('body')
    var testElement = document.createElement('div')
    testElement.style.border = '.5px solid transparent'
    fakeBody.appendChild(testElement)
    docEl.appendChild(fakeBody)
    if (testElement.offsetHeight === 1) {
      docEl.classList.add('hairlines')
    }
    docEl.removeChild(fakeBody)
  }
}(window, document))

2. rem的弊端与优点

rem布局,需要在html文件头部放入一大段压缩过的js代码很难受,vw则能让你的代码更纯粹!

弊端之一:和根元素font-size值强耦合,系统字体放大或缩小时,会导致布局错乱

弊端之二:html文件头部需插入一段js代码

rem的优点:移动端rem布局比vw主流的原因 兼容性

vw单位兼容性比rem稍差,ios8、安卓4.4及以上才完全支持。

3. rem布局前注意点

① 视口设置完整

② 设计图在量取的时候可以直接按照1倍图量取

③ 安装插件 px2rem 自动换算,插件中默认html的 font-size 的大小为16px,所以默认是除以16的,如果需要更改,需要进行配置( 如:设计图是375,html标签的font-size的大小为37.5px,此时应该除以37.5 )

移动端布局rem与vw的区别_第1张图片

4. vw

我们先来看看 vw vh 单位,w3c的官方解释:

vw:1% of viewport’s width  // 视口宽度的 1%
vh:1% of viewport’s height  // 视口高度的 1%

vmin:vw和vh中最小的那一个

vmax:vw和vh中最大的那一个

viewport 即浏览器可视区域大小
我们可以这样理解 100vw = window.innerwidth, 100vh = window.innerheight
在移动端我们可以认为,100vw 就是屏幕宽度。

5. vw单位和%单位对比

百分比%是根据父元素宽度或者高度进行计算,而vw vh固定按照viewport来计算,不会受父元素宽高度影响。
100vw包括了页面滚动条宽度(页面滚动条属于viewport范围内,100vw当然包括了页面滚动条宽度)。但把body或者html设置为width:100%时,是不包括页面滚动条的宽度的。也就是说100vw在有纵向滚动条的情况下,会比100%宽。 那么就会引发一个问题:pc端使用vw单位时,如果页面内容超出一屏长度,会出现了纵向滚动条,同时有元素width:100vw, 则会导致出现条横向滚动条,因为元素(100vw + 滚动条宽度)超出了viewport宽度。(移动端滚动条不占位,所以不会有这个问题)不过pc端一般不需要弹性布局,还是尽量使用width:100%更保险。

6. vw布局前注意点

① 确定设计稿的宽度(视口的宽度),得到 1vw = 视口的宽度的1%

② vw单位的尺寸 = px / 1vw

例如:

设计稿的宽度是 375px,那么 1vw = 375 / 100 = 3.75px

元素在设计稿中测量出的宽度是 450px

那么就把元素的width设置为 450 / 3.75 = 120vw

③ 能偷懒必须偷懒,咱们可以安装 px2vw 插件自动换算

移动端布局rem与vw的区别_第2张图片

④  选择vscode中的设置,搜索 px2vw,设置当前量取的设计稿的尺寸(默认是750)

移动端布局rem与vw的区别_第3张图片

7. vue项目中使用vw

① 安装 postcss-px-to-viewport 依赖

npm install postcss-px-to-viewport -D
# or
yarn add -D postcss-px-to-viewport
# or
pnpm add -D postcss-px-to-viewport

② 项目根目录下新建 postcss.config.js ,配置如下

// eslint-disable-next-line no-undef
module.exports = {
  plugins: {
    'postcss-px-to-viewport': {
      // 视口宽度375计算vw的值,根据实际情况来修改
      viewportWidth: 375
    }
  }
}

③ 有一个控制台警告可忽略,或者使用 postcss-px-to-viewport-8-plugin 代替当前插件

④ 有了 postcss-px-to-viewport,我们在布局的时候直接写固定px,项目 npm run dev或 npm run build 后会自动将 px 转换成 vw

⑤ 一些特殊的情况,像1px不进行转换,忽略某些文件内的px,可以继续操作 postcss.config.js

module.exports = {
		plugins: {
	        autoprefixer: {},
	        "postcss-px-to-viewport": {
	            viewportWidth: 375, //视口的宽度,对应的时设计稿的宽度/2,一般为750,对应iPhone6的宽度
	            viewportHeight: 667, //视口的高度,对应的是设计稿的高度(也可以不配置)
	            unitPrecision: 5, //指定‘px’转换为视口单位值的小数位数(很多时候无法整除)小数位为5位
	            viewportUnit: 'vw', //指定需要转换成的视口单位,建议使用vw(宽度)
	            selectorBlankList: ['ignore'], //指定不需要转换的类(class类名,使用ignore,在元素的class里加入ignore,则该元素里的px不会进行转化)
	            minPixelValue: 1, //小于或等于‘1px’不转换为视口单位
	            mediaQuery: false,//允许在媒体查询中转换为‘px’,使用媒体查询,再对一些东西进行配置
            	exclude: [/TabBar/]  //不需要转化的组件文件名正则,必须是正则表达式
        }
    }
}

你可能感兴趣的:(前端,html,css)