博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

移动端适配:淘宝和唯品会rem方案原理

Posted on 2021-10-23 22:43  kpi311  阅读(244)  评论(0编辑  收藏  举报

0 tl;dr

其实也没啥原理,就是一个比例问题。

1 前置知识

设备独立像素(DIP):一种抽象的像素,与实际物理像素之间的比值就是DPR。简而言之,一个设备独立像素实际上可以由\(1\times1\),\(2\times2\),\(3\times3\)...等任意多个物理像素来表现,取决于设备的设置。而应用一般并不需要实际与物理设备打交道,只与设备独立像素打交道。

理想视口:布局视口等于设备独立像素宽度的视口,可以简单理解为设置了viewport meta标签的html页面。

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

接下来讨论的适配问题都是关于理想视口下设备独立像素的。

2 淘宝适配方案

定义几个变量:设计稿宽度x, 设计稿中任意边长a, 最终设备独立像素宽度 d, a实际渲染的长度a'

最终要在设备中渲染出a',也就是要找出a -> a'的等式。

不难得出一个等式

\[a'=\frac{a}{x}d \]

对该式移项,可得

\[a'=a\frac{d}{x} \]

这里就可以将\(a\)作为转换后的长度;而\(\frac{d}{x}\)作为单位,动态添加。这里html的rem刚好是这样的单位,所以可以将\(\frac{d}{x}\)设置为html的font-size值,而长度数值不变,单位设置为rem。最终css计算的时候乘以这个font-size值就OK。

然而\(\frac{d}{x}\)往往都不会很大(就算是d=1920,在x=375的时候也只有5.12),又由于font-size属性不支持小于12px的值,所以乘以了100以避免被强制提升到12px,另外也方便计算。换句话说,前面对应地要除以100。等式改写为

\[a'=\frac{a}{100}\times\frac{d}{x}\times100 \]

根据这个式子,可以很快拆出需要的部分:

\[\begin{cases} htmlFontSize = \frac{d}{x}\times100\\ pxInCSS = \frac{a}{100} \end{cases} \]

根据这个思路可以给出一个实际的例子:MDN 的 EM 示例

利用浏览器body默认font-size为16px,设置font-size为62.5%,页面各处样式都可以使用1rem = 10px的等式。

3 唯品会方案

还是同样的前设:

设计稿宽度x, 设计稿中任意边长a, 最终设备独立像素宽度 d, a实际渲染的长度a'

\[    a'=\frac{a}{x}d \]

这里唯品会的做法是:引入一个完全固定的中间量10,则上式改为

\[    a'=\frac{a}{x} \times 10 \times \frac{d}{10} \]

拆分之后的结果是

\[\begin{cases}     htmlFontSize = \frac{d}{10}\\     pxInCSS = \frac{a}{x}\times10 \end{cases} \]

4 总结

使用淘宝方案可以拓展到任意尺寸的设计稿,用法都是一致的;唯品会方案在借助工具(lib-flexible)的情况下才易用,但思路上来说更贴近于使用vw单位。

至于lib-flexible是手机淘宝系的开源产品,那就是另外一个故事了🥱