1 rem方案
原理
- 使用理想视口和1/dpr的缩放,使视口的宽度等于设备物理像素。(解决1px问题)。
- 依照某特定宽度设定rem值,用作需要等比缩放的元素。(可以理解为按照屏宽的特定比例布局)
一句话;利用 viewport和设备像素比 调整 基准像素(即调整html的font-size)
1.1步骤:
- meta 设置viewport
width=device-width 使得用户可以在理想视口内看到完整的布局视口的内容。
initial-scale = 1/dpr 解决1px问题。
- 设置 font-size:100px
1rem = 100px,rem是相对单位,相对于html。自适应。
- 设计稿除以100,例设计稿的20px--》.2rem
优点
- 在视觉和设计稿还原方面效果都不错
- 能解决1px问题
缺点
-
理解起来稍显困难
-
使用过程中需要各种计算,比较复杂。
高分屏文字显示较小问题,需要针对dpr设置font-size。 例如:
.a{ font-size:12px; } [data-dpr="2"] .a{ font-size: 24px; } [data-dpr="3"] .a{ font-size: 36px; }
2 vw方案
viewport:解决1px问题 + vw
vh、vw方案即将视觉视口宽度 window.innerWidth 和视觉视口高度 window.innerHeight 等分为 100 份。
- vw(Viewport's width):1vw=视觉视口的1%
- vh(Viewport's height) : 1vh =视觉视口高度的1%
- vmin : vw 和 vh 中的较小值
- vmax : 选取 vw 和 vh 中的较大值
如果视觉视口为375px,那么1vw = 3.75px,这时UI给定一个元素的宽为75px(设备独立像素),我们只需要将它设置为75 / 3.75 = 20vw。
缺点
- px转换成vw不一定能完全整除,因此有一定的像素差。
- 比如当容器使用vw,margin采用px时,很容易造成整体宽度超过100vw,从而影响布局效果。当然我们也是可以避免的,例如使用padding代替margin,结合calc()函数使用等等...
3 那些工具可以使用
PostCSS- px2rem插件
lib-flexible 自动在html的head中添加一个meta name="viewport"的标签,同时会自动设置html的font-size为屏幕宽度除以10,也就是1rem等于html根节点的font-size。
【作用:】
帮我们px值计算转换为对应的rem值,无需开发者自己算。
写代码时,我们只需要根据UI给的设计图写px单位即可。
【优势:】
设计稿给多少,就写多少,35px,你就写35px。无需人工计算rem的值了。
看效果,你写的px,自己转成了rem了。
PostCSS- postcss-px-to-viewport 插件
帮我们把我们需要转的px值计算转换为对应的vw值, 无需人工计算vw的值了。
4 我们如何做的
采用方式1
在index.html 以脚本方式引入,设置viewport和font-size
【1】
通过设置documentElement的fontSize属性值就可以统一整个页面的布局标准。--达到自适应的效果
【2】
借助JavaScript控制viewport的能力,设置viewport的width为device-width,改变浏览器viewport(布局视口和视觉视口)的默认宽度为理想视口宽度,从而使得用户可以在理想视口内看到完整的布局视口的内容。
等比设置viewport的initial-scale、maximum-scale、minimum-scale的值为1/dpr,从而实现1物理像素=1css像素,以适配高倍屏的显示效果(就是在这个地方规避了大家熟知的“1px问题”)
<script>
(function () {
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var scale = 1.0;
var ratio = 1;
if (isIPhone && window.devicePixelRatio >= 2) {
scale *= 0.5;
ratio *= 2;
}
var text = '<meta name="viewport" content="initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', width=device-width, user-scalable=no, viewport-fit=cover" />';
document.write(text);
document.documentElement.style.fontSize = 50 * ratio + 'px';
document.documentElement.setAttribute('data-dpr', ratio);
})();
</script>
IOS
android