【百度前端技術學院 Day7/8】布局
1. 定位
1.1 文檔流
單個元素:
- 塊級元素:內容寬度是其父元素的寬度的100%,並且與其內容一樣高。
- 內聯(行內)元素:高寬與他們的內容高寬一樣。(所以不能為他們設置寬高)
元素之間的交互:
- 塊級元素:在視口中垂直布局——每個都將顯示在上一個元素下面的新行上。
- 內聯元素:它們互相之間以及任何相鄰(或被包裹)的文本內容位於同一行上。如果沒有空間,那麼溢出的文本或元素將向下移動到新行。
- 外邊距摺疊:兩個外邊距接觸,則兩個外邊距中的較大者保留,較小的一個消失。
1.2 介紹定位
1.2.1 靜態定位
靜態定位是每個元素獲取的默認值——它只是意味着將元素放入它在文檔布局流中的正常位置。
1.2.2 相對定位
position: relative;
top
, bottom
, left
, 和 right
來精確指定要將定位元素移動到的位置。
PS:描述和實際情況相反,比如你設置【top: 30px;】你將會看到你所選擇的元素向下移動了30px,這是相對定位工作的方式。你可以想像一個力作用在這個盒子的頂部,將它向下推了30px。
1.2.3 絕對定位
position: absolute;
絕對定位的元素不再存在於正常文檔布局流中。top
,bottom
,left
和right
以不同的方式在絕對定位,它們指定元素應距離每個包含元素的邊的距離,而不是指定元素應該移入的方向。
1.2.4 定位上下文
判斷絕對定位元素的包含元素的方式:取決於絕對定位元素的父元素的position屬性。
- 所有的父元素都沒有顯式地定義position屬性:父元素默認情況下position屬性都是static。絕對定位元素會被包含在初始塊容器中(和瀏覽器視口一樣的尺寸)。
- 其中一個父元素的position屬性是relative:相對於這個父元素進行定位。
1.2.5 z-index
「z-index」是對z軸的參考(無單位)。正值將它們移動到堆棧上方,負值將它們向下移動到堆棧中。默認情況下,定位的元素都具有z-index為auto,實際上為0。
1.2.6 固定定位
fixed:這與絕對定位的工作方式完全相同。絕對定位固定元素是相對於 <html>
元素或其最近的定位祖先,而固定定位固定元素則是相對於瀏覽器視口本身。
1.2.7 position: sticky
被定位的元素表現得像相對定位一樣,直到它滾動到某個閾值點為止,此後它就變得固定了。
2. Flexbox
我們想要將哪些元素設置為Flexbox,就需要給這些flexible元素的父元素display設置為一個特定值——flex。
PS:如果想設置行內元素為flexible box,也可以設置display屬性為inline-flex。
2.1 flex模型說明
- 主軸(main axis)是沿着 flex 元素放置的方向延伸的軸(比如頁面上的橫向的行、縱向的列)。該軸的開始和結束被稱為 main start 和 main end。
- 交叉軸(cross axis)是垂直於 flex 元素放置方向的軸。該軸的開始和結束被稱為 cross start 和 cross end。
- 設置了
display: flex
的父元素被稱之為 flex 容器(flex container)。 - 在 flex 容器中表現為柔性的盒子的元素被稱之為 flex 項(flex item)。
=> 主軸的方向可以設置,Flexbox提供了flex-direction這個屬性:
row(默認值)/ column / row-reverse / cilumn-reverse (reverse為反向排列flex項)
flex是三個屬性的縮寫:flex-grow/flex-shrink /flex-basis
-
flex-grow:無單位比例
flex-shrink
:指定了從每個 flex 項中取出多少溢出量,以阻止它們溢出它們的容器flex-basis
:最小值
2.2 換行
當在布局中使用了定寬或者定高時,可能會出現flexbox中子元素溢出破壞布局的情況。解決方法如下:
flex-wrap: wrap;
flex: 200px; //表示每個元素的寬度至少是200px
這樣就實現了換行操作:任何溢出的元素都會被移到下一行。最後一行如果沒有排滿,那麼最後一行的元素會變得更寬,以便把整個行填滿。
PS:flex-direction 和 flex-wrap 可以縮寫為 flex-flow 。
flex-direction: row;
flex-wrap: wrap;
//下面這一句是一樣的意思
flex-flow: row wrap;
2.3 flex項的動態尺寸
article { flex: 1; } article:nth-of-type(3){ flex: 2; }
我們設置的flex值是一個無單位的比例值,表示每個flex項沿主軸的可用空間大小。只看第一個article,表示每個元素佔用的空間是相等的(佔用空間是指設置padding和margin之後剩餘的空間)。而後面一句表示第三個元素要佔用兩倍可用寬度。也就是說,前兩個元素每個佔1/4的空間,第三個元素佔1/2。
article { flex: 1 200px; } article:nth-of-type(3){ flex: 2 200px; }
這裡的200px是給flex指定了最小值。意味着給每個項首先分出200px可用空間,剩餘的空間再根據設置的比例進行分配。
=>flexbox的價值就在於它的響應性。如果調整瀏覽器窗口的大小或增加一個元素,布局仍然是正確的。
2.4 水平和垂直對齊
- align-items:控制flex項在交叉軸上的位置。
- stretch(默認值):所有的flex項沿着交叉軸的拉伸以填充父容器。如果父容器在交叉軸方向上沒有固定寬高,則變為最長的flex項的長度。
- center:這些項保持原有的高度,但在交叉軸居中。
- flex-start / flex-end:使flex項在交叉軸的開始/結束處對齊所有的值。
- justify-content:控制flex項在主軸上的位置。
- flex-start(默認值):所有項都位於主軸的開始處。
- flex-end:所有項都位於結尾處。
- center:讓flex項在主軸居中。
- space-around:讓所有的flex項在主軸均勻地分佈,再任意一段都留有一定的空間。
- space-between:不會在兩端留下空間。
PS:align-self屬性可以覆蓋align-items的行為。
2.5 flex項排序
flexbox可以改變flex項布局位置,且不會影響到源程序。
button:first-child{ order: 1; }
這裡設置的order值是用於排序的。
所有flex項的默認order值是0,order值大的比小的顯示順序更加靠後,相同order值的項按照源順序顯示。當然也可以給order設置負值讓他們排的更前面。
2.6 flex嵌套
一個元素是flex項,他同樣可以成為一個flex容器,它的子節點也表現為flexible box。
3. 網頁布局
3.1 一列布局
margin : 0 auto;
3.2 兩列布局
1. 雙inline-block
.wrapper { font-size: 0; } .left, .right { display: inline-block; vertical-align: top; box-sizing: border-box; } .right { width: calc(100% - 140px); }
2. 雙float
.wrapper{ overflow: auto; } .left, .right { float: left; box-sizing: border-box; } .right { width: calc(100% - 140px); }
3. float + margin-left
.wrapper-float { overflow: hidden; } .left { float: left; } .right { margin-left: 150px; }
4. absolute + margin-left
.left { position: absolute; } .right { margin-left: 150px; }
5. float + BFC
.wrapper { overflow: auto; } .left { float: left; margin-right: 20px; } .right { margin-left: 0; overflow: auto; }
6. flex
.wrapper { display: flex; align-items: flex-start; } .left { flex: 0 0 auto; } .right { flex: 1 1 auto; }
3.3 三列布局
三列布局指的是兩側定寬中間自適應。
1. 聖杯布局
為了中間div內容不被遮擋,將中間div設置了左右padding-left和padding-right後,將左右兩個div用相對布局position: relative並分別配合right和left屬性,以便左右兩欄div移動後不遮擋中間div。
2. 雙飛翼布局
為了中間div內容不被遮擋,直接在中間div內部創建子div用於放置內容,在該子div里用margin-left和margin-right為左右兩欄div留出位置。