前端新手村 Position 定位
「當你迷惘的時候,就回到原點想一想」-中華一番 蘭飛鴻
¶前言
網頁前端新手村系列文章,宗旨並不在技術本身的教導,重點放在技術與技術之間的脈胳關係。讓零碎的網頁前端技術的關鍵字,成為比較有系統性的視野。
讓一開始接觸網頁前端的新手們,有一個比較友善的系統來架構你的學習,至於技術本身的深入探討,就留給其它的高手們吧。
¶Position 定位
呼!花了五天介紹 CSS 的 Selector!!介紹完 Selector 之後,來介紹常用的 position 吧!
在 CSS 中,有三種可控制的方式,放置 box [1]
語法
| position: 定位方法 | 
- 上下左右的設定用得上再使用
- 定位並不會造成單位變化,所以可以這樣換算 left= -right,top= -bottom
¶Static 無定位
原本畫面上的 box 會依照 Normal flow 排列。
- position: staic是每個 HTML element 的預設值。
- position設定成這個值時,- top,- left,- bottom,- right將不會有任何作用。
¶Relative 相對定位[4]
原本畫面上的 box 會依照 Normal flow 排列。
假設有個叫 box 的HTML element 設定 position: relative  會有什麼影響
- 在 normal flow 佔有的空間,依然佔有。
- 不會影響其它 normal flow 的 HTML Element
- 偏移量是相對於在 normal flow 的位置
- 會導致元素重疊
- 在 table 有些跨欄偏移的應用 (有明確的定義,不過在此不細講)
¶Absolute 絕對定位[4:1]
原本畫面上的 box 會依照 Normal flow 排列。
假設有個叫 box 的HTML element 設定 position: absolute 會有什麼影響
- 跳脫 normal flow 排列規則,不佔有任何空間。
- 不會影響其它 normal flow 的 HTML Element
- 偏移量是相對於有「非 position: static」的位置
- box 以內有 normal flow 和 position: absolute的都與 box 相關
- 會導致元素重疊
¶Fixed 可視區的絕對定位[4:2]
可視區的絕對定位,唸起來很呦口。我也不知道怎麼翻才好。
這是一種類似絕對定位的定位方式。唯一的區別在於偏移量參考點
- absolute 參考容器(的容器)中,使用「非 static 定位」的容器
- 偏移量是相對於可視區 (viewport)
- 每個可視區都會重複 fixed 定位的內容
在內容捲動時,被 fixed 的元素會固定不移動。類似固定背景的效果
有 Media Query 時,有用到 paged 類型,要注意重複的情況。
每個頁面固定放置簽名,是個很有效的做法。
¶Sticky 滾動黏滯定位[4:3]
在介紹 sticky 之前,先說說一個實例
在此這個頁面,在內容向上捲動時,希望 menu 離開頁面時,會固定在最上面,一直到 menu 上面的部份再出現時,menu 再跟著頁面往下捲動。(如下圖)

但是
理想與現實之間
是有的差距的(如下圖)!!!
常見的實作bug,有「內容跳動」的情況。
當 menu 要變成 fixed 時,由於從佔 normal flow 空間改成不佔空間的定位方式。跳動的現象,就是後面的元素因為 normal flow 的排列往前排造成的。

過去的做法
用 JavaScript 加上/移除 CSS 的方式。[5]
| :root { | 
用純 CSS 的做法
只需要將 menu 加上這個 CSS,它就會在可視區 top: 0 和 left: 0 的範圍內,隨內容滾動,在範圍以外,固定在邊界。
| .stickyMenu { | 
看似很符合需求,sticky 卻不只是可以這樣。
名詞解釋: sticky-constraint rectangle
容器或 viewport,裡面的div之類的區塊中,其中一個包含著設定position: sticky的元素。
| <div class="container"> | 
sticky 是一種類似 relative 的定位方式,偏移量是參考有 scroll 的容器或者是 可視區 (viewport)。
- 保留原有 normal flow 所佔用的空間
- sticky元素的活動範圍界於 sticky-constraint rectangle 四邊裡面與容器四邊裡面,若之間的空間小於- sticky元素,則- sticky元素被捲出容器四邊
- 偏移量,捲動到離各邊多少,單位使用百分比,其 100% 是該方向容器的尺寸
- element 滾到上下邊界時, margin 會 margins collapse
千言萬語,先看例子就知道
- sticky定位效果與捲動容器邊界之間的關係。
- sticky定位效果與自身容器(sticky-constraint rectangle)之間的關係。
- 上述兩點裡的容器,影響優先權如何
| <div class="container"> | 
| .sticky-element { | 
¶常見用法
例子1: 容器設 relative 給後代元素做 absolute 的偏移參考
| <div class="container"> | 
| .container { | 
例子2: box 置中
新手常遇到的問題,是置中很難處理。
其實絕對定位可以完美的將 box 置中
| <div class="container"> | 
| * { | 
因為 fixed 和 absolute 要符上這個公式[6]
| 'left' + 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing block | 
¶圖層
由於 position 會造成 HTML element 互疊,甚至是內容遮蔽,所以在此必須使用 z-index 調整前景與背景的關係。
在未使用 z-index 時,HTML element 的層級順序,同層是由 html 檔排列順序(由上而下),下面的 html 會渲染在前景。
看個例子

| <div class="blue"> | 
| div { |