目前在不考慮IE以及低端安卓機(4.3-)的兼容下,已經能夠放心使用flex進行佈局了。什麼是flex佈局以及它的好處,這裏就再也不贅述。html
在這篇文章裏,想說說flex佈局的屬性語法及其細節。那麼網上也有很多flex佈局的教程,爲何又要再寫一篇?java
首先,flex佈局的迷之屬性們,若是隻知其一;不知其二,機械記憶的話,那不到半個月基本忘光光。先感覺一下這12個flex佈局屬性,是否是很「迷」人。css3
容器屬性git
元素屬性github
就連老外也都在twitter吐槽很差理解,可見仍是有必定的學習成本。web
而目前不少flex教程主要以列舉屬性爲主,缺少對比和理解性脈絡。markdown
所以,下面會經過我梳理的一個脈絡去理解flex佈局,包括不一樣屬性的異同以及一些容易形成誤解的細節點,完全弄懂flex佈局。dom
對於某個元素只要聲明瞭display: flex;
,那麼這個元素就成爲了彈性容器,具備flex彈性佈局的特性。
display:flex
設置爲另外一個彈性容器,造成嵌套關係。所以一個元素既能夠是彈性容器也能夠是彈性元素。彈性容器的兩根軸很是重要,全部屬性都是做用於軸的。下面從軸入手,將全部flex佈局屬性串起來理解。
flex佈局是一種一維佈局模型,一次只能處理一個維度(一行或者一列)上的元素佈局,做爲對比的是二維佈局CSS Grid Layout,能夠同時處理行和列上的佈局。
也就是說,flex佈局大部分的屬性都是做用於主軸的,在交叉軸上不少時候只能被動地變化。
咱們能夠在彈性容器上經過flex-direction
修改主軸的方向。若是主軸方向修改了,那麼:
flex-direction:row
flex-direction:column
flex-direction:row-reverse
flex-direction:column-reverse
彈性元素永遠沿主軸排列,那麼若是主軸排不下,該如何處理?
經過設置flex-wrap: nowrap | wrap | wrap-reverse
可以使得主軸上的元素不折行、折行、反向折行。
默認是nowrap
不折行,難道任由元素直接溢出容器嗎?固然不會,那麼這裏就涉及到元素的彈性伸縮應對,下面會講到。
wrap
折行,顧名思義就是另起一行,那麼折行以後行與行之間的間距(對齊)怎樣調整?這裏又涉及到交叉軸上的多行對齊。
wrap-reverse
反向折行,是從容器底部開始的折行,但每行元素之間的排列仍保留正向。
flex-flow = flex-drection + flex-wrap
flex-flow
至關於規定了flex佈局的「工做流(flow)」
flex-flow: row nowrap;
當flex-wrap: nowrap;
不折行時,容器寬度有剩餘/不夠分,彈性元素們該怎麼「彈性」地伸縮應對?
這裏針對上面兩種場景,引入兩個屬性(需應用在彈性元素上)
flex-shrink
:縮小比例(容器寬度<元素總寬度時如何收縮)flex-grow
:放大比例(容器寬度>元素總寬度時如何伸展)來看下如下場景,彈性容器#container
寬度是200px,一共有三個彈性元素,寬度分別是50px、100px、120px。在不折行的狀況下,此時容器寬度是明顯不夠分配的。
實際上,flex-shrink
默認爲1,也就是當不夠分配時,元素都將等比例縮小,佔滿整個寬度,以下圖。
#container {
display: flex;
flex-wrap: nowrap;
}
真的是等比縮小(每一個元素各減去70/3的寬度)嗎?這裏稍微深究一下它的收縮計算方法。
先拋結論:flex-shrink: 1
並不是嚴格等比縮小,它還會考慮彈性元素自己的大小。
-70px
1*50 + 1*100 + 1*120 = 270
(1爲各元素flex-shrink的值)1*50/270
1*50/270 * (-70)
50px + (1*50/270 *(-70)) = 37.03px
加入彈性元素自己大小做爲計算方法的考慮因素,主要是爲了不將一些自己寬度較小的元素在收縮以後寬度變爲0的狀況出現。
一樣,彈性容器#container
寬度是200px,但此時只有兩個彈性元素,寬度分別是50px、100px。此時容器寬度是有剩餘的。
那麼剩餘的寬度該怎樣分配?而flex-grow
則決定了要不要分配以及各個分配多少。
(1)在flex佈局中,容器剩餘寬度默認是不進行分配的,也就是全部彈性元素的flex-grow
都爲0。
(2)經過指定flex-grow
爲大於零的值,實現容器剩餘寬度的分配比例設置。
放大的計算方法並無與縮小同樣,將元素大小歸入考慮。
僅僅按flex-grow
聲明的份數算出每一個需分配多少,疊加到原來的尺寸上。
50px
50px / (3+2) = 10px
50px + 3 * 10 = 80px
下圖中,彈性容器的寬度正好等於元素寬度總和,無多餘寬度,此時不管flex-grow
是什麼值都不會生效。
同理,對於flex-shrink
,在容器寬度有剩餘時也是不會生效的。所以這兩個屬性是針對兩種不一樣場景的互斥屬性。
在進行彈性處理之餘,其實有些場景咱們更但願元素尺寸固定,不須要進行彈性調整。設置元素尺寸除了width和height之外,flex還提供了一個flex-basis
屬性。
flex-basis
設置的是元素在主軸上的初始尺寸,所謂的初始尺寸就是元素在flex-grow
和flex-shrink
生效前的尺寸。
首先以width爲例進行比較。看下下面的例子。#container {display:flex;}
。
<div id="container">
<div>11111</div>
<div>22222</div> </div>
—— 數值相同時二者等效
—— 同時設置,flex-basis優先級高
flex-basis爲auto時,如設置了width則元素尺寸由width決定;沒有設置則由內容決定
這個屬性應該是最容易迷糊的一個,下面揭開它的真面目。
flex = flex-grow + flex-shrink + flex-basis
複合屬性,前面說的三個屬性的簡寫。
flex: 1
= flex: 1 1 0%
flex: 2
= flex: 2 1 0%
flex: auto
= flex: 1 1 auto;
flex: none
= flex: 0 0 auto;
// 經常使用於固定尺寸 不伸縮其實能夠歸結於flex-basis:0
和flex-basis:auto
的區別。
flex-basis
是指定初始尺寸,當設置爲0時(絕對彈性元素),此時至關於告訴flex-grow
和flex-shrink
在伸縮的時候不須要考慮個人尺寸;相反當設置爲auto
時(相對彈性元素),此時則須要在伸縮時將元素尺寸歸入考慮。
所以從下圖(轉自W3C)能夠看到絕對彈性元素若是flex-grow
值是同樣的話,那麼他們的尺寸必定是同樣的。
前面講完了元素大小關係以後,下面是另一個重要議題——如何對齊。能夠發現上面的全部屬性都是圍繞主軸進行設置的,但在對齊方面則不得不加入做用於交叉軸上。須要注意的是這些對齊屬性都是做用於容器上。
justify-content
主軸上比較好理解,重點是交叉軸上。由於交叉軸上存在單行和多行兩種狀況。
align-items
默認值是stretch
,當元素沒有設置具體尺寸時會將容器在交叉軸方向撐滿。
當align-items
不爲stretch
時,此時除了對齊方式會改變以外,元素在交叉軸方向上的尺寸將由內容或自身尺寸(寬高)決定。
注意,交叉軸不必定是從上往下,這點再次強調也不爲過。
還記得能夠經過flex-wrap: wrap
使得元素在一行放不下時進行換行。在這種場景下就會在交叉軸上出現多行,多行狀況下,flex佈局提供了align-content
屬性設置對齊。
align-content
與align-items
比較相似,同時也比較容易迷糊。下面會將二者對比着來看它們的異同。
首先明確一點:align-content
只對多行元素有效,會以多行做爲總體進行對齊,容器必須開啓換行。
align-content: stretch | flex-start | flex-end | center | space-between | space-around
align-items: stretch | flex-start | flex-end | center | baseline
在屬性值上,align-content
比align-items
多了兩個值:space-between
和space-around
。
與align-items
同樣,align-content:
默認值也是stretch
。二者同時都爲stretch
時,毫無懸念全部元素都是撐滿交叉軸。
#container { align-items: stretch; align-content: stretch; }
當咱們將align-items改成flex-start
或者給彈性元素設置一個具體高度,此時效果是行與行之間造成了間距。
#container { align-items: flex-start; align-content: stretch; }
/或者/
#container {
align-content: stretch;
}
#container > div {
height: 30px;
}
爲何?由於align-content
會以整行爲單位,此時會將整行進行拉伸佔滿交叉軸;而align-items
設置了高度或者頂對齊,在不能用高度進行拉伸的狀況下,選擇了用間距。
嘗試把align-content
設置爲頂對齊,此時以行爲單位,總體高度經過內容撐開。
而align-items
僅僅管一行,所以在只有第一個元素設置了高度的狀況下,第一行的其餘元素遵循align-items: stretch
也被拉伸到了50px。而第二行則保持高度不變。
#container {
align-items: stretch;
align-content: flex-start;
}
#container > div:first-child {
height: 50px;
}
二者的區別仍是不明顯?來看下面這個例子。
這裏僅對第二個元素的高度進行設置,其餘元素高度則仍保持內容撐開。
以第一個圖爲例,會發現align-content
會將全部行進行頂對齊,而後第一行因爲第二個元素設置了較高的高度,所以體現出了底對齊。
二者差別總結:
除了在容器上設置交叉軸對齊,還能夠經過align-self
單獨對某個元素設置交叉軸對齊方式。
align-items
相同align-items
屬性auto
,表示繼承父元素的align-items
屬性#container {
display: flex;
align-items: flex-start;
}
#container > div:first-child {
align-self: stretch;
}
#container > div:nth-child(3) {
align-self: center;
}
#container > div:nth-child(4) {
align-self: flex-end;
}
#container > div:first-child {
order: 2;
}
#container > div:nth-child(2) {
order: 4;
}
#container > div:nth-child(3) {
order: 1;
}
#container > div:nth-child(4) {
order: 3;
}
order:可設置元素之間的排列順序
參考阮老師博文中的骰子練習,我作了張圖,你們不妨能夠各自實現下,理解以後應該可以比較輕鬆地寫出來。codepen
深刻理解css3中的flex-grow、flex-shrink、flex-basis
相關閱讀
bitset用法小結
Numpy基礎知識點彙總
【每日課程推薦】機器學習實戰!快速入門在線廣告業務及CTR相應知識
此文轉至https://www.cnblogs.com/qcloud1001/p/9848619.html點擊閱讀原文