CSS position
屬性規定一個元素在文檔中的定位類型。top
,right
,bottom
和left
屬性則決定了該元素的最終位置。
Object.style.position = static | relative | absolute | fixed | sticky
先解釋下什么是文檔流:
將窗體自上而下分成一行行, 並在每行中按從左至右的順序排放元素,即為文檔流
static 靜態定位(默認)
默認值,元素出現在正常的流中。位置設置為static的元素,它始終處於正常文檔流給予的位置,不影響其他元素的偏移。(static 元素會忽略任何 top、bottom、left 、 right 或者 z-index 聲明)。
relative 相對定位
位置設置為 relative 的元素,相對於其正常位置進行定位,該元素會在正常文檔流中會占據位置,從而不影響其他元素的偏移。此元素的位置可通過 "left"、"top"、"right" 以及 "bottom" 屬性來規定。因此 "left:20px" 會將元素移至元素正常位置左邊 20 個像素的位置。
我們用個簡單例子分析
正常文檔流
<div style="width: 200px; height:200px; background-color:green;">
<div style="width: 100px; height:100px;background-color: #cff;">
1
</div>
<div style="width: 100px; height:100px; background-color: #ccf;">
2
</div>
</div>
加了relative之后的布局
<div style="width: 200px; height:200px; background-color:green;">
<div style="width: 100px; height:100px;background-color: #cff; position: relative;top: 10px;left:10px;">
1
</div>
<div style="width: 100px; height:100px; background-color: #ccf;">
2
</div>
</div>
加上margin/padding/border之后的布局
記住一點,relative是相對自身定位。加上margin/padding/border之后,是在這些屬性起作用之后,再來計算relative。
<div style="width: 200px; height:200px; background-color:green;">
<div style="width: 100px; height:100px;background-color: #cff; margin: 10px; padding: 10px; border: 10px solid red; position: relative;top: 10px;left:10px;">
1
</div>
<div style="width: 100px; height:100px; background-color: #ccf;">
2
</div>
</div>
加上margin/padding/border之后圖對比:
absolute 絕對定位
位置設置為 absolute 的元素,相對於非`static`定位以外的第一個父元素進行絕對定位,脫離了正常文檔流,該元素不占據正常文檔流空間,因此會影響其他元素的偏移。此元素的位置可通過 "left"、"top"、"right" 以及 "bottom" 屬性來規定。
我們用個簡單例子分析
正常文檔流
<div style="width: 200px; height:200px; background-color:green; position: relative;">
<div style="width: 100px; height:100px;background-color: #cff;">
1111111111
</div>
<div style="width: 100px; height:100px; background-color: #ccf;">
我是2,我在下面 .....我是2,。我在下面,會被覆蓋?
</div>
</div>
加了absolute之后的布局
設置為絕對定位之后,被定位的元素會以 “第一個設置了定位的祖先元素” 定位,這里就是第一個div元素。
<div style="width: 200px; height:200px; background-color:green; position: relative;">
<div style="width: 100px; height:100px;background-color: #cff; position: absolute;top: 10px; left: 10px;">
1111111111
</div>
<div style="width: 100px; height:100px; background-color: #ccf;">
我是2,我在下面 .....我是2,。我在下面,會被覆蓋?
</div>
</div>
加上margin/padding/border之后的布局
記住一點,absolute是相對第一個被定位的祖先元素。加上margin/padding/border之后,也是在這些屬性起作用之后,再來計算absolute。
<div style="width: 200px; height:200px; background-color:green; position: relative;">
<div style="width: 100px; height:100px;background-color: #cff;
position: absolute;top: 10px; left: 10px;margin: 10px; padding: 10px;border: 10px solid red;">
1111111111
</div>
<div style="width: 100px; height:100px; background-color: #ccf;">
我是2,我在下面 .....我是2,。我在下面,會被覆蓋?
</div>
</div>
加上margin/padding/border之后,absolute定位的對比圖:
fixed 固定定位
位置被設置為 fixed 的元素,可相對於瀏覽器視口(viewport)進行定位。不論窗口滾動與否,元素都會留在那個位置。工作於 IE7(strict 模式),低版本的IE不支持。此元素的位置可通過 "left"、"top"、"right" 以及"bottom" 屬性來規定。`fixed`屬性會創建新的層疊上下文。當元素祖先的`transform`屬性非`none`時,容器由視口改為該祖先。
正常情況的定位,請看最后的例子。這里着重說下transform
屬性非none
值時候,fixed
的表現。transform
屬性向元素應用2D 或 3D 轉換。該屬性允許我們對元素進行旋轉,縮放,移動或傾斜。
<div style="transform: rotate(10deg); width: 200px; height: 200px; border: 1px dotted red;">我定義transform屬性
<div style="position: fixed; left: 50px; bottom: 100px; border: 1px solid red; background-color: #ffc;">
我是第二個fixed,我在哪里?我使用fixed定位
</div>
</div>
體現的布局:
從此圖中,可以看出。fixed
定位是相對於父元素有transform
屬性非none
值來決定的。
sticky 粘性定位
盒位置根據正常流計算(這稱為正常流動中的位置),然后相對於該元素在流中的 flow root(BFC)和 containing block(最近的塊級祖先元素)定位。在所有情況下(即便被定位元素為 table 時),該元素定位均不對后續元素造成影響。當元素 B 被粘性定位時,后續元素的位置仍按照 B 未定位時的位置來確定。position: sticky 對 table 元素的效果與 position: relative 相同。
注意的點
- 這里的幾個屬性,都可以理解為相對定位,只是參照物不一樣。
relative,參照物為自己。
absolute,參照物為有定位(非static定位)的父元素。
fixed, 參照物為瀏覽器的視口。
sticky,參照物為瀏覽器視口。設置不同方向的值,會粘住於不同方向。 - 我們知道html和body元素相差有8px。relative和static方式在最外層時是以body標簽為定位原點的,而absolute方式在無父級是position非static定位時是以html作為原點定位。
- sticky 粘性定位,須指定 top,right,bottom和left四個閾值其中之一,才可使粘性定位生效。否則其行為與相對定位相同。
- 如果只設置position屬性,覆蓋程度:relative > fixed > absolute > sticky > static,relative會在最上面。(關於這一點,還是有點點疑惑的,為什么會這樣,或者為什么不是這樣)
此文檔對應的例子
https://codepen.io/weiqinl/pen/BqeQoQ
里面有position各種屬性的情況。