1. Flexible Box 是什么
??布局的傳統(tǒng)解決方案熔脂,基于盒狀模型佩研,依賴 display
屬性 + position
屬性 + float
屬性。它對(duì)于那些特殊布局非常不方便霞揉,比如旬薯,垂直居中就不容易實(shí)現(xiàn)。所以在2009年适秩,w3c提出了一種可以簡(jiǎn)潔绊序、快速?gòu)椥圆季值膶傩裕饕枷胧墙o予容器控制內(nèi)部元素高度和寬度的能力秽荞,這就是今天要說(shuō)的Flexible Box骤公,彈性布局。
??由于瀏覽器的限制蚂会,在寫代碼之前推薦查詢一下兼容模式淋样,了解下目前flex的支持程度,我們可以通過(guò)CanIuse這個(gè)網(wǎng)站來(lái)進(jìn)行查詢胁住,如下圖,可以看到刊咳,除了對(duì)于IE支持一般之外彪见,其他瀏覽器大多沒(méi)啥毛病,但為了以防萬(wàn)一娱挨,在寫代碼的時(shí)候還是加上-webkit-
這一前綴以防萬(wàn)一余指。
.box{
display: -webkit-flex; /* Safari */
display: flex;
}
重點(diǎn)!flex一共有兩根軸:main axis(主軸)和cross axis(交叉軸)跷坝,大家一般認(rèn)為主軸就是水平酵镜,交叉軸就是垂直的。但是柴钻!這是錯(cuò)誤的淮韭!請(qǐng)與水平垂直這兩個(gè)方位的概念區(qū)分開,這是一個(gè)方位贴届,如果說(shuō)當(dāng)年定義的時(shí)侯為什么不命名為vertical&horizon靠粪??原因就是main axis沒(méi)有一個(gè)固定的方位毫蚓,所以請(qǐng)不要再通過(guò)水平垂直的方位來(lái)理解了占键。那么主軸是怎么區(qū)分的呢?其實(shí)很簡(jiǎn)單按照當(dāng)前flex的方向元潘,是水平排列還是垂直排列畔乙。如果是水平排列(row),主軸就是水平的翩概,交叉軸就是垂直的牲距,反之亦然袖订。這是一個(gè)很重要的概念。
<font color='#E64A19'>注意嗅虏,設(shè)為 Flex 布局以后洛姑,子元素的float、clear和vertical-align屬性將失效皮服。</font>
2. 屬性描述
2.1.父容器的屬性
flex-direction :該元素決定主軸的方向(即子元素的排列方向) 默認(rèn)值 :row 適用于 :flex 容器
屬性 | 描述 |
---|---|
row | 主軸為水平方向楞艾,起點(diǎn)在左端。 |
row-reverse | 主軸為水平方向龄广,起點(diǎn)在右端硫眯。 |
column | 主軸為垂直方向,起點(diǎn)在上沿择同。 |
column-reverse | 主軸為垂直方向两入,起點(diǎn)在下沿。 |
flex-wrap :設(shè)置或檢索伸縮盒對(duì)象的子元素超出父容器時(shí)是否換行 默認(rèn)值 :nowrap 適用于 :flex 容器
屬性 | 描述 |
---|---|
nowrap | 不換行(默認(rèn)) |
wrap | 換行敲才,第一行在上方 |
wrap-reverse | 換行裹纳,第一行在下方 |
PS: flex-flow
屬性是 flex-direction
屬性和 flex-wrap
屬性的簡(jiǎn)寫形式,默認(rèn)值為 row nowrap
.box {
flex-flow: flex-direction flex-wrap|initial|inherit;
}
justify-content :定義了子元素在主軸上的對(duì)齊方式紧武。 默認(rèn)值 :flex-start 適用于 :flex 容器
屬性 | 描述 |
---|---|
flex-start | 左對(duì)齊 |
flex-end | 右對(duì)齊 |
center | 居中 |
space-between | 兩端對(duì)齊剃氧,項(xiàng)目之間的間隔都相等 |
space-around | 每個(gè)項(xiàng)目?jī)蓚?cè)的間隔相等。所以阻星,項(xiàng)目之間的間隔比項(xiàng)目與邊框的間隔大一倍 |
align-items :定義了子元素在交叉軸上的對(duì)齊方式 默認(rèn)值 :stretch 適用于 :flex 容器
屬性 | 描述 |
---|---|
flex-start | 交叉軸的起點(diǎn)對(duì)齊 |
flex-end | 交叉軸的終點(diǎn)對(duì)齊 |
center | 交叉軸的中點(diǎn)對(duì)齊 |
baseline | 子元素第一行文字的基線對(duì)齊,如果子標(biāo)簽內(nèi)沒(méi)有內(nèi)容朋鞍,將按照每個(gè) div 的底部對(duì)齊 |
stretch | 如果項(xiàng)目未設(shè)置高度或設(shè)為auto,將占滿整個(gè)容器的高度 |
align-items: stretch 時(shí)每個(gè)子元素的 height 必須為 auto 否則 height 屬性會(huì)覆蓋 stretch 的效果
如果 div 內(nèi)沒(méi)有內(nèi)容妥箕,或者子標(biāo)簽內(nèi)沒(méi)有內(nèi)容滥酥,將按照每個(gè) div 的底部對(duì)齊
align-content :定義多根軸線的對(duì)齊方式,如果子元素只有一根軸線畦幢,該屬性不起作用 默認(rèn)值 :stretch 適用于 :多行的彈性盒模型容器
屬性 | 描述 |
---|---|
flex-start | 與交叉軸的起點(diǎn)對(duì)齊 |
flex-end | 與交叉軸的終點(diǎn)對(duì)齊 |
center | 與交叉軸的中點(diǎn)對(duì)齊 |
space-between | 與交叉軸兩端對(duì)齊坎吻,軸線之間的間隔平均分布 |
space-around | 每根軸線兩側(cè)的間隔都相等。所以呛讲,軸線之間的間隔比軸線與邊框的間隔大一倍 |
stretch | 軸線占滿整個(gè)交叉軸 |
PS: 在上面的例子 flex-wrap 需設(shè)為 wrap, 且數(shù)量超出一行, 父容器的高度相對(duì)于子容器有多余禾怠,才能看到效果
2.2 子元素的屬性
order :定義子元素的排列順序,數(shù)值越小贝搁,排列越靠前 默認(rèn)值:0 適用于:flex子項(xiàng)和flex容器中的絕對(duì)定位子元素
PS:用整數(shù)值來(lái)定義排列順序吗氏,數(shù)值小的排在前面。元素的值可以為負(fù)值
flex-grow :定義子元素的放大比例 默認(rèn)值 :0 適用于 :flex子項(xiàng)
<ul class="flex">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
.flex{display:flex;width:600px;margin:0;padding:0;list-style:none;}
.flex li {text-align:center;height:100px;}
.flex li:nth-child(1){width:200px;background-color:green;}
.flex li:nth-child(2){flex-grow:1;width:50px;background-color:yellow;}
.flex li:nth-child(3){flex-grow:3;width:50px;background-color:red;}
flex-grow的默認(rèn)值為0雷逆,如果沒(méi)有顯示定義該屬性弦讽,是不會(huì)擁有分配剩余空間權(quán)利的。
本例中b,c兩項(xiàng)都顯式的定義了flex-grow,flex容器的剩余空間分成了4份往产,其中b占1份被碗,c占3分,即1:3
flex容器的剩余空間長(zhǎng)度為:600-200-50-50=300px仿村,所以最終a,b,c的長(zhǎng)度分別為:
a: 50+(300/4)=200px
b: 50+(300/4*1)=125px
c: 50+(300/4*3)=275px
flex-shrink :定義子元素的收縮比例(與flex-grow相反) 默認(rèn)值 :1 適用于 :flex子項(xiàng)
<ul class="flex">
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
.flex{display:-webkit-flex;display:flex;width:400px;margin:0;padding:0;list-style:none;}
.flex li{width:200px;}
.flex li:nth-child(1){background:#888;}
.flex li:nth-child(2){background:#ccc;}
.flex li:nth-child(3){-webkit-flex-shrink:3;flex-shrink:3;background:#aaa;}
flex-shrink的默認(rèn)值為1锐朴,如果沒(méi)有顯示定義該屬性呵晚,將會(huì)自動(dòng)按照默認(rèn)值1在所有因子相加之后計(jì)算比率來(lái)進(jìn)行空間收縮眉枕。
本例中c顯式的定義了flex-shrink,a,b沒(méi)有顯式定義胆筒,但將根據(jù)默認(rèn)值1來(lái)計(jì)算畏鼓,可以看到總共將剩余空間分成了5份酱酬,其中a占1份,b占1份云矫,c占3分膳沽,即1:1:3
我們可以看到父容器定義為400px,子項(xiàng)被定義為200px让禀,相加之后即為600px挑社,超出父容器200px。那么這么超出的200px需要被a,b,c消化
通過(guò)收縮因子堆缘,所以加權(quán)綜合可得200*1+200*1+200*3=1000px滔灶;
于是我們可以計(jì)算a,b,c將被移除的溢出量是多少:
a被移除溢出量:(200*1/1000)*200,即約等于40px
b被移除溢出量:(200*1/1000)*200吼肥,即約等于40px
c被移除溢出量:(200*3/1000)*200,即約等于120px
最后a,b,c的實(shí)際寬度分別為:200-40=160px, 200-40=160px, 200-120=80px
PS:如果所有項(xiàng)目的 flex-shrink 屬性都為 1麻车,當(dāng)空間不足時(shí)缀皱,都將等比例縮小。如果一個(gè)項(xiàng)目的 flex-shrink 屬性為0动猬,其他項(xiàng)目都為 1啤斗,則空間不足時(shí),前者不縮小赁咙。負(fù)值對(duì)該屬性無(wú)效钮莲。
flex-basis :設(shè)置或檢索彈性盒伸縮基準(zhǔn)值 默認(rèn)值 :auto 適用于 :flex子項(xiàng)
flex-basis 控制元素的默認(rèn)尺寸,然后再由其他 Flexbox 屬性控制彼水,可以覆蓋 width 屬性
flex-basis 可以和 width 屬性互換
PS:flex-basis 是通過(guò)主軸 (main axis) 來(lái)影響元素尺寸的
align-self:允許單個(gè)子元素有與其他項(xiàng)目不一樣的對(duì)齊方式崔拥,可覆蓋align-items屬性 默認(rèn)值 :auto 適用于 :flex子項(xiàng)
屬性 | 描述 |
---|---|
auto | 繼承父元素的"align-items"值,如果其沒(méi)有父元素凤覆,等同于"stretch" |
flex-start | 交叉軸的起點(diǎn)對(duì)齊 |
flex-end | 交叉軸的終點(diǎn)對(duì)齊 |
center | 交叉軸的中點(diǎn)對(duì)齊 |
baseline | 第一行文字的基線對(duì)齊 |
stretch | 如果項(xiàng)目未設(shè)置高度或設(shè)為auto链瓦,將占滿整個(gè)容器的高度 |
父元素: align-items:flex-end
a: align-self: flex-end
b: align-self: center
c: align-self: flex-start
d: align-self: baseline; padding: 20px 10px
e: align-self: baseline
f: align-self: stretch
g: align-self: auto