基础

  1. vw视口单位,通常来说,100vw等于浏览器可见宽度,1vw表示1%的屏幕宽度。
  2. rem:CSS布局单位,1rem等于html标签的font-size属性值大小。

vw方案

如果设计稿是按照iphone6来设计的(iphone6实际宽度 375px),而设计稿上的宽度是750px,实现自适应方案如下:

  1. html {
  2. /* 除以的7.5是根据设计稿的屏幕宽度来定的,这样750px宽度下根元素字体大小则为750px/7.5=100px=1rem */
  3. font-size: calc(100vw / 7.5);
  4. /* 同时,通过Media Queries 限制根元素字体最大最小值,否则随着屏幕宽度变大会无限放大字体 */
  5. @media screen and (max-width: 320px) {
  6. font-size: 64px;
  7. }
  8. @media screen and (min-width: 540px) {
  9. font-size: 108px;
  10. }
  11. }
  12. /* body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小 */
  13. body {
  14. max-width: 540px;
  15. min-width: 320px;
  16. }
  17. #app {
  18. font-size: initial;//重置页面字体大小恢复为浏览器默认16px,否则就显示成50px了
  19. }

其中,100vw是设备宽度deviceWidth,这样就实现了不同设备宽度下,动态修改根字体font-size的大小,比如:
deviceWidth = 320,font-size = 320 / 7.5 = 42.6667px //iphone5
deviceWidth = 375,font-size = 375 / 7.5 = 50px //iphone678 X
deviceWidth = 414,font-size = 414 / 7.5 = 55.2px //iphone678 plus

设计思路就是,根据设计稿将html的font-size设置为100px。比如750的设计稿,就除以7.5
这样设计的原因是:实现适配只要在代码里把宽高直接将设计稿的尺寸除以100即可,换算很方便。

vw单位,在低版本的设备可能不支持,再配合 js 处理不支持视窗单位的设备

  1. document.documentElement.style.fontSize = window.innerWidth/7.5 + 'px'

ps:之所以让1rem等于50px,而不是1rem等于1px,是因为在chrome下针对中文的最小字体是12px。

缺点:需要自己手动计算,无法自动换算元素单位为px

postcss方案(推荐)

我用的是vue-cli4脚手架搭建的,首先初始化完项目,再安装相关的依赖

  1. yarn add cssnano cssnano-preset-advanced postcss-aspect-ratio-mini postcss-cssnext postcss-px-to-viewport postcss-px-to-viewport-opt postcss-viewport-units postcss-write-svg

配置postCss文件项目的根目录文件夹 postcss.config.js 跟package.json同级

  1. module.exports = {
  2. "plugins": {
  3. // "postcss-import": {},
  4. // "postcss-url": {},
  5. // to edit target browsers: use "browserslist" field in package.json
  6. "postcss-write-svg": {
  7. uft8: false
  8. },
  9. "postcss-cssnext": {},
  10. "postcss-px-to-viewport": {
  11. viewportWidth: 750, // 设计稿宽度
  12. viewportHeight: 1334, // 设计稿高度,可以不指定
  13. unitPrecision: 3, // px to vw无法整除时,保留几位小数
  14. viewportUnit: 'vw', // 转换成vw单位
  15. selectorBlackList: ['.ignore', '.hairlines'], // 不转换的类名
  16. minPixelValue: 1, // 小于1px不转换
  17. mediaQuery: false, // 允许媒体查询中转换
  18. exclude: /(/|)(node_modules)(/|)/ //不转换我们引入的第三方包
  19. },
  20. "postcss-viewport-units": {},
  21. "cssnano": {
  22. preset: "advanced",
  23. autoprefixer: false, // 和cssnext同样具有autoprefixer,保留一个
  24. "postcss-zindex": false
  25. }
  26. }
  27. }

删除package.json的browserslist的 "not dead"
image.png