不論是在基礎或是進階的版面排列,幾乎離開不了 position 系列的 CSS 語法,如果對於這些語法不熟悉,要快速完成畫面需求幾乎是不可能的,甚至會延宕整個團隊的開發速度(對,position 語法就是這麽重要)。
這也是為什麼 position 系列語法的應用 ,常常被列為前端面試考題的原因。
那 position 語法究竟要解決什麼問題呢?
根據 MDN:「The position CSS property sets how an element is positioned in a document. The top, right, bottom, and left properties determine the final location of positioned elements.」
position 語法的設定,會影響在整個網頁中元素是如何被放置,而 top、right、bottom 及 left 屬性會決定元素最終的位置。
這篇文章就要來跟大家聊聊以下這些 position 系列的 CSS 語法,會如何在實務上進行應用,本篇文章中會提及以下語法:
在提及 position 語法前,我們先來聊聊 top、right、bottom、left 這四個語法是做什麼的,這四個方向性的屬性主要是用來定義元素的位置要從什麼方向起算延伸,也就是前文提到,這四個方向屬性設定會影響元素最終位置的原因。
舉例來說:
在之後的範例中,我們會大量使用到這四個方向性的屬性來輔助解釋 position 語法。
position 的預設值: static
當我們沒有給網頁元素加上 position 語法時,網頁元素會自己帶有 position: static 的特性。
帶有這種特性的元素,會按照原有的 HTML flow 來進行排列,而 top、right、bottom、left 及 z-index 是不會生效的!
如果你發現自己設定的 top、right、bottom、left 或是 z-index 並沒有生效,很有可能是你根本沒有啟用 position 的其他語法(稍後會提及)。
由於元素預設就帶有這個語法效果,通常並不會額外拿出來使用,或是當作效果加在元素上。
相對定位
再來我們來看看 MDN 文件對於相對定位的定義是什麼:「The element is positioned according to the normal flow of the document, and then offset relative to itself based on the values of top, right, bottom, and left.」
但不要緊張,這不代表 position: relative 是沒有用的語法,他需要與其他的 position 語法一起使用才會有意義。
絕對定位
接著我們要來看另外一個語法,他叫做 position: absolute。
我們一樣先來看看官方文件對於這個語法的定義:「The element is removed from the normal document flow, and so space is created for the element in the page layout. It is positioned relative to its closest positioned ancestor, if any; otherwise, it is placed relative to the initial containing block, Its final position is determined by the value if top, right, bottom and left.」
首先,帶有 position: absolute 的元素會被移出原有的 HTML flow,產生新的堆疊環境,也就是說帶有此語法特性的元素不會影響到其他的元素的排列順序。
再者,帶有 position: absolute 的元素會以最接近且同樣也帶有額外設定的 position 語法的父元素作為參考點,並以 top、right、bottom、left 屬性來決定屬性的最後位置。
如果外層沒有父元素,或是父元素本身並沒有帶有額外設定 position 語法的話,像是 position: relative、position: absolute、position:sticky 或是 position: fixed 語法等,就會以最外層的 body 作為參考點,讓我們先來看個程式碼範例:
在這個範例中,在綠色的容器中帶有兩個分別為紅色及粉紅色的方塊,且按照正常的 HTML flow 排列來說,粉紅色的方塊應該是要在紅色方塊的上方。
但問題來了,現在粉紅色方塊帶有 position: absolute 的屬性,依照此語法的特性粉紅色方塊就會被挪出原本的 HTML flow ,並以 body 作為參考點,出現在距離 body 上方 200px 、左方 200px 的位置。
因為粉紅色方塊被挪出 HTML flow,所以其他的元素就會去填補空缺的位置,於是紅色方塊的位置就會向上移,也就是先前我提到,一旦使用 position: absolute 語法,粉紅色的方塊會出現在另外一個堆疊環境(stacking context),實際上他們並不存在在同一個 z-index 上。
position: fixed 語法是一個非常方便,但在開發初期很容易被忽略的一個語法,老樣子,我們先來看看這個語法官方的定義:「The element is removed from the normal document flow, and no space is created for the element in the page layout.」
跟 position: absolute 非常類似,一旦元素帶有 position: fixed 的特性,就會被移出原本的 HTML flow,並且被移到另外的堆疊環境,簡單來說,它會與其他元素帶有不同的 z-index,所以不會影響到其他元素的排列狀況。
再者,MDN 提到:「It is positioned relative to the initial containing block establish ed by the viewport, expect when one of its ancestors has a transform, perspective or filter property set to something other than none, in which case that ancestor behaves as the containing block. Its final position is determined by the values of top, right, bottom and left.」
position: fixed 會以 viewport 創造的區域,這裡可以暫且想像成以整個瀏覽器的「畫面」作為參考點,以 top、right、bottom 及 left 屬性來決定元素的最後位置。
MDN 是這麼描述 position: sticky 的:「The element is positioned according to the normal flow of the document, and then offset relative to its nearest scrolling ancestor and containing block(nearest block-level ancestor), including table-related elements, base on the value of top, right, bottom, and left. 」
帶有 position: sticky 的元素不會被挪出 HTML flow,並且會跟最近的區塊滾動元素碰觸時,在原有的 HTML flow 中產生一個留白空間,並以 top、right、bottom 及 left 屬性來決定元素的最後位置:
從上方範例來看,你會發現帶有 position:sticky 的元素一旦碰到最近、帶有 overflow: scroll 特性的父元素,就會以該父元素作為參考點,並依照你撰寫的 top、right、bottom 或 left 屬性來進行定位(取決於你在滾動頁面時,會從哪個方向觸碰到父元素)。