基础
vw
:视口单位,通常来说,100vw
等于浏览器可见宽度,1vw表示1%的屏幕宽度。rem
:CSS布局单位,1rem
等于html
标签的font-size
属性值大小。
vw方案
如果设计稿是按照iphone6来设计的(iphone6实际宽度 375px),而设计稿上的宽度是750px,实现自适应方案如下:
html {
/* 除以的7.5是根据设计稿的屏幕宽度来定的,这样750px宽度下根元素字体大小则为750px/7.5=100px=1rem */
font-size: calc(100vw / 7.5);
/* 同时,通过Media Queries 限制根元素字体最大最小值,否则随着屏幕宽度变大会无限放大字体 */
@media screen and (max-width: 320px) {
font-size: 64px;
}
@media screen and (min-width: 540px) {
font-size: 108px;
}
}
/* body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小 */
body {
max-width: 540px;
min-width: 320px;
}
#app {
font-size: initial;//重置页面字体大小恢复为浏览器默认16px,否则就显示成50px了
}
其中,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 处理不支持视窗单位的设备
document.documentElement.style.fontSize = window.innerWidth/7.5 + 'px'
ps:之所以让1rem等于50px,而不是1rem等于1px,是因为在chrome下针对中文的最小字体是12px。
缺点:需要自己手动计算,无法自动换算元素单位为px
postcss方案(推荐)
我用的是vue-cli4脚手架搭建的,首先初始化完项目,再安装相关的依赖
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同级
module.exports = {
"plugins": {
// "postcss-import": {},
// "postcss-url": {},
// to edit target browsers: use "browserslist" field in package.json
"postcss-write-svg": {
uft8: false
},
"postcss-cssnext": {},
"postcss-px-to-viewport": {
viewportWidth: 750, // 设计稿宽度
viewportHeight: 1334, // 设计稿高度,可以不指定
unitPrecision: 3, // px to vw无法整除时,保留几位小数
viewportUnit: 'vw', // 转换成vw单位
selectorBlackList: ['.ignore', '.hairlines'], // 不转换的类名
minPixelValue: 1, // 小于1px不转换
mediaQuery: false, // 允许媒体查询中转换
exclude: /(/|)(node_modules)(/|)/ //不转换我们引入的第三方包
},
"postcss-viewport-units": {},
"cssnano": {
preset: "advanced",
autoprefixer: false, // 和cssnext同样具有autoprefixer,保留一个
"postcss-zindex": false
}
}
}
删除package.json的browserslist的 "not dead"