文章目錄
文檔流
在講position屬性之前,我們先要了解文檔流的基本概念,有助於我們深入理解position的每個值的特點。
我們來看看什麼是文檔流(normal flow),下面是 www.w3.org 的描述:
Normal flow
Boxes in the normal flow belong to a formatting context, which may be block or inline, but not both simultaneously. Block-level boxes participate in a block formatting context. Inline-level boxes participate in an inline formatting context.
翻譯:
正常流中的框屬於格式化上下文,它可以是塊或內聯的,但不能同時是塊和內聯的。塊級別的框參與塊格式化上下文。內聯級別的框參與內聯格式上下文。
簡單的說就是:
- normal flow直譯爲常規流、正常流,國內大多翻譯爲文檔流
- 窗體自上而下分成一行一行,並在每行中按從左至右的順序排放元素
- 每個非浮動塊級元素都獨佔一行;非浮動的內聯元素則從左到右連續排列,直到改行容納不下再另起一行
- 浮動元素則按規定浮在行的一端,若當前行容不下,則另起新行再浮動
- 幾乎所有元素(包括塊級,內聯和列表元素)均可生成子行,用於擺放子元素
- 有三種情況將使得元素脫離normal flow而存在,分別是 float,absolute ,fixed,但是在IE6中浮動元素也存在於normal flow中。
position詳解
position屬性指定一個元素(靜態的,相對的,絕對或固定)的定位方法的類型。默認取值 static
,它所有可取的值見下表:
可取值 | 描述 |
---|---|
static | 默認值。沒有定位,元素出現在正常的流中(忽略 top, bottom, left, right 或者 z-index 聲明)。 |
relative | 生成相對定位的元素,相對於其正常位置進行定位。 |
absolute | 生成絕對定位的元素,相對於 static 定位以外的第一個父元素進行定位。元素的位置通過 “left”, “top”, “right” 以及 “bottom” 屬性進行規定。 |
fixed | 生成固定定位的元素,相對於瀏覽器窗口進行定位。元素的位置通過 “left”, “top”, “right” 以及 “bottom” 屬性進行規定。 |
sticky | 粘性定位,該定位基於用戶滾動的位置。它的行爲就像 position:relative; 而當頁面滾動超出目標區域時,它的表現就像 position:fixed;,它會固定在目標位置。 注意: Internet Explorer, Edge 15 及更早 IE 版本不支持 sticky 定位。 Safari 需要使用 -webkit- prefix (查看以下實例)。 |
inherit | 規定應該從父元素繼承 position 屬性的值。 |
initial | 設置該屬性爲默認值 |
在開始對每個屬性值進行講解前,先來個思維導圖:
position 之 static
默認值。沒有定位,元素出現在正常的流中(忽略 top, bottom, left, right 或者 z-index 聲明)。
注意:
- 默認從父級元素的左上角開始佈局,如果父級元素有padding屬性,則所在位置會按照padding值進行調整
- 它的margin屬性是相對於postion爲static的位置起作用的(如果附近有relative的元素,則margin是相對於該元素的默認位置計算外邊距)
實例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change-to-flex</title>
<link rel="stylesheet" href="./reset.css">
<style>
body {
margin: 0;
}
.block {
position: relative;
top:10px;
width: 50px;
height: 50px;
line-height: 50px;
text-align: center;
border: 2px solid blue;
box-sizing: border-box;
}
/* 忽略 top 屬性 */
.block:nth-child(2){
position: static;
border-color:red;
}
</style>
</head>
<body>
<div class="block">
A
</div>
<div class="block">
B
</div>
<div class="block">
C
</div>
<div class="block">
D
</div>
</body>
</html>
運行:
從運行結果可以看出,A、C、D元素都相對默認位置,向下偏移了10px,而B因爲是static 的緣故,忽略了top的值,保持默認在文檔流中的位置
position 之 relative
生成相對定位的元素,通過top,bottom,left,right的設置相對於其正常(原先本身)位置進行定位。可通過z-index進行層次分級。
注意:
- 他是默認參照默認static的位置配合TRBL(top,right,bottom,left)進行相對定位
- 可以理解成雖然相對原來的位置發生了偏移,但是原來的位置的坑還佔着在,margin的計算還是參照原來的坑位計算
實例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change-to-flex</title>
<style>
body {
margin: 0;
}
.border {
width: 200px;
height: 224px;
padding: 10px;
border: 2px solid blue;
box-sizing: border-box;
}
.block {
width: 100px;
height: 100px;
background-color: red;
position: relative;
top: 20px;
left: 20px
}
.static {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div class="border">
<div class="block"></div>
<div class="static"></div>
</div>
</body>
</html>
運行:
position 之 absolute
生成絕對定位的元素,相對於 static
定位以外的第一個父元素進行定位。元素的位置通過 “left”, “top”, “right” 以及 “bottom” 屬性進行調整。可通過z-index進行層次分級。
注意:
- 相對於
static
定位以外的第一個父元素進行定位- absolute會造成撐開的父元素髮生坍塌
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change-to-flex</title>
<style>
body {
margin: 0;
}
.block {
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
.border {
width: 300px;
border: 2px solid blue;
}
</style>
</head>
<body>
<div class="border">
<div class="block"></div>
</div>
</body>
</html>
注意:
- 如果position爲absolute的元素的lrtb都沒有設置(即爲auto),則該元素的將仍然會按照正常文檔流佈局,但是其原來在文檔中的坑並不會被佔着,所以父元素仍會有高度坍塌的現象
- Top的值表示對象上邊框與瀏覽器窗口頂部的距離,bottom的值表示對象下邊框與瀏覽器窗口底部的距離,兩者同時存在時,只有Top起作用;如果兩者都未指定,則其頂端將與原文檔流位置一致,即垂直保持位置不變
- left的值表示對象左邊框與瀏覽器窗口左邊的距離,right的值表示對象右邊框與瀏覽器窗口右邊的距離,兩者同時存在時,只有left起作用;如果兩者都未指定,則其左邊將與原文檔流位置一致,即水平保持位置不變
- 1和relative之間的margin回取最大值不同,absolute元素的margin不會和其它的margin合併
實例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change-to-flex</title>
<style>
body {
margin: 0;
}
.border-re {
width: 40px;
height: 40px;
border: 2px solid blue;
margin: 10px;
}
.border {
width: 40px;
height: 40px;
border: 2px solid blue;
margin: 10px;
position: absolute;
}
</style>
</head>
<body>
<div class="border-re"></div>
<div class="border"></div>
</body>
</html>
運行:
position 之 fixed
生成絕對定位的元素,相對於瀏覽器窗口進行定位。元素的位置通過 “left”, “top”, “right” 以及 “bottom” 屬性進行規定。可通過z-index進行層次分級。
注意:
- fixed和relative的特點差不多,唯一的區別就是ltrb的對象不同,一個是非static的父元素,一個是瀏覽器的窗口
position 之 sticky
position屬性中最有意思的就是sticky了,設置了sticky的元素,在屏幕範圍(viewport)時該元素的位置並不受到定位影響(設置是lrtb等屬性無效),當該元素的位置將要移出偏移範圍時,定位又會變成fixed,根據設置的lrtb等屬性成固定位置的效果。
這裏有一段mdn上的描述:
盒位置根據正常流計算(這稱爲正常流動中的位置),然後相對於該元素在流中的 flow root(BFC)和 containing block(最近的塊級祖先元素)定位。在所有情況下(即便被定位元素爲 table時),該元素定位均不對後續元素造成影響。當元素 B 被粘性定位時,後續元素的位置仍按照 B 未定位時的位置來確定。position: sticky對 table元素的效果與 position: relative 相同。
由於sticky並不是w3c推薦的標準,且兼容性不好,這裏就不深入討論了。如果想實現類似的效果,通過js完全可以實現。
———————————————————————————
本文部分內容摘自CSDN博主「姜皓」的原創文章,文章鏈接:https://blog.csdn.net/jianghao233/article/details/80534835