移动端布局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布局前注意点

① 视口设置完整

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />

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

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

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 插件自动换算

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

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/]  //不需要转化的组件文件名正则,必须是正则表达式
        }
    }
}

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用`node-sass`和`sass-loader`来解析`.scss`文件,同时使用`postcss-loader`和`autoprefixer`来自动添加浏览器厂商前缀,最后使用`css-loader`和`style-loader`将CSS样式注入到HTML页面中。 在Vue项目中,可以在`vue.config.js`文件中进行配置: ```javascript module.exports = { css: { loaderOptions: { sass: { prependData: ` @import "@/assets/scss/_variables.scss"; @import "@/assets/scss/_mixins.scss"; ` }, postcss: { plugins: [ require('autoprefixer')({ overrideBrowserslist: ['last 2 versions', '>1%'] }) ] } } } } ``` 然后,可以在`.vue`文件中使用`<style lang="scss">`标签来编写Sass样式,例如: ```scss // _variables.scss $base-font-size: 16px; $base-width: 750px; // _mixins.scss @function px2rem($px) { @return ($px / $base-font-size) * 1rem; } @mixin center() { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } // index.vue <style lang="scss"> .container { width: $base-width; margin: 0 auto; } .title { font-size: px2rem(32px); margin-top: px2rem(20px); } .box { width: 50vw; height: 50vh; background-color: #f00; @include center(); } </style> <template> <div class="container"> <h1 class="title">Hello World!</h1> <div class="box"></div> </div> </template> ``` 以上示例中,`$base-font-size`和`$base-width`变量定义在`_variables.scss`中,`px2rem()`和`center()`混合宏定义在`_mixins.scss`中,然后在`index.vue`中引入并使用它们来实现移动端自适应布局

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值