LayoutUnit & Subpixel Layout

LayoutUnit & Subpixel Layout

引言

为了更好的支持移动端和 PC 端的缩放,WebKit 增加了subpixel layout(次像素/亚像素布局)为此他们还改变了 rendering tree。一个次像素单元在 WebKit 内被称为 LayoutUnit 用于取代之前使用整数来布局一个元素在页面中位置和大小。从 2013 年开始 WebKit 就已经开启了这个 flag。

LayoutUnit

LayoutUnit 是逻辑像素的一种抽象表示,在 WebKit 的实现中它是一个像素的 1/64,这样我们就可以使用整数来进行布局计算,避免了使用浮点数计算而丢失精度的问题。

虽然我们现在在布局计算时使用了 LayoutUnit,但是在最终将计算值渲染对应到设备上时仍然会出现计算值不能与物理像素对齐的情况。因为计算出的值可能是一个小数而 1 个物理像素已经不能再进行切割。所以出现了这样一个问题,次像素如何与物理像素进行对齐?

回到我们实际的编程过程中,我们会有很多场景遇到次像素的问题,只是很多人不会关注,或者会忽略掉这些细节。比如如果一个 box 的宽度是 10px,我们把它平均分成 3 份,那么里面的三个盒子的宽度分别是多少呢,3.3333px?再比如我们在使用 rem 布局的时候有时候会发现一个正方形设置了 border-raduis 预期让它展示成一个圆形,在一些设备上却并不那么圆,在整体比较小的时候可能会被渲染成一个椭圆形。以及这种时候这个元素还设置了一个 background-size 覆盖整个容器但是背景却被切掉了一小块。这些问题不是那么容易被发现,但是确实是存在的。

阅读更多
解析移动端滚动穿透

解析移动端滚动穿透

滚动穿透在移动端开发中是一个很常见的问题,产生诡异的交互行为,影响用户体验,同时也让我们的产品看起来不那么“专业”。虽然不少产品选择容忍了这样的行为,但是作为追求极致的工程师,应该去了解为什么会产生以及如何去解决。

什么是滚动穿透

移动端开发中避免不了会在页面上进行弹窗、加浮层等这种操作。一个最常见的场景就是整个页面上有一个遮罩层,上面画着各种各样的东西,具体是什么就不讨论。实现这样一个遮罩层可难不住即使是一个刚开始写前端的小白。但是这里有一个问题就是如果不对遮罩层做任何处理,当用户在上面滑动时会发现遮罩层下方的页面居然也在滚动,这就很 interesting 了。就如下面的例子,一个名为mask长宽都是屏幕大小的遮罩层,我们在上面滑动时,下面的内容也在跟随滚动,即滚动“穿透”到了下方,这就是滚动穿透(scroll-chaining)。

scroll-chaining

上方 demo 的遮罩层底部是一个逐渐变蓝的内容容器,但是滑动上面遮罩层时,底部也跟随滚动了,这只是一个最简单的场景,后面我们会讨论更复杂的情况。

阅读更多