正常布局流
瀏覽器在默認(rèn)情況下陶珠,組織元素的布局方式:
- 任何元素都被包裝成一個(gè)盒子,包含內(nèi)容享钞、內(nèi)外邊距以及邊框
- 塊級(jí)元素會(huì)基于其父元素的書(shū)寫(xiě)順序進(jìn)行放置揍诽,每個(gè)塊級(jí)元素會(huì)在上一個(gè)元素下面另起一行,它們會(huì)被設(shè)置好的margin 分隔
- 內(nèi)聯(lián)元素的表現(xiàn)有所不同 --- 它們不會(huì)另起一行栗竖;只要在其父級(jí)塊級(jí)元素的寬度內(nèi)有足夠的空間暑脆,它們與其他內(nèi)聯(lián)元素、相鄰的文本內(nèi)容(或者被包裹的)被安排在同一行狐肢。如果空間不夠添吗,溢出的文本或元素將移到新的一行
- 如果兩個(gè)相鄰的元素都設(shè)置了margin 并且兩個(gè)margin有重疊,那么更大的設(shè)置會(huì)被保留份名,小的則會(huì)消失 --- 這被稱(chēng)為外邊距疊加
定位(Position)
定位的目的即允許我們通過(guò)某種手段覆蓋上述正常布局流文檔碟联,以按照我們想要的效果來(lái)進(jìn)行排版
靜態(tài)定位(static)
靜態(tài)定位是每個(gè)元素獲取的默認(rèn)值——它只是意味著“將元素放入它在文檔布局流中的正常位置 ——這里沒(méi)有什么特別的,比如在某個(gè)規(guī)則中添加position屬性僵腺,并使其值為static:
.positioned {
background: yellow;
position: static;
}
此代碼和添加position屬性之前沒(méi)有任何區(qū)別玄帕,即:靜態(tài)定位是每個(gè)元素的默認(rèn)行為
相對(duì)定位(relative)
相對(duì)定位仍可以使該元素占據(jù)正常文本流,但是可以通過(guò)top想邦、bottom裤纹、left和right屬性修改它的最終位置,包括讓它與頁(yè)面上的其它元素重疊
.relative{
position: relative;
top: 30px;
left: 30px;
}
這里的結(jié)果表示,應(yīng)用position: relative的元素相對(duì)于其原來(lái)所處的位置向下移動(dòng)了30px鹰椒,向右移動(dòng)了30px
- relative 表現(xiàn)的和 static 一樣锡移,除非你添加了一些額外的屬性
- 在一個(gè)相對(duì)定位(position屬性的值為relative)的元素上設(shè)置 top 、 right 漆际、bottom 和 left 屬性會(huì)使其偏離其正常位置淆珊。其他的元素的位置則不會(huì)受該元素的影響發(fā)生位置改變來(lái)彌補(bǔ)它偏離后剩下的空隙
絕對(duì)定位
與相對(duì)定位不同,絕對(duì)定位的元素不再存在于正常文本流中奸汇。相反票灰,它處于獨(dú)立于正常文本流的一層碗短,因此后面的元素會(huì)填補(bǔ)其空出的位置
.absolute{
position: absolute;
top: 30px;
left: 30px;
}
需要注意這里的結(jié)果,這和relative的結(jié)果很不一樣,被設(shè)置為position: absolute的元素會(huì)相對(duì)于其父元素(這里是body)產(chǎn)生位置偏移蚯舱,這里是距離父元素的頂部邊框30px妈经,距離父元素的左邊框30px
這里有另一個(gè)例子芹敌,設(shè)置父元素的position值為relative會(huì)讓其設(shè)置絕對(duì)定位的子元素看起來(lái)很不一樣:
.relative {
position: relative;
width: 600px;
height: 400px;
}
.absolute {
position: absolute;
top: 120px;
right: 0;
width: 300px;
height: 200px;
}
因此一個(gè)元素的絕對(duì)定位的具體表現(xiàn)與其父元素的定位方式有很大關(guān)系:
如果元素是靜態(tài)定位的蠢沿。即如果它是 position: static ,那么它的絕對(duì)定位子元素會(huì)跳過(guò)它直接相對(duì)于body元素定位
z-index
當(dāng)多個(gè)元素使用絕對(duì)定位時(shí)塘雳,難免會(huì)造成彼此之間的重疊陆盘,因此要決定哪些元素在哪些元素的頂部就顯得非常重要,這也是為什么我們要設(shè)置z-index的原因
這實(shí)際上和圖層原理很相似败明,凡是定位的元素都具有z-index的值為auto隘马,實(shí)際上是0
如果不設(shè)置z-index的值,則元素的原始堆疊順序是:在html標(biāo)記中妻顶,定義順序越靠后的元素將堆疊在靠前元素的上面
如果設(shè)置了z-index的值祟霍,則值越大的元素會(huì)疊加在值越小的元素上面
圖中綠色背景框與黃色背景框都被設(shè)置成position:absolute,但因?yàn)榫G色背景框的CSS規(guī)則中設(shè)置了z-index值:
z-index: 1;
而黃色背景框的z-index值默認(rèn)為0盈包,所以綠色疊加在了黃色上面
需要注意的是:z-index只接受無(wú)單位索引值沸呐;你不能指定你想要一個(gè)元素是Z軸上23像素—— 它不這樣工作。 較高的值將高于較低的值呢燥,這取決于您使用的值崭添。 使用2和3將產(chǎn)生與300和40000相同的效果
固定定位
還有一種類(lèi)型的定位覆蓋——fixed。 這與絕對(duì)定位(absolute)的工作方式完全相同叛氨,只有一個(gè)主要區(qū)別:絕對(duì)定位固定元素是相對(duì)于<html>或其最近的定位祖先呼渣,而固定定位固定元素則是相對(duì)于瀏覽器視口本身。 這意味著您可以創(chuàng)建固定的有用的UI項(xiàng)目寞埠,如持久導(dǎo)航菜單
position:sticky
還有一個(gè)可用的位置值稱(chēng)為 position: sticky屁置,比起其他位置值要新一些。它基本上是相對(duì)位置和固定位置的混合體仁连,它允許被定位的元素表現(xiàn)得像相對(duì)定位一樣蓝角,直到它滾動(dòng)到某個(gè)閾值點(diǎn)(例如阱穗,從視口頂部起10像素)為止,此后它就變得固定了使鹅。例如揪阶,它可用于使導(dǎo)航欄隨頁(yè)面滾動(dòng)直到特定點(diǎn),然后粘貼在頁(yè)面頂部
例子:
https://www.w3school.com.cn/tiy/t.asp?f=css_position_sticky
參考:
https://zh.learnlayout.com/position.html
彈性盒子(FlexBox)
即便大多數(shù)情況下患朱,使用float和position屬性就能完成大多數(shù)布局鲁僚,但還是有一些情況是這兩種屬性很難完成、甚至無(wú)法完成的裁厅,因此引入“彈性盒子”可以更好的幫助我們完成網(wǎng)頁(yè)的自適應(yīng)布局
flex模型說(shuō)明
當(dāng)一個(gè)元素表現(xiàn)為flex框時(shí)冰沙,它會(huì)沿著兩個(gè)軸來(lái)進(jìn)行布局:
主軸:是沿著 flex 元素放置的方向延伸的軸(比如頁(yè)面上的橫向的行、縱向的列)执虹。該軸的開(kāi)始和結(jié)束被稱(chēng)為 main start 和 main end
交叉軸:是垂直于 flex 元素放置方向的軸拓挥。該軸的開(kāi)始和結(jié)束被稱(chēng)為 cross start 和 cross end
設(shè)置了 display: flex 的父元素(被稱(chēng)之為 flex 容器(flex container)。
在 flex 容器中表現(xiàn)為柔性的盒子的元素被稱(chēng)之為 flex 項(xiàng)(flex item)元素声畏。
在了解了以上內(nèi)容之后,即可開(kāi)始說(shuō)明flex布局的表現(xiàn)形式以及具體屬性
flex父容器屬性
要先使用flexbox模型姻成,首先必須先定義flex容器:
html:
<div class="flex-container">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
CSS:
.flex-container {
display: flex;
}
通過(guò)display屬性設(shè)置為flex插龄,父容器將變得可以隨瀏覽器窗口大小而伸縮
flex-direction:控制容器堆疊flex項(xiàng)目的方向
垂直從上到下
.flex-container {
display: flex;
flex-direction: column;
}
垂直從下到上
.flex-container {
display: flex;
flex-direction: column-reverse;
}
水平從左到右
.flex-container {
display: flex;
flex-direction: row;
}
水平從右到左
.flex-container {
display: flex;
flex-direction: row-reverse;
}
flex-wrap:控制容器內(nèi)flex項(xiàng)目換行,默認(rèn)值為“ nowrap ”
在必要的時(shí)候?qū)lex項(xiàng)目進(jìn)行換行處理
.flex-container {
display: flex;
flex-wrap: wrap;
}
此外該屬性取值為wrap-reverse時(shí)科展,父容器將對(duì)flex項(xiàng)目進(jìn)行倒序換行
flex-flow:簡(jiǎn)寫(xiě)屬性均牢,用來(lái)同時(shí)設(shè)置flex-direction和flex-wrap,比如:
.flex-container {
display: flex;
flex-flow: row wrap;
}
即相當(dāng)于設(shè)置了 flex-direction:row 才睹,flex-wrap:wrap
justify-content:用于定義flex項(xiàng)目在主軸上的對(duì)齊方式徘跪,以下說(shuō)明取值效果:
center:中心對(duì)齊
flex-start:在容器開(kāi)頭對(duì)齊
flex-end:在容器末尾對(duì)齊
space-around:保留flex項(xiàng)目間與父容器邊框之間的空隙
space-between:僅保留flex項(xiàng)目間的空隙
align-items:用于定義flex項(xiàng)目在交叉軸上的對(duì)齊方式
flex-start:交叉軸起點(diǎn)對(duì)齊
flex-end:交叉軸終點(diǎn)對(duì)齊
center:交叉軸中點(diǎn)對(duì)齊
stretch:若項(xiàng)目沒(méi)有設(shè)置高度或設(shè)置為auto,flex項(xiàng)目將占滿整個(gè)容器的高度(默認(rèn)值)
baseline:項(xiàng)目的第一行文字的基線對(duì)齊
align-content:定義多軸線對(duì)齊方式琅攘,如果項(xiàng)目只有一根軸線垮庐,則該屬性不起作用
flex-start:交叉軸起點(diǎn)對(duì)齊
flex-end:交叉軸終點(diǎn)對(duì)齊
center:交叉軸中點(diǎn)對(duì)齊
stretch:軸線上的項(xiàng)目占滿整個(gè)交叉軸
space-between:與交叉軸兩端對(duì)齊,軸線之間的間隔平均分布
space-around:每根軸線兩側(cè)的間隔都相等
完美居中
對(duì)flex父容器設(shè)置:
.flex-container {
display: flex;
height: 300px;
justify-content: center;
align-items: center;
}
結(jié)果如下:
子項(xiàng)目屬性
order:定義項(xiàng)目的排列順序坞琴,數(shù)值越小哨查,排列越靠前
<div class="flex-container">
<div style="order: 3">1</div>
<div style="order: 2">2</div>
<div style="order: 4">3</div>
<div style="order: 1">4</div>
</div>
flex-grow:定義項(xiàng)目的放大比例。默認(rèn)值為0剧辐,即如果存在是剩余空間寒亥,也不放大
<div class="flex-container">
<div style="flex-grow: 1">1</div>
<div style="flex-grow: 1">2</div>
<div style="flex-grow: 2">3</div>
</div>
如果所有項(xiàng)目的flex-grow屬性都為1,則它們將等分剩余空間(如果有的話)荧关。如果一個(gè)項(xiàng)目的flex-grow屬性為2溉奕,其他項(xiàng)目都為1,則前者占據(jù)的剩余空間將比其他項(xiàng)多一倍
flex-shrink:定義項(xiàng)目的縮小比例忍啤,默認(rèn)值為1加勤,即如果空間不足,項(xiàng)目縮小
<div class="flex-container">
<div>1</div>
<div>2</div>
<div style="flex-shrink: 0">3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
如果所有項(xiàng)目的flex-shrink屬性都為1,當(dāng)空間不足時(shí)胸竞,都將等比例縮小欺嗤。如果一個(gè)項(xiàng)目的flex-shrink屬性為0,其他項(xiàng)目都為1卫枝,則空間不足時(shí)煎饼,前者不縮小
flex-basis:屬性規(guī)定 flex 項(xiàng)目的初始長(zhǎng)度
<div class="flex-container">
<div>1</div>
<div>2</div>
<div style="flex-basis:200px">3</div>
<div>4</div>
</div>
第三個(gè)彈性項(xiàng)目的初始長(zhǎng)度為 200 像素
flex簡(jiǎn)寫(xiě)屬性
flex 屬性是 flex-grow、flex-shrink 和 flex-basis 屬性的簡(jiǎn)寫(xiě)屬性
比如:
<div class="flex-container">
<div>1</div>
<div>2</div>
<div style="flex: 0 0 200px">3</div>
<div>4</div>
</div>
使第三個(gè)彈性項(xiàng)目不可增長(zhǎng)(0)校赤,不可收縮(0)吆玖,且初始長(zhǎng)度為 200 像素
align-self
- align-self 屬性規(guī)定彈性容器內(nèi)所選項(xiàng)目的對(duì)齊方式
- align-self 屬性將覆蓋容器的 align-items 屬性所設(shè)置的默認(rèn)對(duì)齊方式
- 允許單個(gè)項(xiàng)目有與其他項(xiàng)目不一樣的對(duì)齊方式,可覆蓋align-item值马篮,默認(rèn)為auto沾乘,表示繼承父元素的align-item屬性,如果沒(méi)有父元素浑测,則等同于stretch
BFC
不要試圖去講解 BFC 的定義3嵴蟆!
如何說(shuō)明 BFC 迁央,舉例子V澜场!不要試圖去講定義岖圈!
具有 BFC 特性的元素可以看作是隔離了的獨(dú)立容器讹语,容器里面的元素不會(huì)在布局上影響到外面的元素,并且 BFC 具有普通容器所沒(méi)有的一些特性
通俗一點(diǎn)來(lái)講蜂科,可以把 BFC 理解為一個(gè)封閉的大箱子顽决,箱子內(nèi)部的元素?zé)o論如何翻江倒海,都不會(huì)影響到外部
如何觸發(fā)BFC
只要元素滿足下面任一條件即可觸發(fā) BFC 特性:
- body 根元素
- 浮動(dòng)元素:float 除 none 以外的值
- 絕對(duì)定位元素:position (absolute导匣、fixed)
- display 為 inline-block才菠、table-cells、flex
- overflow 除了 visible 以外的值 (hidden贡定、auto鸠儿、scroll)
具體應(yīng)用
避免外邊距折疊
同一個(gè) BFC 下外邊距會(huì)發(fā)生折疊,既然如此厕氨,把它們分別放到兩個(gè)BFC里就行了
html:
<div class="container">
<p></p>
</div>
<div class="container">
<p></p>
</div>
CSS:
.container {
overflow: hidden;
}
p {
width: 100px;
height: 100px;
background: lightblue;
margin: 100px;
}
這時(shí)进每,兩個(gè)盒子的邊距變成了200px;
BFC可以包含浮動(dòng)元素(清除浮動(dòng))
清除浮動(dòng)的手法之一:
<div style="border: 1px solid #000;overflow: hidden">
<div style="width: 100px;height: 100px;background: #eee;float: left;"></div>
</div>
BFC可以阻止元素被浮動(dòng)元素覆蓋
設(shè)置float的文字環(huán)繞效果:
<div style="height: 100px;width: 100px;float: left;background: lightblue">我是一個(gè)左浮動(dòng)的元素</div>
<div style="width: 200px; height: 200px;background: #eee">我是一個(gè)沒(méi)有設(shè)置浮動(dòng), 也沒(méi)有觸發(fā) BFC 元素, width: 200px; height:200px; background: #eee;</div>
這時(shí)候其實(shí)第二個(gè)元素有部分被浮動(dòng)元素所覆蓋命斧,(但是文本信息不會(huì)被浮動(dòng)元素所覆蓋) 如果想避免元素被覆蓋田晚,可觸第二個(gè)元素的 BFC 特性,在第二個(gè)元素中加入 overflow: hidden国葬,就會(huì)變成:
這個(gè)方法可以用來(lái)實(shí)現(xiàn)兩列自適應(yīng)布局贤徒,效果不錯(cuò)芹壕,這時(shí)候左邊的寬度固定,右邊的內(nèi)容自適應(yīng)寬度