> For the complete documentation index, see [llms.txt](https://information9527.gitbook.io/html/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://information9527.gitbook.io/html/2.css/position.md).

# Position

在 CSS 中，有三種可控制的方式，放置 box \[1]

1. Normal flow 自然排列\[2]
2. `float` 排列\[3]
3. `position` 定位

### 語法

```css
position: 定位方法
top: 數字
bottom: 數字
left: 數字
right: 數字
```

* 上下左右的設定用得上再使用
* 定位並不會造成單位變化，所以可以這樣換算 `left` = -`right`, `top` = -`bottom`

## Position定位種類

### 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 有些跨欄偏移的應用

&#x20;relative 和 static 其實非常像，但在 relative 的情況下可以使用 `top`,`right`, `bottom`, `left`, `z-index` 且不影響其他 elements 的排列。也就是像下面這個樣子：

![](/files/-MbdYkmGFyVmQ3eyh7k2)

&#x20;藍色的方塊還以為綠色的方塊還在原本的位置上，但實際上綠色的方塊已經透過 `top`,`right`, `bottom`, `left` 屬性偏移原本的位置了。另一方面，你也會注意到，在 HTML 結構上先出現的綠色方塊，這時候覆蓋在藍色方塊上，這是因為當我們設定 `position: relative` 時，會創造出一個新的 "stacking context"，這個新的 stacking context 出現在原本的 stacking context 之後，所以在 z-index 層級上會變得比較高。

### Absolute 絕對定位\[4]

原本畫面上的 box 會依照 Normal flow 排列。

假設有個叫 box 的HTML element 設定 `position: absolute` 會有什麼影響

* 跳脫 normal flow 排列規則，不佔有任何空間。
* 不會影響其它 normal flow 的 HTML Element
* 偏移量是相對於有「非 `position: static` 」的位置
* box 以內有 normal flow 和 `position: absolute` 的都與 box 相關
* 會導致元素重疊

以下圖為例，白色方塊設定了 `position: relative` ，當綠色方塊設定了 `position: absolute` 要往父層找參考點的時候，就會找到白色方塊，然後因為此時設定 `top: 0; left: 0`，所以就會直接黏在白色方塊的左上角。

![](/files/-MbdZA8bRUZJzAEkFu5F)

同時你也會發現，因為綠色方塊脫離了原本的排版，所以藍色方塊就當綠色方塊不存在，直接排在紅色方塊後面，跟`position: relative` 的狀況不一樣。

&#x20;但如果我們忘記在白色方塊設定 `position: relative` 的時候，會發生什麼事情呢？這時候綠色方塊就會一路往上找，找到上一個創造出 stacking context 的 element，也就是 html 上

![](/files/-MbdZrmI1e_oKc0rY54n)

&#x20;最後一提的是，不是只能找到 `position: relative` 的 element 才能當作參考點，`position: absolute`, `position: fixed` 也都可以喔。

### Fixed 可視區的絕對定位\[4]

可視區的絕對定位，唸起來很呦口。我也不知道怎麼翻才好。

這是一種類似絕對定位的定位方式。唯一的區別在於偏移量參考點

* absolute 參考容器(的容器)中，使用「非 static 定位」的容器
* 偏移量是相對於可視區 (viewport)
* 每個可視區都會重複 fixed 定位的內容

在內容捲動時，被 `fixed` 的元素會固定不移動。類似固定背景的效果

> 有 Media Query 時，有用到 paged 類型，要注意重複的情況。\
> 每個頁面固定放置簽名，是個很有效的做法。

```
position: fixed
```

如果弄清楚了 `position: abosolute` 的特性，那麼要理解 `position: fixed` 就相對簡單多了。不同於 `absolute`，`fixed` 的參考點在 viewport 上，也就是說，它是以使用者可以看到的畫面做為參考點，常見的應用就是，讓一個 element 固定在畫面的某個地方，不會因為畫面滾動而有所改變。

另一個有趣的事情是，如果我們要將網頁印成文件，那麼這個 `fixed` 的 element 會出現在每一頁的同一個位置上。

### Sticky 滾動黏滯定位\[4]

`sticky` 是一種類似 `relative` 的定位方式，偏移量是參考有 scroll 的容器或者是 可視區 (viewport)。

* 保留原有 normal flow 所佔用的空間
* `sticky` 元素的活動範圍界於 sticky-constraint rectangle 四邊裡面與容器四邊裡面，若之間的空間小於`sticky` 元素，則`sticky` 元素被捲出容器四邊
* 偏移量，捲動到離各邊多少，單位使用百分比，其 100% 是該方向容器的尺寸
* element 滾到上下邊界時， margin 會 margins collapse

```
position: sticky
```

根據 MDN 上的說明，`sticky` element 不會脫離原本的排版流，跟 `relative` 有點像，但是會黏在最近的 "scrolling ancestor" 上。

什麼是 "scrolling ancestor" 呢？可以想像創造出可滾動的父層元素，像是有設定 overflow 的 elements，或者是，整個 html 文件本身。

知道什麼是 scrolling ancestor 之後，`sticky` element 的行為就是：

* 在還沒有碰到 scrolling ancestor，就像是 `position: relative` 一樣
* 在碰到 scrolling ancestor 後，就像是 `position: absolute` 一樣，位置會固定在相對於參考點的絕對位置上，而這個參考點就是 scrolling ancestor。

舉下面的例子，container 當中的 elements 高度遠大於 container 的高度，因為有設定 `overflow` 因此產生滾動效果。對於有設定 `position: sticky` 的綠色方塊來說，使用者一路往下滑、綠色方塊往上跑的時，當綠色方塊碰到 scrolling ancestor，也就是 container 的時候，就會「黏在」他上面。當然「黏的」的位置，可以透過 `top`, `right`, `bottom`, `left` 來決定。
