在 Chrome 22 中,position:fixed
元素的布局行为与之前的版本略有不同。现在,所有 position:fixed
元素都会形成新的堆叠上下文。这会更改某些网页的堆叠顺序,可能会破坏网页布局。新行为与移动设备上的 WebKit 浏览器(iOS Safari 和 Android 版 Chrome)的行为一致。
什么是堆叠?
大家都知道并喜爱用于确定网页上元素深度排序的 z-index
。不过,并非所有 z-index 都是一样的:元素的 z-index
仅决定其相对于同一堆叠上下文中的其他元素的排序。网页上的大多数元素都位于单个根堆叠上下文中,但采用绝对或相对定位且 z-index
值不为“auto”的元素会形成自己的堆叠上下文(即,其所有子元素都将在父元素内按 Z 顺序排列,而不会与父元素外的内容交错)。从 Chrome 22 开始,position:fixed
元素也会创建自己的堆叠上下文。
如需大致了解堆叠上下文,请参阅 这篇 MDN 文章。
将 position:fixed
与新的 position:sticky 属性进行比较:请注意,position:sticky
始终会创建新的堆叠上下文。
设计初衷
移动浏览器(Mobile Safari、Android 浏览器、基于 Qt 的浏览器)会将 position:fixed 元素放入自己的堆叠上下文中,并且已经这样做了一段时间(从 iOS5、Android Gingerbread 等开始),因为这样可以进行某些滚动优化,使网页对触摸的响应速度更快。我们之所以在桌面设备上实施此项变更,有以下三个原因:
- 在“移动”和“桌面”浏览器上呈现不同的渲染行为是 Web 作者的一大绊脚石;CSS 应尽可能在所有设备上以相同的方式运行。
- 对于平板电脑,尚不清楚是“移动设备”还是“桌面设备”堆叠上下文创建算法更合适。
- 将移动设备上的滚动性能优化功能引入到桌面设备上,对用户和创作者都有益。
更改的具体内容
以下示例展示了不同的布局行为:https://codepen.io/paulirish/pen/CgAof
更改生效后,这两个版本都会呈现为右侧版本。
在此示例中,绿色方框包含 z-index: 1
,粉色方框包含 z-index: 3
,橙色方框包含 z-index: 2
。蓝色框是橙色框的祖先,并且具有 position:fixed
。
如果蓝色方块获得自己的堆叠上下文,则系统会根据蓝色方块的堆叠上下文计算橙色方块的 z-index
。由于蓝色方框的 z-index
为 auto
,因此在根堆叠上下文中,其堆叠级别为 0,这意味着橙色方框最终位于绿色和粉色方框后面,后两者的 z 轴索引分别为 1 和 3(在根上下文中)。
如果蓝色方块未获得自己的堆叠上下文,则系统会相对于根堆叠上下文(以及绿色和粉色方块)计算橙色方块的 z-index
。因此,橙色框最终会与粉色框和绿色框交错排列。
如需详细了解堆叠上下文创建的条件(以及堆叠上下文的一般行为方式),请再次参阅这篇 MDN 文章。在该示例中,由于不透明度小于 1,右侧版本始终为蓝色方框提供自己的堆叠上下文。所做的行为更改实际上会添加另一个用于创建单独堆叠上下文的标准,即元素的 position:fixed 属性。
测试和未来
如需测试您的网页是否会发生变化,请前往 Chrome 的 about:flags
,然后开启/关闭“固定位置元素会创建堆叠上下文”。如果布局在两种情况下的行为相同,则表示布局已设置完毕。如果没有,请确保您能接受启用该标志后的显示效果,因为 Chrome 22 将采用该标志的默认设置。
此更改移除了一项功能,即将 position:fixed 子树中的内容与外部非滚动内容交错显示的功能。任何 Web 开发者都不可能有意为之,通过为多个 position:fixed 元素分配 DOM 的不同部分,也可以产生相同的效果。例如,请考虑以下两个示例:
https://codepen.io/wiltzius/pen/gcjCk
此页面会尝试获取 position:fixed 元素的两个子 div(overlayA 和 overlayB),并将其中一个放置在单独的内容 div 上方,另一个放置在同一单独的内容 div 下方。现在,这已不可能实现,因为 position:fixed 元素是它自己的堆叠上下文,它(及其所有子元素)将完全位于内容 div 上方或下方。请注意,此示例在 Chrome 21 及更低版本中有效,但在 Chrome 22 中已不再有效。
要解决此问题,可以将这两个叠加层拆分为各自的 position:fixed 元素。每个元素都有自己的堆叠上下文,其中一个可以位于内容 div 上方,另一个可以位于内容 div 下方。请参阅已修正的示例,该示例适用于 Chrome 21 和 22:
https://codepen.io/wiltzius/pen/vhFzG
Chrome 是第一个让 position:fixed 元素创建自己的堆叠上下文的桌面浏览器。相关标准是 CSS z-index 规范(例如,请参阅 https://www.w3.org/TR/CSS21/zindex.html)。我们尚未就如何处理移动版和桌面版浏览器之间的差异达成共识,但鉴于移动版和桌面版浏览器采用两种不同的行为会造成混淆,Chrome 目前选择在两个平台上采用这种单一行为。
更新时间:2012 年 10 月 1 日:本文的原始版本建议,CSS z-index
规范已更改,以反映 position: fixed 元素的新行为。这不准确;我们已在 www-style 列表中讨论过此问题,但规范中尚未做出任何更改。