【百度前端技術學院 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;

絕對定位的元素不再存在於正常文檔布局流中。topbottomleftright以不同的方式在絕對定位,它們指定元素應距離每個包含元素的邊的距離,而不是指定元素應該移入的方向。

1.2.4 定位上下文

判斷絕對定位元素的包含元素的方式:取決於絕對定位元素的父元素的position屬性

  1. 所有的父元素都沒有顯式地定義position屬性:父元素默認情況下position屬性都是static。絕對定位元素會被包含在初始塊容器中(和瀏覽器視口一樣的尺寸)。
  2. 其中一個父元素的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留出位置。