最近遇到一個有意思的現象,如下 demo 中 fixed 的元素沒有相對 viewport 定位,而是相對於它的父元素進行定位。javascript
<html> <head> <style> .parent { width: 200px; height: 300px; background: yellow; transform: scale(1); } .fixed { position: fixed; left: 0; right: 0; bottom: 0; background: red; } </style> </head> <body> <div class='parent'> parent <div class='fixed'>fixed</div> </div> </body> </html>
在 w3c 中對 position: fixed 的[定義](https://www.w3.org/TR/css-position/#fixed-pos)以下:css
Fixed positioning is similar to absolute positioning. The only difference is that for a fixed positioned box, the containing block is established by the viewport.
大概意思就是,fixed 元素的塊級格式上下文 Block Formatting Context(BFC) 由 viewport 建立,也就是fixed 元素的 BFC 包含在根元素的 BFC 裏。html
那以上 demo 的表現就說不過去了。爲何呢🤔。谷歌一下,原來是父元素的 transform 在搗亂。java
再看看 w3c 對 transform 的[定義]():orm
For elements whose layout is governed by the CSS box model, any value other than none for the transform property also causes the element to establish a containing block for all descendants. Its padding box will be used to layout for all of its absolute-position descendants, fixed-position descendants, and descendant fixed background attachments.
大概意思就是,transform 屬性使元素建立了**新的 BFC,全部**的子元素都被包含在這個新的 BFC 內。那麼設置了 position: fixed 的子元素 BFC 被包含在了 transform 元素的 BFC 裏。htm
BFC 和定位有什麼關係呢,繼續翻 w3c,有段關於 BFC 的[定義](https://www.w3.org/TR/css-position/#def-cb):blog
The position and size of an element’s box(es) are sometimes computed relative to a certain rectangle, called the containing block of the element.
元素的位置和尺寸是相對於一個肯定的 BFC 計算的。ip
因此 demo 展現的 fixed 元素位置是根據它所在的 BFC 計算的。element