文、菜鳥編
Flexbox盒子模型在CSS3時出現,只是當時並無太多的討論,近年因為行動裝置促成響應式布局的發展及在CSS3普及的狀況下,成了一個當紅的靈活盒子應用。就連Bootstrap 4 也使用了Flexbox的布局方式,所以搞懂這盒子模型已經是必然的,這一篇我們就來詳細介紹一下Flexbox的使用。
布局的模式:
開始說明之前,先來了解一下容器與元素,以下圖來說,標示數字1.2.3的Flex項目(Flex item),被外層的定義為Flex容器(Flex Container)給包覆著,意思就是說當要使用Flexbox前,需要訂定一個區塊(藍色),讓區塊內的元素(綠色)具有自適應的排序效果。
外層元素只要透過display:flex設置就可以開始使用Flexbox盒子模型,以下面例子來說,當把父級元素設定成flexbox後,容器內的子元素就成了flex項目。
HTML:
<div class="flex">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
CSS:
.flex{
width: 400px;
height: 400px;
display: flex;
border: 1px solid #000;
}
.flex div{
background-color: #66aeb4;
width: 100px;
height: 100px;
margin: 2%;
font-size: 30px;
color: #fff;
text-align: center;
line-height: 100px;
}
左圖為預設排列方式,右圖使用了Flexbox後的效果,就如同使用了float一樣。
要搞懂Flexbox的布局,首先要搞懂Flexbox中最重要的兩條線,「主軸線」與「交錯軸」。這兩條軸線關係到了Flex項目的排序方向,從下圖可以看到,預設值的主軸線(main axis)是由左至右的排列方式,交錯軸(cross axis)是由上至下的排列方式。
但可別用數學的角度來看待這兩條軸線,不是水平就是主軸線,垂直就是交錯軸,因為Flexbox屬一維布局,也就是說你可以隨意指定主軸的方向,當你定義主軸線為垂直方向,那「交錯軸」就會是水平方向,而排序的方向也會因屬性的定義而有所不同,這部分在後面的說明你就會有更深入的瞭解,接下來就分別來說明一下容器的屬性與flex項目的屬性。
容器的屬性:
屬性 |
說明 |
值 |
display |
決定布局方式 |
flex ; inline-flex |
flex-direction |
控制主軸線排列的方向 |
row ; row-reversecolumn ; column-reverse |
flex-warp |
決定是否要換行 |
nowrap ; wrap ; wrap-reverse |
flex-flow |
flex-direction和flex-wrap 組合簡寫屬性 |
|
justify-content |
flex項目與主軸線對齊的方式 |
flex-start ; flex-end ; center; space-between ; space-around |
align-items |
flex項目與交錯軸對齊的方式 |
flex-start ; flex-end ; center ; baseline ; stretch; |
align-content |
與align-items相似只是用於多行的狀況下 |
flex-start ; flex-end ; center ; stretch;space-between ; space-around |
► display:
可以用其他布局的方式來思考。
felx:相當於display: block,會換行
inline-flex:相當於display: inline-block,不換行
► flex-direction:
前面有提到,我們可以隨意的指定主軸線的方向,而flex-direction就是指定主軸線的排序方向,總共有四個設定值:
CSS:
.flex{
flex-direction: row /* row-reverse || column || column-reverse*/
}
row:由左至右的排列。
row-reverse:反向row排列方向,由右至左排列。
column:由上至下垂直排列。
column-reverse:反向column排列方向,由下至上排列。
► flex-wrap:
CSS:
.flex{
flex-wrap: nowrap /* wrap || wrap-reverse */
}
Flexbox中flex-wrap預設值為nowrap,容器內的flex項目會以單行(不換行)方式彈性撐滿容器,例如下圖添加了多個li後,寬度會自動調整塞滿整個容器。當設定了flex-wrap:wrap後,flex項目的寬度就不會變動,當總寬度加總大於容器時,就會換行。
flex-wrap換行方向為交叉軸的方向,預設值是由上而下排列,所以當設定成wrap-reverse除了換就會是由下至上換行。
► flex-flow:
CSS中有相當多屬性簡寫,例如background、font、border、padding、margin。flex-flow就是flex-direction與flex-wrap的簡寫,例如下圖指定「主軸線」為水平反向,所以排列就會由右至左,換行部分為「反向換行」則是由下往上。
如果沒有搞懂Flexbox中「主軸線」與「交錯軸」,就很容易在這邊搞不清楚排序的方向。所以再次提醒,千萬別用數學象限的角度來看待這兩條線。「主軸線」與「交錯軸」是可分別定義方位與排序的方向。
► justify-content:
CSS:
.flex{
justify-content: flex-start /*flex-end || center || space-around || space-between*/
}
justify-content會影響到容器內項目與容器「主軸線」的對齊方式,預設值是flex-strat,也是因為如此,在這篇文章一開始時,透過Flexbox就可以讓布局看起來像是使用float的效果。
( 下圖皆以預設值flex-direction: row排列 )
justify-content: flex-start:靠齊「主軸線」的「main start」排列。
justify-content: flex-end:靠齊「主軸線」的「main end」排列。
justify-content: center:對齊「主軸線」的中心位置排列。
justify-content: space-around:將容器的項目間距平均分布「主軸線」。
justify-content: space-between:容器內項目兩側靠齊容器,其餘平均分布。
► align-items:
CSS:
.flex{
align-items: flex-start /* flex-end || center || baseline || stretch */
}
justify-content影響了flex項目與「主軸線」的對齊,而align-items就是與「交錯軸」的對齊方式。
( 下圖皆以預設值flex-direction: row排列 )
align-items: flex-start:靠齊「交錯軸」的「cross start」排列。
align-items: flex-end:靠齊「交錯軸」的「cross end」排列。
align-items: center:對齊「交錯軸」的中心位置排列。
align-items: baseline:以容器內的flex項目的基線作為對齊標準。
align-items: stretch:將flex項目全部撐開與容器的高度相同,如果flex項目有設定高度,則會以設定的為主,不會撐開。
► align-content:
align-content與align-items相似,差別在於align-content是針對多行的排列,也就是當你設定flex-wrap為wrap或wrap-reverse時才有效。一樣也是針對「交錯軸」對齊方式。
( 下圖皆以預設值flex-direction: row ; flex-wrap: wrap排列 )
align-content: flex-start:靠齊「交錯軸」的「cross start」排列。
align- content: flex-end:靠齊「交錯軸」的「cross end」排列。
align- content: center:對齊「交錯軸」的中心位置排列。
align- content: space-around:平均分布。
align- content: space-between:容器內項目兩側靠齊容器,其餘平均分布。
align- content: stretch:將flex項目的高度撐開,如果flex項目有設定高度,則會以設定的為主,不會撐開。
提供align- content: stretch的設定:
CSS:
.flex-stretch > div{
width: auto;
height: auto;
padding: 40px
}
Flex項目的屬性:
屬性 |
說明 |
值 |
order |
重新定義flex項目的排列順序 |
|
align-self |
可個別設定單一元件「交錯軸」的值與對齊位置。 |
|
flex |
flex 是縮寫,依序包含三個屬性 flex-grow、flex-shrink 和 flex-basis,如果只設定一個則是 flex-grow。 |
flex-grow :預設值為0
|
► order:
透過order可以讓flex項目排序的方式更有彈性,以下圖來說,左方是未設定任何order時的排序,右圖則是使用了order,數字越小,排序越前面。
HTML:
<div class="flex">
<div class="order2">1</div>
<div class="order4">2</div>
<div class="order1">3</div>
<div class="order3">4</div>
<div class="order6">5</div>
<div class="order5">6</di>
</div>
► align-self:
在容器屬性設定中,都是針對容器與整體的flex項目,而align就是一個彈性的使用。例如下圖,我們在容器中設定align-items: flex-end,但我們將項目2的部分獨自設定了「align-self: center」,就會脫離整體的設定,與「交錯軸」的中心位置對齊。
► flex:
flex是整個Flexbox中的精華,也有點抽象不好理解,是一個縮寫屬性,依序包含三個屬性 flex-grow、flex-shrink 和 flex-basis,如果只設定一個則是 flex-grow。
首先我們用一張圖來做說明,設定了一個Flexbox容器寬度為250px,內部的item元素設定寬度為50px,撇開padding與margin的部分,我們將容器扣除掉3個flex item的總寬度150px,所得的100px我們這邊稱呼為「剩餘空間」。
flex-basis:
預設值為auto,當內部元素有設定寬度時,則會以我們設定的寬度為主。flex-basis決定了剩餘空間的大小。如果剩餘空間大於0,則瀏覽器就會依照flex-grow所設定的比例調整放大flex項目;相反的當剩餘空間小於0時,就會依照flex-shrink設定進行調整。
flex-grow:
flex-grow的設定值為無單位的數字,屬性決定了項目的放大比例,預設值為0,所以當我們在一開始設定flex項目的尺寸時,預設並不會自動放大。以下面來說,當我分別設定了3個flex-item的flex-grow的大小為1、2、3時,瀏覽器就會將剩餘空間依照比例來調整所有flex項目的寬度,也就是說item1放大「剩餘空間」的1/6大小,item2為2/6、item3為3/6。如果3個項目都設定都相同,則就會獲得3個相同寬度的項目,不管原本的寬度設定為何!
flex-shrink:
設定值一樣為無單位的數字,了解了flex-grow,要理解flex-shrink就會簡單。在容器寬度小於內部flex item總寬度時,會將flex item進行比例的寬度縮小,達成自適應的效果。以下面動畫來說,分別將3個內部item設定為0.5、0、1,其中item2不進行寬度調整。可以看到item3縮小的幅度也比item1來的顯著。
flex屬性預設為flex: 0 1 auto,不進行寬度放大的調整,以內部元素設定尺寸為主,但當外部容器無法容下內部元素總寬度時,就會進行比例的縮小,所以才有辦法自適應。Flex屬性也提供了兩個快速值,auto與none,代表意思為:
auto: 1 1 auto
none: 0 0 auto
Flexbox已逐漸成為主流,也相當好用,搞懂Flexbox後對於布局會相當方便,文章建議可以來回多看幾次,因為這些觀念都是前後應用與牽扯,重點是一定要實際操作才會真的理解。只要多看、多練習幾次,相信你就能搞定Flexbox,如果你覺得這篇文章很實用,也別忘了分享給你的親友們,相信對他們一定很有幫助!
► 推薦課程:跨平台商業網站設計
延伸閱讀
聯成電腦網頁設計教學:推薦給前端設計的10個Chrome外掛
官方網站:http://www.lccnet.com.tw
FB粉絲團:https://www.facebook.com/lccnetzone
菜鳥救星:https://www.facebook.com/greensn0w
留言列表