为什么要做适配?
因为在不同尺寸的设备上,同一个元素,呈现在屏幕上的肉眼大小不同。
效果图对比:
为了对比明显,特选以下两种像素差很大的设备
iphone 12 Pro 下18px
的字体效果:
iPad Air 下同样18px
字体的显示效果:
怎么样?是不是感觉iPad下字体很小?
值的注意的是,有时候,就是希望大屏幕下看到更多的内容,而不是更大的元素。
方案一(rem):
核心原理:rem单位是基于文档根节点(html)字体大小的相对单位,所以我们只需动态设置html的font-size属性,css中用rem替代px,则可以达到适配效果。
- 1.通过js动态设置根字体大小=(当前设备横向独立像素*100)/设计稿宽度
function setRem() {
const deviceWidth = document.documentElement.clientWidth;
// 这里选择以iphone 12 pro的390宽度作为基准值
// 然后将宽度划分为100份(这个可以自定义),目的是为了模拟vw的效果
const rem = (deviceWidth * 100) / 390;
// 动态设置html的font-size
document.querySelector('html').style.fontSize = rem + 'px';
}
- 2.编写css样式时,使用rem作为单位,值为设计稿/100:
设计稿样式:
.box {
font-size: 18px;
}
rem写法
.box {
// 计算方式:设计稿尺寸/100(上面定义的划分为多少份)
// 18 / 100 = 0.18
font-size: 0.18rem;
}
这样就完成了rem适配;
效果展示:
iphone 12 Pro(基准尺寸下,px和rem显示效果一致):
iPad Air:
可以看到,rem单位始终如一,占据的比例一直都是那么大,而px单位在iPad上看起来似乎变小了。
以上这种方案,有一个经典的库
flexible:github.com/amfe/lib-fl… 需要注意的是,flexible基准宽度是使用时参与计算,而不是在封装中计算,其划分的是10份,而不是100份。
方案二(viewport):
建议使用,目前兼容性也非常不错了
核心原理:使用vh、vw、vmin、vmax等css单位代替px单位,这些单位都是相对于屏幕的尺寸的,所以就不需要用js动态获取文档根节点的宽度了,另外还需要注意meta标签的设置。
vw: 1vw等于1%屏幕宽度 100vw则等于100%屏幕宽度;
vh: 1vh等于1%屏幕高度 100vh则等于100%屏幕高度;
vmin:vw和vh中较小的值
vmax:vw和vh中较大的值
同样还是以iPhone 12 pro 的390为基准宽度
设计稿css:
.box {
font-size: 18px;
}
viewport:
.box {
// 设计稿尺寸/基准尺寸*100(因为vw是将屏幕划分为100份)
// 18 / 390 * 100 = 4.615
width: 4.615vw;
}
iphone 12 Pro(基准尺寸下,vw和rem显示效果一致):
iPad Air:
可以看到,仅仅使用了vw单位,没有任何hack手段,就实现了rem的效果。
以上这种方案也有一个库帮助将px单位转换为viewport单位
postcss-px-to-viewport:
github.com/evrone/post…
1px问题
通常设计稿的宽度都是真机的多倍,比如设计稿宽度是750,而真机的像素是375,只有设计稿的1/2;由于css最低只支持1px,所以真机上1px占据的大小看起来视乎就变粗了。
解决方法1:媒体查询,对不同dpr设置transform缩放或0.5px或伪元素高度0.5等操作;
解决方法2:
通过 meta的viewport,调整缩放,进行校正
<script>
(function (window, document){
const viewport = document.querySelector("meta[name=viewport]");
const pixelRatio = window.devicePixelRatio;
const scale = 1 / pixelRatio;
viewport.setAttribute('content', `width=device-width,initial-scale=${scale}, maximum-scale=${scale}, minimum-scale=${scale}, user-scalable=no`);
}(window, document))
</script>
不过这种是对整体进行缩放,所以需要再配合rem适配方案使用。