CSS 彈性布局Flex詳細(xì)講解(Flex 屬性詳解、場(chǎng)景分析)

前言
我們知道,網(wǎng)頁(yè)展示就好比一個(gè)個(gè)盒子堆疊在一起,通過(guò)調(diào)整盒子的大小、位置、樣式等,形成了各式各樣的頁(yè)面。當(dāng)我們?cè)陂_(kāi)發(fā)一個(gè)頁(yè)面的時(shí)候,我們常規(guī)的做法可能是:搭建框架、劃分區(qū)域、定制排版、調(diào)整位置、嵌入內(nèi)容、微調(diào)與增添樣式。
布局排版是頁(yè)面基礎(chǔ)且關(guān)鍵的一環(huán)。其中,常用的自適應(yīng)布局技術(shù):Flex布局。
Flex 布局是什么?
Flex 簡(jiǎn)介
Flex 是 Flexible Box 的縮寫,意為"彈性布局",用來(lái)為盒狀模型提供最大的靈活性。
任何一個(gè)容器都可以指定為 Flex 布局。
.box { display: flex; }
行內(nèi)元素也可以使用 Flex 布局。
.box { display: inline-flex; }
Webkit 內(nèi)核的瀏覽器,必須加上-webkit
前綴。
.box { display: -webkit-flex; /* Safari */ display: flex; }
采用 Flex 布局的元素,稱為 Flex 容器(flex container),簡(jiǎn)稱"容器"。它的所有子元素自動(dòng)成為容器成員,稱為 Flex 項(xiàng)目(flex item),簡(jiǎn)稱"項(xiàng)目"。
Flex 容器屬性
- flex-direction
- flex-wrap
- flex-flow
- justify-content
- align-items
- align-content
接下來(lái),咱們通過(guò)具體實(shí)例介紹Flex屬性的使用與其在布局上達(dá)成的效果。
Flex 基本使用
場(chǎng)景一
整個(gè)頁(yè)面分為兩大部分,我們希望左邊部分作為菜單欄,寬度固定;右邊部分作為內(nèi)容展示區(qū),寬度自適應(yīng)且占滿剩余部分。
類似如下布局
常規(guī)方式:浮動(dòng)(float)
首先,將框架搭起來(lái)
<div id="app"> <div id="nav"> <div class="main-content"> <div class="left-content">Left</div> <div class="right-content">Right</div> </div> </div> </div>
為了方便查看效果,給每個(gè)盒子設(shè)置大小與添加背景色
<style> .main-content { width: 100%; height:100%; background: #72f884; } .left-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(238, 119, 34); } .right-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(68, 133, 255); } </style>
初始頁(yè)面展示效果
現(xiàn)在,使用浮動(dòng)(float),使左邊跟右邊并列布局
<style> .main-content { width: 100%; height:100%; background: #72f884; } .left-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(238, 119, 34); /* 使用浮動(dòng)完成左右并列布局 */ float: left; } .right-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(68, 133, 255); /* 使用浮動(dòng)完成左右并列布局 */ float: left; } </style>
頁(yè)面展示效果
此時(shí),再將右邊的寬度通過(guò) calc() 方法計(jì)算,實(shí)現(xiàn)右邊自適應(yīng)
<style> .right-content { box-sizing: border-box; /* width: 200px; */ height: 200px; background: rgb(68, 133, 255); /* 使用浮動(dòng)完成左右并列布局 */ float: left; /* 使用calc(),右邊寬度 = 總寬度 - 左邊菜單欄寬度 */ width: calc(100% - 200px); } </style>
縮小窗口,查看效果
此時(shí),實(shí)現(xiàn)了場(chǎng)景一的需求,效果看起來(lái)也還OK。但是有個(gè)問(wèn)題,現(xiàn)在的這個(gè)布局使用的是浮動(dòng),即代表著這兩個(gè)塊脫離了文檔流,如果頁(yè)面有其他布局區(qū)域,如頭部導(dǎo)航欄、底部關(guān)于欄、甚至是其他主內(nèi)容區(qū),這時(shí)候我們可能就需要花點(diǎn)時(shí)間去清除浮動(dòng)帶來(lái)的影響,或者是增加更多的浮動(dòng)來(lái)完成其他區(qū)域的布局。
那么有沒(méi)有一種布局是既可以不使用浮動(dòng)(或者說(shuō)是不脫離文檔流),又能實(shí)現(xiàn)上面的布局呢?答案是肯定的,可以使用Flex(彈性布局),且寫起來(lái)也更簡(jiǎn)便。
現(xiàn)在,我們將浮動(dòng)樣式去掉,在包含左右兩個(gè)盒子的父盒子加上 display:flex,表示使用彈性布局
<style> .main-content { width: 100%; height:100%; background: #72f884; /* 使用flex彈性布局 */ display: flex; } .left-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(238, 119, 34); } .right-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(68, 133, 255); } </style>
此時(shí)查看頁(yè)面效果
實(shí)現(xiàn)右邊部分自適應(yīng)只需要為右邊添加樣式 flex:1 即可
.right-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(68, 133, 255); /* 表示該盒子自動(dòng)占滿剩余空間(往下展開(kāi)) */ flex: 1; }
此時(shí)左右兩個(gè)盒子并列布局,且右邊自適應(yīng),why?以下詳細(xì)展開(kāi)。
flex-direction
flex-direction
屬性決定主軸的方向,即項(xiàng)目(或者說(shuō)是子盒子)的排列方向。
它可能有4個(gè)值。
row
(默認(rèn)值):主軸為水平方向,起點(diǎn)在左端。row-reverse
:主軸為水平方向,起點(diǎn)在右端。column
:主軸為垂直方向,起點(diǎn)在上沿。column-reverse
:主軸為垂直方向,起點(diǎn)在下沿。
布局圖示
上面例子不設(shè)置該屬性,因此為默認(rèn)值(row),即主軸水平、從左到右排列。
場(chǎng)景二
整個(gè)頁(yè)面分為多個(gè)部分,我們希望這些部分是并列布局,且寬度自適應(yīng)。
頁(yè)面布局如下(以三個(gè)部分舉例,若更多部分做法一致)
<div id="app"> <div id="nav"> <div class="main-content"> <div class="left-content">Left</div> <div class="middle-content">Middle</div> <div class="right-content">Right</div> </div> </div> </div>
初始樣式(同樣,父盒子使用flex布局)
<style> .main-content { width: 100%; height:100%; background: #72f884; /* 使用flex彈性布局 */ display: flex; } .left-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(238, 119, 34); } .middle-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(173, 40, 250); } .right-content { box-sizing: border-box; width: 200px; height: 200px; background: rgb(68, 133, 255); } </style>
初始頁(yè)面效果
現(xiàn)在,我們?nèi)齻€(gè)子盒子的寬度是固定的,因此實(shí)現(xiàn)不了自適應(yīng),我們可以使用 %(百分比)方式設(shè)置各個(gè)子盒子相對(duì)于父盒子所占的百分比
<style> .left-content { box-sizing: border-box; /* 寬度使用 % ,實(shí)現(xiàn)自適應(yīng) */ width: 30%; height: 200px; background: rgb(238, 119, 34); } .middle-content { box-sizing: border-box; /* 寬度使用 % ,實(shí)現(xiàn)自適應(yīng) */ width: 40%; height: 200px; background: rgb(173, 40, 250); } .right-content { box-sizing: border-box; /* 寬度使用 % ,實(shí)現(xiàn)自適應(yīng) */ width: 30%; height: 200px; background: rgb(68, 133, 255); } </style>
頁(yè)面展示效果
縮小查看頁(yè)面展示效果
注意觀察,此時(shí)三個(gè)子盒子的寬度總和等于父盒子的寬度,即30% + 40% + 30% = 100%。
如果三個(gè)盒子的寬度占比總和小于100%,即都為30%,頁(yè)面效果如下
此時(shí)頁(yè)面會(huì)多出空的部分,我們可以將這部分利用起來(lái)。
justify-content
該屬性定義了項(xiàng)目在主軸上的對(duì)齊方式。
它可能取5個(gè)值,具體對(duì)齊方式與軸的方向有關(guān)。下面假設(shè)主軸為從左到右。
此時(shí)主軸(flex-direction
)為默認(rèn)的row,即水平方向,從左到右。
flex-start
(默認(rèn)值):左對(duì)齊(即上面頁(yè)面展示效果)flex-end
:右對(duì)齊center
: 居中space-between
:兩端對(duì)齊,項(xiàng)目之間的間隔都相等。space-around
:每個(gè)項(xiàng)目?jī)蓚?cè)的間隔相等。所以,項(xiàng)目之間的間隔比項(xiàng)目與邊框的間隔大一倍。
接下來(lái)我們一一展示屬性達(dá)成的效果
flex-start
如上圖
flex-end
center
space-between(注意空白部分分配情況)
space-around(注意空白部分分配情況)
以上就是justify-content不同取值的布局效果,最后兩個(gè)取值就是如何分配剩余的空白部分。
還有一個(gè)與justify-content相似的屬性是align-items。
align-items
該屬性定義項(xiàng)目在交叉軸上如何對(duì)齊。(如果主軸為水平,那么交叉軸就是垂直)
它可能取5個(gè)值。具體的對(duì)齊方式與交叉軸的方向有關(guān),下面假設(shè)交叉軸從上到下。
flex-start
:交叉軸的起點(diǎn)對(duì)齊。flex-end
:交叉軸的終點(diǎn)對(duì)齊。center
:交叉軸的中點(diǎn)對(duì)齊。baseline
: 項(xiàng)目的第一行文字的基線對(duì)齊。stretch
(默認(rèn)值):如果項(xiàng)目未設(shè)置高度或設(shè)為auto,將占滿整個(gè)容器的高度。
flex-start、flex-end、center與
justify-content中展示效果類似,只是一個(gè)是水平方向一個(gè)是垂直方向。各屬性布局效果如下:
回到場(chǎng)景二,如果三個(gè)盒子的寬度占比總和大于100%,頁(yè)面效果又是怎樣的?
<style> .left-content { box-sizing: border-box; /* 寬度使用 % ,實(shí)現(xiàn)自適應(yīng) */ width: 40%; height: 200px; background: rgb(238, 119, 34); } .middle-content { box-sizing: border-box; /* 寬度使用 % ,實(shí)現(xiàn)自適應(yīng) */ width: 40%; height: 200px; background: rgb(173, 40, 250); } .right-content { box-sizing: border-box; /* 寬度使用 % ,實(shí)現(xiàn)自適應(yīng) */ width: 30%; height: 200px; background: rgb(68, 133, 255); } </style>
現(xiàn)在,調(diào)整父盒子的寬度為1000px
如果子盒子為40%,寬度理應(yīng)為400px,但是有下圖可知,寬度小于400px了
此時(shí)寬度被壓縮了,其實(shí)此時(shí)是按照比例縮小了,由之前的按照100份來(lái)占比,現(xiàn)在相當(dāng)于按照1100份來(lái)占比(40% 40% 30%),此時(shí)的寬度就是1000 * (40/110) 大概就是363.64。
那如果我們就想寬度是那么多,不能有誤差,該怎么辦呢?
flex-wrap
默認(rèn)情況下,項(xiàng)目都排在一條線(又稱"軸線")上。flex-wrap
屬性定義,如果一條軸線排不下,如何換行。在寬度總和超出父盒子的寬度時(shí),希望保持每個(gè)子盒子的準(zhǔn)確寬度,那就只能分行排列(一行排列會(huì)被按比例壓縮,如上圖)。
它可能有3個(gè)值。
nowrap
(默認(rèn)值):不換行。wrap
:換行。wrap-reverse
:換行,第一行在下方。
分別對(duì)應(yīng)以下圖
此時(shí)設(shè)置flex-wrap:wrap,允許換行
.main-content { width: 100%; height:100%; background: #72f884; /* 使用flex彈性布局 */ display: flex; /* 使用flex-wrap,wrap為允許換行,nowrap為不允許換行 */ flex-wrap: wrap; }
再次查看頁(yè)面展示效果
換行之后子盒子的寬度正常,不被壓縮了。
場(chǎng)景三
現(xiàn)在希望將場(chǎng)景一與場(chǎng)景二結(jié)合,即在一個(gè)頁(yè)面中分為左右兩大部分,左邊部分是菜單欄(寬度固定200px);右邊部分是內(nèi)容展示區(qū),寬度自適應(yīng)且占滿,內(nèi)容展示區(qū)里面又分為三部分,每個(gè)部分寬度為該區(qū)域的30%。
1、搭建左右兩大部分
html
<div id="app"> <div id="nav"> <div class="main-content"> <div class="left-content">Left</div> <div class="right-content">Right</div> </div> </div> </div>
css
<style> .main-content { width: 100%; height:100%; background: #72f884; /* 使用flex彈性布局 */ display: flex; } .left-content { box-sizing: border-box; width: 200px; height: 100%; background: rgb(238, 119, 34); } .right-content { box-sizing: border-box; flex: 1; height: 100%; background: rgb(68, 133, 255); } </style>
頁(yè)面展示效果
2、布局右邊部分
里面分為三部分(用一個(gè)新的div包裹,結(jié)構(gòu)分明)
html
<div id="app"> <div id="nav"> <div class="main-content"> <div class="left-content">Left</div> <div class="right-content"> Right <div class="right-content-item"> <div class="right-content-item-list">part1</div> <div class="right-content-item-list">part2</div> <div class="right-content-item-list">part3</div> </div> </div> </div> </div> </div>
css
.right-content-item { width: 100%; height: 100%; } .right-content-item-list { width: 30%; height: 30%; background: rgb(242, 245, 37); }
頁(yè)面展示效果
此時(shí)右邊部分(新增的div)內(nèi)容區(qū)使用flex布局
.right-content-item { width: 100%; height: 100%; display: flex; }
頁(yè)面展示效果
此時(shí)使用justify-content屬性
.right-content-item { width: 100%; height: 100%; display: flex; justify-content: space-around; }
頁(yè)面展示效果
縮小窗口,查看頁(yè)面展示效果
無(wú)論窗口放大或縮小,都能實(shí)現(xiàn)自適應(yīng)。在該例子中,可以知道,flex布局里面的子盒子依然可以使用flex布局,即可以嵌套使用,可用該特點(diǎn)結(jié)合flex中的各個(gè)屬性實(shí)現(xiàn)多種自適應(yīng)布局場(chǎng)景。
最后flex-flow跟align-content不展開(kāi),可以自行了解。
參考文章:
Flex 布局教程:語(yǔ)法篇
https://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
到此這篇關(guān)于Css 彈性布局Flex詳細(xì)介紹(Flex 屬性詳解、場(chǎng)景分析)的文章就介紹到這了,更多相關(guān)css 彈性布局Flex內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
CSS彈性布局FLEX,媒體查詢及移動(dòng)端點(diǎn)擊事件的實(shí)現(xiàn)
這篇文章主要介紹了CSS彈性布局FLEX,媒體查詢及移動(dòng)端點(diǎn)擊事件的實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-24- 這篇文章主要介紹了css flex 彈性布局詳解的相關(guān)資料,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-02
- 下面小編就為大家?guī)?lái)一篇CSS彈性盒模型flex在布局中的應(yīng)用詳解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-05-24