为什么需要移动端适配?
现如今,web页面已经不局限于在PC端运行,也需要在移动端运行。而移动端的机型是非常多的,所以我们常常需要将页面做一个移动端适配,使其能在不同的终端完美运行。
适配方案
1. rem适配
原理
rem是css3新增的一个相对单位,当使用rem为元素设定字体大小时,相对的是HTML根元素的字体大小。例如你给html设置font-size为16px,html中的div元素设置font-size为1rem,则这1rem也是16px。
rem适配的原理是布局等比例缩放,我们可以动态控制html中font-size的大小来改变rem的大小。
实现方法
1. 设置视口viewport
在移动端配置视口的方法是设置一个meta标签:
<meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1; minimum-scale=1; user-scalable=no;">
其中,width为定义视口的宽度,height为定义视口的高度,initial-scale为定义初始缩放值,maximum-scale和minimum-scale分别为定义放大最大和缩小最小比例,user-scalable指是否允许用户手动缩放页面。上面的meta标签例子是将scale设置为固定1倍视口的大小。
如果我们不去设置,则浏览器的默认设置为:viewport=980,initial-scale为空
让我们看看设置与不设置viewport的区别:
不设置:
设置:
同样设置宽高为300px的正方形,可以看出,当设置viewport时,会有一个缩放效果。
我们也可以根据设备像素比例devicePixelRatio的值来缩放viewport,代码如下:
let viewport = document.querySelector('meta[name=viewport]')
let dpr = window.devicePixelRatio || 1
let scale = 1 / dpr
viewport.setAttribute(
"content",
"width=device-width" +
",initial-scale=" +
scale +
", maximum-scale=" +
scale +
", minimum-scale=" +
scale +
", user-scalable=no"
)
这样我们就可以实现元素在不同设备下有不同的缩放效果
缺点:边框等不需要缩放的元素,也会跟着缩放
注意:
- viewport标签只对移动端浏览器有效,对PC端浏览器是无效的。
- 当缩放比例为100%时,逻辑像素 = CSS 像素宽度 = 理想视口的宽度 = 布局视口的宽度。
- 单独设置initial-scale或 width都会有兼容性问题,所以设置布局视口为理想视口的最佳方法是同时设置这两个属性。
- 即使设置了user-scalable = no,在Android Chrome浏览器中也可以强制启用手动缩放。
2. 动态设置rem
通过js获取设备宽度来动态设置font-size随着视口大小的改变而改变,流程如下:
- 获得设计稿尺寸,如750px
- 对设计稿标注进行转换
- 需要等比缩放的使用rem,不需要缩放的,例如border阴影,则使用px
- 代码如下:
const WIDTH = 750//设计稿宽度
function setRemUnit() {
let rem = 100*screen.width/WIDTH
document.documentElement.style.fontSize = `${rem}px`
}
setRemUnit()
看看无设置和有设置的区别:
除了字体,设置宽高等值,都可以达到缩放的效果。
缺点
- css与js代码具有一定的耦合性
- 必须将改变font-size的代码放在css样式之前
2. vw适配
如果说我们要一个不需要JS和CSS耦合在一起的单位,那vw/vh就是一个不错的选择。
vw:view width,指视口宽度的百分比,如:1vw = 视口宽度的1%
vh:view height,指视口高度的百分比,如:1vh = 视口高度的1%
vmin:vmin的值是当前vw和vh中较小的值
vmax:vmax的值是当前vw和vh中较大的值
使用起来也比较简单,比如我假设设计稿使用1080px宽度,则100vw = 1080px,即1vw = 10.8px。我们可以根据设计图上的px值直接转换成对应的vw值,也可以使用PostCSS的插件postcss-px-to-viewport,可以直接在代码中写px。
例子:设置一个视口宽高都占百分之五十的div
.box {
width: 50vw;
height: 50vh;
background-color: red;
}
3. rem配合vw
我们也可以通过vw来动态调整html的font-size,元素布局上使用rem单位,并使用媒体查询@media,当超过一定宽度时设置font-size为px限制根元素字体的大小。
@media screen and (max-width: 320px) {
html {
font-size: 64px;
}
}
@media screen and (min-width: 540px) {
html {
font-size: 108px;
}
}
html {
font-size: 20vw;
}
.box {
max-width: 540px;
min-width: 320px;
}
总结
-
新闻、社区等可阅读内容比较多的场景:px+flex+百分比
- 例子:携程(m.ctrip.com/html5/)
-
视觉图形组件较多的,或者是组件位置有一定相对依赖关系的场景:vw + rem
- 例子:京东(m.jd.com/)
- 网易(3g.163.com/touch/)