location:fixed 元素即将生效的叠放变更

Tom Wiltzius
Tom Wiltzius

在 Chrome 22 中,position:fixed 元素的布局行为与以前的版本略有不同。所有 position:fixed 元素现在都会形成新的堆叠上下文。这会更改某些页面的叠放顺序,有可能破坏页面布局。新行为与移动设备(iOS Safari 和 Android 版 Chrome)上 WebKit 浏览器的行为保持一致。

堆叠什么?

大家都了解并喜欢使用 z-index 来确定页面上元素的深度排序。不过,并非所有 Z-index 的创建都相同:元素的 z-index 仅确定其相对于同一堆叠上下文中其他元素的顺序。网页上的大多数元素都位于单个根堆叠上下文中,但具有非自动 z-index 值的绝对或相对定位元素会形成它们自己的堆叠上下文(也就是说,它们的所有子元素都将在父元素内按 Z 顺序排序,而不是与父元素外部的内容交错)。从 Chrome 22 开始,position:fixed 元素还会创建自己的堆叠上下文。

如需大致了解堆叠上下文,请参阅这篇 MDN 文章

position:fixed新的 position:sticky 属性进行比较:为便于参考,position:sticky 始终会创建新的堆叠上下文。

设计初衷

移动浏览器(移动 Safari、Android 浏览器、基于 Qt 的浏览器)将 position:Fix 元素置于其自身的堆叠上下文中,并已有一段时间(自 iOS5、Android Gingerbread 等开始)使用了,因为它支持特定的滚动优化,使网页的触摸响应速度更高。此次变更推出至桌面版的原因有三:

  1. 对于网页作者而言,在“移动”浏览器和“桌面”浏览器上具有不同的呈现行为是一大阻碍;如果可能,CSS 在任何情况下都应保持不变。
  2. 对于平板电脑,目前并不清楚哪种“移动设备”或“桌面设备”堆叠上下文创建算法更适合您。
  3. 将滚动性能优化从移动设备转移到桌面设备,对用户和作者都有好处。

此次变更的具体内容

以下示例展示了不同的布局行为:https://codepen.io/paulirish/pen/CgAof

更改之后,两个版本的呈现效果将与右侧版本相同。

在此示例中,绿色框具有 z-index: 1,粉色框具有 z-index: 3,橙色框具有 z-index: 2。蓝色框是橙色框的祖先实体,具有 position:fixed

如果蓝框有自己的堆叠上下文,则橙色框的 z-index 是相对于蓝框的堆叠上下文计算的。由于蓝色框的 z-indexauto,因此在根堆叠上下文中,其堆叠级别为零,这意味着橙色框最终位于绿色和粉色框的后面,它们在根上下文中的 Z-index 分别为 1 和 3。

如果蓝色框没有获得自己的堆叠上下文,则橙色框的 z-index 将相对于根堆叠上下文(以及绿色框和粉色框)进行计算。因此,橙色方框最终与粉色和绿色方框交错。

如需详细了解创建堆叠上下文的条件(以及堆叠上下文的一般行为方式),请再次参阅这篇 MDN 文章。在此示例中,右侧版本始终为蓝色框提供自己的堆叠上下文,因为其不透明度小于 1。所进行的行为变更有效地添加了创建单独的堆叠上下文的另一个条件,即位置:固定的元素。

测试与未来

如需测试您的网页是否会发生变化,请前往 Chrome 的 about:flags,然后开启/关闭“固定位置元素会创建堆叠上下文”。如果布局在这两种情况下的行为相同,则设置妥当。如果不能,请确保在启用该标记后您觉得可以接受,因为这将在 Chrome 22 中默认显示。

此变更移除了一项功能,即在 position:Fix 子树内与外部非滚动内容交错的功能。任何网络开发者不太可能会有意为之,通过为多个 position:Fix 元素指定 DOM 的不同部分,可达到相同的效果。例如,请考虑以下两个示例:

https://codepen.io/wiltzius/pen/gcjCk

此页面试图提取一个 position:Fix 元素的两个子级 div(overlayA 和 overlayB),将一个放置在单独的内容 div 上方,将另一个置于该单独内容 div 下方。目前无法执行此操作,因为 position:Fix 元素自身是其自己的堆叠上下文,且该元素(及其所有子元素)将完全位于内容 div 的上方或完全下方。请注意,上述示例在 Chrome 中不再有效。2

为修复此问题,可将这两个叠加层分解成各自的 position:Fix 元素。每个 Context 都是自己的堆叠上下文,其中一个位于内容 div 上方,另一个位于内容 div 下方。请参阅 Chrome 21 和 Chrome 22 中的固定示例:

https://codepen.io/wiltzius/pen/vhFzG

本示例的起源要归功于不可修改的 hixie

Chrome 是第一款可让 position:Fix 元素创建自己的堆叠上下文的桌面浏览器。相关标准是 CSS Z-index 规范(例如 https://www.w3.org/TR/CSS21/zindex.html)。对于应如何区分移动浏览器和桌面浏览器,目前我们还未达成共识,但鉴于移动设备和桌面设备上存在两种不同行为的混淆,Chrome 目前已选择在这两个平台上都采用这种单一行为。

2012 年 10 月 1 日更新:本文的原始版本表明,我们已经更改 CSS z-index 规范,以反映 position: 固定元素的新行为。这并不准确;已在 www 样式列表中讨论过,但该规范尚未纳入任何更改。