CSS學習摘要 定位 === 註:全文摘自 "MDN CSS定位" 定位允許您從正常的文檔流佈局中取出元素,並使它們具有不同的行為,例如放在另一個元素的上面,或者始終保持在瀏覽器視窗內的同一位置。 本文解釋的是定位( " " )的各種不同值,以及如何使用它們。 文檔流 定位是一個相當複雜的話題,所以 ...
CSS學習摘要-定位
註:全文摘自MDN-CSS定位
定位允許您從正常的文檔流佈局中取出元素,並使它們具有不同的行為,例如放在另一個元素的上面,或者始終保持在瀏覽器視窗內的同一位置。 本文解釋的是定位(position
)的各種不同值,以及如何使用它們。
文檔流
定位是一個相當複雜的話題,所以我們深入瞭解代碼之前,讓我們審視一下佈局理論,並讓我們瞭解它的工作原理。
首先,環繞元素內容添加任何內邊距、邊界和外邊距來佈置單個元素盒子——這就是 盒模型 ,我們前面看過。 預設情況下,塊級元素的內容寬度是其父元素的寬度的100%,並且與其內容一樣高。內聯元素高寬與他們的內容高寬一樣。您不能對內聯元素設置寬度或高度——它們只是位於塊級元素的內容中。 如果要以這種方式控制內聯元素的大小,則需要將其設置為類似塊級元素 display: block;
。
這隻是解釋了單個元素,但是元素相互之間如何交互呢? 正常的佈局流(在佈局介紹文章中提到)是將元素放置在瀏覽器視口內的系統。預設情況下,塊級元素在視口中垂直佈局——每個都將顯示在上一個元素下麵的新行上,並且它們的外邊距將分隔開它們。
內聯元素表現不一樣——它們不會出現在新行上;相反,它們互相之間以及任何相鄰(或被包裹)的文本內容位於同一行上,只要在父塊級元素的寬度內有空間可以這樣做。如果沒有空間,那麼溢流的文本或元素將向下移動到新行。
如果兩個相鄰元素都在其上設置外邊距,並且兩個外邊距接觸,則兩個外邊距中的較大者保留,較小的一個消失——這叫外邊距摺疊, 我們之前也遇到過。
讓我們來看一個簡單的例子來解析這一切:
<h1>Basic document flow</h1>
<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
<p>By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
body {
width: 500px;
margin: 0 auto;
}
p {
background: aqua;
border: 3px solid blue;
padding: 10px;
margin: 10px;
}
span {
background: red;
border: 1px solid black;
}
在我們閱讀本文時,我們將多次重覆這個例子,因為我們要展示不同定位選項的效果。
如果可能,我們希望您在本地電腦上跟隨練習 — 從GitHub倉庫下載一個[0_basic-flow.html](http://mdn.github.io/learning-area/css/css-layout/positioning/0_basic-flow.html)
(源代碼) 然後用它作為我們的起步點。
介紹定位
定位的整個想法是允許我們覆蓋上面描述的基本文檔流行為,以產生有趣的效果。如果你想稍微改變佈局中一些盒子的位置,使它們的預設佈局流程位置稍微有點古怪,不舒服的感覺呢?定位是你的工具。或者,如果您想要創建一個浮動在頁面其他部分頂部的UI元素,並且/或者始終停留在瀏覽器視窗內的相同位置,無論頁面滾動多少?定位使這種佈局工作成為可能。
有許多不同類型的定位,您可以對HTML元素生效。要使某個元素上的特定類型的定位,我們使用position
屬性。
靜態定位
靜態定位是每個元素獲取的預設值——它只是意味著“將元素放入它在文檔佈局流中的正常位置 ——這裡沒有什麼特別的。
為了演示這一點,併為以後的部分設置示例,首先在HTML中添加一個positioned
的 class
到第二個<p>
:
<p class="positioned"> ... </p>
現在,將以下規則添加到CSS的底部:
.positioned {
position: static;
background: yellow;
}
如果現在保存和刷新,除了第2段的更新的背景顏色,根本沒有差別。這很好——正如我們之前所說,靜態定位是預設行為!
相對定位
相對定位是我們將要看的第一個位置類型。 它與靜態定位非常相似,占據在正常的文檔流中,除了你仍然可以修改它的最終位置,包括讓它與頁面上的其他元素重疊。 讓我們繼續並更新代碼中的 position 屬性:
position: relative;
如果您在此階段保存並刷新,則結果根本不會發生變化——那麼如何修改元素的位置呢? 您需要使用top
,bottom
,left
和right
屬性 ,我們將在下一節中解釋。
介紹 top, bottom, left, right
top
top樣式屬性定義了定位元素的上外邊距邊界與其包含塊上邊界之間的偏移,非定位元素設置此屬性無效。bottom
bottom樣式屬性定義了定位元素下外邊距邊界與其包含塊下邊界之間的偏移,非定位元素設置此屬性無效。left
left屬性定義了定位元素的左外邊距邊界與其包含塊左邊界之間的偏移,非定位元素設置此屬性無效。right
right樣式屬性定義了定位元素的右外邊距邊界與其包含塊右邊界之間的偏移,非定位元素設置此屬性無效。
使用上述四個屬性來精確指定要將定位元素移動到的位置。 要嘗試這樣做,請在CSS中的 .positioned
規則中添加以下聲明:
top: 30px;
left: 30px;
註意:這些屬性的值可以採用邏輯上期望的任何單位 ——px,mm,rems,%等。
如果你現在保存和刷新,你會得到一個這樣的結果:
酷,是嗎? 好吧,所以這個結果這可能不是你期待的——為什麼它移動到底部和右邊,但我們指定頂部和左邊? 聽起來不合邏輯,但這隻是相對定位工作的方式——你需要考慮一個看不見的力,推動定位的盒子的一側,移動它的相反方向。 所以例如,如果你指定 top: 30px;
一個力推動框的頂部,使它向下移動30px。
絕對定位
絕對定位帶來了非常不同的結果。讓我們嘗試改變代碼中的位置聲明如下:
position: absolute;
如果你現在保存和刷新,你應該看到這樣:
首先,請註意,定位的元素應該在文檔流中的間隙不再存在——第一和第三元素已經關閉在一起,就像它不再存在!好吧,在某種程度上,這是真的。絕對定位的元素不再存在於正常文檔佈局流中。相反,它坐在它自己的層獨立於一切。這是非常有用的——這意味著我們可以創建不幹擾頁面上其他元素的位置的隔離的UI功能 ——例如彈出信息框和控制菜單,翻轉面板,可以在頁面上的任何地方拖放的UI功能等。
第二,註意元素的位置已經改變——這是因為top
,bottom
,left
和right
以不同的方式在絕對定位。 它們指定元素應距離每個包含元素的邊的距離,而不是指定元素應該移入的方向。 所以在這種情況下,我們說的絕對定位元素應該位於從“包含元素”的頂部30px,從左邊30px。
註意:您可以使用top
,bottom
,left
和right
如果需要,調整元素大小。 嘗試設置 top: 0; bottom: 0; left: 0; right: 0;
和 margin: 0;
對你定位的元素,看看會發生什麼! 之後再回來。
註意:是的,外邊距仍會影響定位的元素。 然而,外邊距摺疊不會。
定位上下文
哪個元素是絕對定位元素的“包含元素”? 預設情況下,它是<html>
元素——定位的元素是被嵌套在<body>
中的HTML源代碼,但在最終的佈局,它離頁面邊緣的頂部和左側30px距離,這是<html>
元素。 這更準確地稱為元素的定位上下文。
我們可以改變定位上下文——絕對定位的元素相對於其定位的元素。 這是通過在元素的其他祖先之一上設置定位來實現的——它是嵌套在其中的元素之一(你不能相對於其中沒有嵌套的元素來定位它)。 為了演示這一點,將以下聲明添加到您的body規則中:
position: relative;
這應該給出以下結果:
定位的元素現在相對於<body>
元素。
介紹 z-index
所有這些絕對定位很有趣,但還有另一件事我們還沒有考慮到 ——當元素開始重疊,什麼決定哪些元素出現在其他元素的頂部? 在我們已經看到的示例中,我們在定位上下文中只有一個定位的元素,它出現在頂部,因為定位的元素勝過未定位的元素。 當我們有不止一個的時候呢?
嘗試添加以下到您的CSS,使第一段也是絕對定位:
p:nth-of-type(1) {
position: absolute;
background: lime;
top: 10px;
right: 30px;
}
此時,您將看到第一段的顏色為綠色,移出文檔流程,並位於原始位置上方一點。它也堆疊在原始的 .positioned
段落下,其中兩個重疊。這是因為 .positioned
段落是源順序中的第二個段落,並且源順序中後定位的元素將贏得先定位的元素。
您可以更改堆疊順序嗎?是的,您可以使用z-index
屬性。 “z-index”是對z軸的參考。你可以從源代碼中的上一點回想一下,我們使用水平(x軸)和垂直(y軸)坐標來討論網頁,以確定像背景圖像和陰影偏移之類的東西的位置。 (0,0)位於頁面(或元素)的左上角,x和y軸跨頁面向右和向下(適合從左到右的語言,無論如何)。
網頁也有一個z軸——一條從屏幕錶面到你的臉(或者在屏幕前面你喜歡的任何其他東西)的虛線。z-index
值影響定位元素位於該軸上的位置——正值將它們移動到堆棧上方,負值將它們向下移動到堆棧中。預設情況下,定位的元素都具有z-index為auto,實際上為0。
要更改堆疊順序,請嘗試將以下聲明添加到 p:nth-of-type(1)
規則中:
z-index: 1;
你現在應該看到完成的例子:
請註意,z-index只接受無單位索引值;你不能指定你想要一個元素是Z軸上23像素—— 它不這樣工作。 較高的值將高於較低的值,這取決於您使用的值。 使用2和3將產生與300和40000相同的效果。
固定定位
還有一種類型的定位覆蓋——fixed。 這與絕對定位的工作方式完全相同,只有一個主要區別——絕對定位固定元素是相對於 <html>
元素或其最近的定位祖先,而固定定位固定元素則是相對於瀏覽器視口本身。 這意味著您可以創建固定的有用的UI項目,如持久導航菜單。
讓我們舉一個簡單的例子來說明我們的意思。首先,從CSS中刪除現有的 p:nth-of-type(1)
和.positioned
規則。
現在,更新 body
規則以刪除position: relative;
聲明並添加固定高度,如此:
body {
width: 500px;
height: 1400px;
margin: 0 auto;
}
現在我們要給<h1>
元素 position: fixed;
,並讓它坐在視口的頂部中心。將以下規則添加到CSS:
h1 {
position: fixed;
top: 0;
width: 500px;
margin: 0 auto;
background: white;
padding: 10px;
}
top: 0;
是要使它貼在屏幕的頂部;我們然後給出標題與內容列相同的寬度,並使用可靠的老技巧 margin: 0 auto;
使它居中。 然後我們給它一個白色背景和一些內邊距,所以內容將不會在它下麵可見。
如果您現在保存並刷新,您會看到一個有趣的小效果,標題保持固定,內容顯示向上滾動並消失在其下。 但是我們可以改進這一點——目前標題下麵擋住一些內容的開頭。這是因為定位的標題不再出現在文檔流中,所以其他內容向上移動到頂部。 我們要把它向下移動一點;我們可以通過在第一段設置一些頂部邊距來做到這一點。添加:
p:nth-of-type(1) {
margin-top: 60px;
}
你現在應該看到完成的例子:
實驗屬性: position sticky
有一個新的定位值可用稱為 position: sticky
,尚未廣泛支持。 這基本上是相對位置和固定位置之間的混合,其允許定位的元件像它被相對定位一樣動作,直到其滾動到某一閾值點(例如,從視口頂部10像素),之後它變得固定。閱讀我們的position:sticky 引用入口 查看詳情和例子。
總結
我相信你用基本定位愉快地玩耍——它是創建複雜的CSS佈局和UI功能背後的基本工具之一。 考慮到這一點,在下一篇文章中,我們將更有趣的定位——我們將進一步,開始建立一些真實世界有用的東西。
【end】