CSS position 屬性生成器

通過圖形介面切換5種CSS position取值(static、relative、absolute、fixed、sticky),即時預覽top/right/bottom/left與z-index的效果,並免費生成對應的CSS程式碼。

把 position 的五個取值擺在一起比

position 是決定元素落在何處的屬性,取 static、relative、absolute、fixed、sticky 五個值。本工具讓您在這幾者之間切換,當場確認 top/right/bottom/left 與 z-index 如何使勁,並產生 CSS。

用 absolute 定位的元素跑到意想不到的位置,原因幾乎只有一個:它的基準是「最近的、position 不為 static 的祖先元素」。 如果沒有這樣的祖先,元素就會以初始包含區塊(與視口同樣大小的矩形)為基準。忘記給父元素加上 position: relative,幾乎就是這種現象的全部真相。sticky 也有一個眾所周知的陷阱:它會貼在最近的「具有捲動機制的祖先」(overflow 為 hidden、auto、scroll 的元素)上,如果這個祖先實際上並不捲動,看起來就像黏性完全沒有生效。 另外,z-index 被限制在名為「堆疊脈絡」的巢狀單元內,只要元素所在的脈絡低於外部元素,無論數值設得多大,都無法蓋到外部元素之上。

使用方法

  1. 切換 position 的取值 依次試過這五個,各自以何為準的分別便顯出來了。
  2. 挪動偏移量 請確認:取值為 static 時,top 之流一概不起作用。
  3. 改動 z-index 可以看出堆疊的次序如何變動。
  4. 複製產生的 CSS 擺放合乎心意之後,便可原樣貼進您的程式。

用好本工具的小技巧

  • 切換到position: relative並設定top/left後,Box B會從原來的位置發生視覺偏移,請注意Box C(後一個元素)的位置並不會改變。
  • 切換到absolute或fixed後,Box B會完全脫離正常文件流,因此Box C會往上填補它留下的空隙。
  • z-index 用於決定元素重疊時的堆疊順序,但對 position: static 的元素無效(彈性項目與網格項目例外,即使維持 static 也有效)。在嘗試「設定 z-index」之前,請先修改 position。
  • position: sticky只在可滾動的容器內才會生效。請實際滾動預覽框,觀察元素在中途被固定住的效果。
  • 生成的CSS程式碼可以直接複製貼上到你自己的樣式表中,不妨在真實頁面上確認效果是否一致。

這些情境會用到

把標題黏在視窗頂端

有了 sticky,頁面捲動時標題依然留在原處。

把徽章或圖示疊在角上

父元素 relative、子元素 absolute,是最基本的搭配。

放一個固定的按鈕

fixed 原則上相對於螢幕(視口)定位,因此捲動時不會移動。請注意祖先元素設定了 transform 時基準會改變。

查究堆疊的毛病

某個元素藏到了另一個之下時,頭一個該疑的便是堆疊脈絡。

position 的術語

static
初始值。在此值下,top 等偏移量不起作用,z-index 除非是彈性或網格項目,也不起作用。
relative
把元素從它本該在的位置挪開。它動了,可原處的空間仍為它留著。
absolute
以最近的、position 不為 static 的祖先為基準定位。 若不存在,則以初始包含區塊(視口大小的矩形)為基準。
fixed
原則上以螢幕(視口)為基準定位,捲動時位置不變。若祖先設定了 transform、perspective、filter、contain、will-change 等,則以該祖先為基準。
sticky
先處於正常位置,到達指定位置後貼住。基準是最近的「具有捲動機制的祖先」,如果該祖先不捲動,看起來就像沒有生效。
堆疊脈絡
堆疊次序得以定奪的巢狀單元。其內的 z-index 無法與外部的元素直接相比。

常見問題

absolute 以「最近的已定位祖先元素(position 不為 static 的父元素)」為基準定位,若不存在這樣的祖先,則以初始包含區塊(與視口同樣大小的矩形)為基準。而 fixed 原則上以瀏覽器視口為基準定位,因此即使捲動頁面,也會一直停留在螢幕上的同一位置。不過,如果祖先元素設定了 transform、perspective、filter 等屬性,就會改以該祖先為基準。

sticky 不生效的主要原因有:祖先元素設定了 overflow: hidden、auto 或 scroll,但該祖先實際上並不捲動;父元素高度與 sticky 元素幾乎相同,沒有固定的餘地;或者根本沒有設定 top、bottom 等偏移量。sticky 會貼在最近的具有捲動機制的祖先上,而且無法超出父元素的範圍繼續貼住,因此也請確認父元素是否有足夠的高度。

relative會以該元素本應作為普通static元素時所佔據的原始位置為基準,按照設定的top/right/bottom/left值做視覺上的偏移。關鍵在於,它原本佔據的空間在佈局中仍然被保留——這與會完全脫離文件流的absolute有明顯區別。

z-index 只對 position 不為 static(relative、absolute、fixed、sticky)的元素以及彈性項目、網格項目有效。此外,如果父元素設定了 transform 或 opacity 等樣式,就會建立獨立的堆疊脈絡(stacking context),子元素的 z-index 會被限制在其中,可能無法如預期運作。

常見做法是給想作為基準的父元素設定position: relative。即使不設定任何偏移值,僅僅新增position: relative就能使其成為"已定位元素",其內部的absolute子孫元素就會以該元素的內側邊緣為基準進行定位。
工具君

閒話 ― position: sticky標準化的漫長曆程

CSS早期就已經擁有static、relative、absolute、fixed這4種取值,但要實現"滾動到一定位置後才固定"的表頭或側邊欄,長期以來只能依靠JavaScript監聽滾動事件,再手動切換為position: fixed。當時並不存在僅用CSS就能完成這一效果的方案。

position: sticky 的構想大約在 2012 年就被納入 CSS 規範(CSS Positioned Layout Module Level 3),Safari 在 2013 年前後以帶 WebKit 廠商前綴(-webkit-sticky)的形式率先實作。Firefox 早在 2014 年的第 32 版就支援了不帶前綴的 sticky,Chrome 則直到 2017 年(第 56 版)才跟進。2019 年 Safari 13 也不再需要前綴,此後只寫不帶前綴的 sticky 就能在所有主流瀏覽器中使用。

position: sticky「中途被固定」的行為,在實作上可以解釋為 relative 與 fixed 的混合體。平時它作為 relative 遵循正常文件流,當捲動位置到達指定的偏移量時,就像當場切換成 fixed 一樣表現。這種切換以最近的具有捲動機制的祖先為基準,並且只會在父元素的範圍內發生。這兩個限制正是 sticky 常常讓人覺得「不起作用」的主要原因。

如今,固定表格表頭、讓目錄在滾動時始終可見等場景中,sticky已成為Web設計的常用技巧。不再需要通過JavaScript監聽滾動事件,這在效能和程式碼簡潔性兩方面都是實實在在的進步。