起因
今天复习移动端适配问题的时候,想起了lib-flexible
这个rem
适配方案,但是在 github 上面看到了下面这段话:
由于viewport单位得到众多浏览器的兼容,lib-flexible这个过渡方案已经可以放弃使用,不管是现在的版本还是以前的版本,都存有一定的问题。建议大家开始使用viewport来替代此方。
看来现在移动端的主流解决方案已经可以用 vw
和 vh
代替了,当然这只是我从上面这段话中提取到的信息,接下来是一些复习回顾内容。
viewport
viewport 按照不同的功能可以大致分为以下三种
layout viewport(布局视窗)
布局视窗指的是网页的绘制区域,如果要使 PC 页面在移动端显示,为了达到页面显示正常的目的,势必要设置合理的布局视图来承载页面,默认情况下,这个值是 980px,这就会导致页面出现横向滚动条。
此区域的宽度可通过 document.documentElement.clientWidth
获取
visual viewport(可视视窗)
可视视窗指的是移动端可视区域,一般就是屏幕宽度。他的宽度可通过 window.innerWidth
来获取
ideal viewport(理想视窗)
这是一个抽象概念,是指移动端要将页面在不显示横向滚动条的前提下,做到字体,图片等内容显示正常,这是移动设备的理想视窗,一般在 iphone中宽度为 320px,可以参考viewportsizes.com查看相关宽度。
所以,根据上述的描述实际开发中主要是用的是 ideal viewport
,因为这个宽度代表了屏幕宽度,它可以保证宽度设置为ideal viewport
width 后,一定能撑满整个屏幕,不管你屏幕的分辨率是多少。
关于分辨率
在移动设备上,因为高清屏的存在,会使CSS 中的px 变得不会像 PC 中那么准确,也就是 1px !==1设备像素
,所以,就有了dpi = 物理像素/CSS像素
如果这个值不等于 1,就说明在屏幕上的 1px 代表了更多的像素点。比如:当 dpi=2 时,1px 就代表了 2*2 的像素点,所以以常规的 CSS 的 px 单位来直接对移动端设备样式编写会存在一定的问题,需要一个相对单位的转换,也就是说,可以采取 ideal viewport
作为屏幕宽度的基础,将设计图中的 px 单位进行一些转换,来达到不同设备适配的目的。
这里就可以引出:
vw
,vh
rem
vw&vh
这两个单位时相对于视口来说的,可以理解为相对于 ideal viewport
的,这样子就可以使用这个单位来进行样式的编写,而不需要担心不同设备和分辨率的情况下,显示的差异。
但是,仍然需要一些转换,来讲设计像素转换为 vw
和 vh
vw
是视口宽度的 1/100,明白了这些,可以借助一些数学和css预处理器来进行转换
元素实际宽度(y)/视口宽度(z) = 元素设计宽度(x)/设计图宽度(c)
由此可以知道 y = z*x/c;
而 1vw = z/100
也就是 y = 100*x/c ==> y = x/c*100vw
最终得出一个转换公式 y = (元素设计宽度(x)/设计图宽度(c))*100vw;
有了转换公式,借助 less
函数的功能,可以轻松的实现转换:
@dW: 720px; // 设计图宽度
.function {
.foo(@px) {
return: unit((@px/@dw)*100,vw);
}
}
less
天生不支持自定义函数,所以需要额外的插件配置自定义函数插件
// 这里是一个 webpack 配置的示例
const LessPluginFunctions = require('less-plugin-functions');
module.exports = {
...
{
loader: "less-loader", options: {
plugins: [
new LessPluginFunctions()
]
}
}]
...
};
如果能使用的是 scss
,也可以定义成同样的函数。
rem
rem 是相对于根元素的 font-size 的大小,可以通过媒体查询和js 脚本动态改变来实现。
rem 的相对单位转换的计算方法和上述vw
的计算方式一致,只要看你想把屏幕分成多少等分来进行计算。
lib-flexible 是淘宝开源的成型方案,但是貌似已经不进行维护了,转而使用 vw
就好了。
更多的解决方案
- flex
- grid
这两种是CSS3 提出的弹性和栅格布局,也能很好的做出相应式的页面,但是存在一些兼容性,后续在进行了解分析。
利用 meta 标签对 viewport 进行控制
这一部分内容请移步这里
文章参考自: github.com/hijiangtao/…