flex彈性盒子模型是新一代的佈局模式,在大部分狀況下能夠徹底替代以前的display屬性 + position屬性 + float屬性的佈局方式,設計友好,目前兼容性已經很好了,不少主流網站都已經開始採用。本文總結一下flex的設計思想和語法,以及在實際的佈局應用中爲咱們帶來了哪些便利。css
咱們能夠仔細想一下咱們以前佈局的難點和麻煩的地方都有什麼,我總結了幾個:html
其實float
、position
、line-height
、vertical-align
設計之初並非爲了應對這種複雜佈局,只是比較適用於web1.0的圖文佈局界面。後來人以本身的聰明才智利用種種css特性,組合使用,實現了複雜的佈局方案。這種佈局方案相對比較複雜,須要很紮實的基本功,不是太容易理解。flex彈性佈局就是爲了應對這種狀況而生的。web
對於上述種種不便,若是讓咱們本身去要求有一種新的佈局方案,咱們會怎麼要求,我但願的是這樣less
個人要求就這麼簡單知足着3條就能夠解決我平常開發中的大部分問題,提升開發效率。flex的佈局設計就能夠輕鬆知足上述要求,並且還能夠知足咱們更多的要求。佈局
咱們來了解一下flex的設計,首先咱們瞭解一下2個概念:flex
display: flex
的元素都是flex容器
flex容器
的子元素都被稱爲flex項目
flex容器
默認有兩個軸線分別對應水平方向和垂直方向,叫作主軸和交叉軸。網站
默認主軸是水平方向,交叉軸是垂直方向,可是咱們也能夠經過設置調換,因此在flex設計中水平方向和垂直方向是同樣容易設置的。咱們能夠在flex容器
中設置主軸方向、排列方式。容器一共有6個css屬性能夠設置,其實都是圍繞主軸方向、排列方式設置的。ui
flex-direction
: 決定主軸方向,一共有4個值
flex-wrap
: 決定換行:spa
flex-flow
: flex-direction
屬性和flex-wrap
屬性的簡寫形式,默認值爲row nowrap
設計
justify-content
: 這個屬性就是決定主軸方向排列方式的,水平居中,等間隔排列均可以用它來實現,應用的比較多,有6個值:
align-items
: 這個屬性決定交叉軸方向的排列方式,能夠很方便地實現垂直居中,也有5個值,以從上到下的垂直方向爲交叉軸方向:
auto
,則填充整個容器高度align-content
: 該屬性定義了主軸有多根軸線時,多根軸線在交叉軸的排列方式。只有一根軸線,就是項目沒有換行時,該屬性不起做用。這裏比較複雜的一個地方是多軸線的問題,主軸一旦換行就會造成多個軸線,align-items
仍然在每一個軸線內起做用,而軸線的排列方式則由align-content
來設置,和justify-content
相對應。該屬性有6個值,以從上到下的垂直方向爲交叉軸方向:
例子:
<div class="outer">
<div class="inner">hello</div>
<div class="inner">nihao</div>
<div class="inner">wobuhao</div>
</div>
複製代碼
.outer{
display: flex;
background: blue;
height: 400px;
flex-wrap: wrap;
align-items: stretch;
align-content: stretch;
}
.inner{
width: 650px;
background: orange;
}
複製代碼
效果以下:
若是咱們把align-content
設置爲space-between
,則效果以下:
若是咱們把align-content
設置爲stretch
,同時align-items
設置爲center
,則效果以下,說明align-items
在單個軸線內起做用:
你能夠本身去試一試!
容器上的屬性都已經介紹完了,主要就是設置主軸方向和兩個軸的排列方式。
下面咱們介紹一下flex項目上的屬性,flex容器
上主要設置了排列方式,flex項目
上則主要設置了項目的大小。一樣flex-項目
上有6個css屬性能夠設置:
order
: 定義項目的排列順序。數值越小,排列越靠前,默認爲0
flex-grow
: 定義項目的放大比例,該值越大,放大的比例越大,0表示不放大,默認值爲0。這個屬性和下一個flex-shrink
很重要,須要深刻理解。這個有一個很容易誤解的點,就是放大比例是參考誰來放大的。注意不是參考主軸寬度,而是參考剩餘寬度,也就是容器寬度減去項目總寬度。固然了,若是項目總寬度加起來比容器寬度大,那就不存在放大這一說了,有剩餘空間的狀況下才會去放大。假如一行有n項目,n個項目的放大比例分別爲grow1,grow2...grown,則第m(m<=n)個項目的放大空間爲:
space = growm/(grow1+grow2+...grown) * (容器寬度
-項目總寬度
)
由此也能夠知道爲何0表示不放大,知道了明確的換算公式,咱們在設置大小時纔不會亂。
flex-shrink
: 定義項目的縮小比例,該值越大,縮小的比例越大,0表示不縮小,默認爲1。縮小比例的參考系則是項目總寬度減去容器寬度,也就是說容器寬度容納不下項目了,項目纔會去縮小。這裏和flex-grow
不同的地方是,縮小空間不止和flex-shrink
的值有關,還和項目的寬度有關。假如一行有n個項目,n個項目的flex-shrink
值分別爲shrink1,shrink2...shrinkn,n個項目的寬度分別爲width1,width2...widthn,則第m(m<=n)個項目的縮小空間爲:
space = (shrinkm *
widthm)/(shrink1 *
width1 + shrink2 *
width2 +...shrinkn *
widthn) *
(項目總寬度
-容器寬度
)
flex-basis
: 定義了項目在主軸上的所佔據的空間大小,默認值爲auto
。咱們以前說的放大縮小,都要依賴於項目總寬度
的計算。這個項目總寬度
就是依據flex-basis
算出來的。那若是項目原本就設置了width
或者height
,那項目寬度或者高度由誰來決定那?答案是flex-basis
,flex-basis
的優先級高於width
或者height
,可是低於min-widht
或者max-height
,仍受最大最小寬度的限制。好比下面的例子:
<div class="outer">
<div class="inner">
</div>
</div>
複製代碼
.outer{
display: flex;
height: 300px;
background: blue;
}
.inner{
width: 300px;
flex-basis: 500px;
background: yellow;
}
複製代碼
效果以下:
能夠看出項目的寬度是由flex-basis
決定的。另外當flex-basis
爲auto
時,則表示項目佔據主軸空間的大小爲項目原本的大小,此時width
便會起做用。
flex
: flex屬性是flex-grow
,flex-shrink
和flex-basis
的簡寫,默認值爲0 1 auto
。flex
的值使用起來比較複雜,能夠看下面這段代碼,基本包含全部狀況。/* Basic values */
flex: auto; /* 1 1 auto,該放大放大,該縮小縮小 */
flex: none; /* 0 0 auto,既不縮小,也不放大 */
/* One value, unitless number: flex-grow */
flex: 2;
/* One value, width/height: flex-basis */
flex: 10em;
flex: 30px;
/* Two values: flex-grow | flex-basis */
flex: 1 30px;
/* Two values: flex-grow | flex-shrink */
flex: 2 2;
/* Three values: flex-grow | flex-shrink | flex-basis */
flex: 2 2 10%;
複製代碼
align-self
: 和align-items
做用同樣,只不過該屬性設置在項目上,能夠對單個項目設置,容許咱們設置某些項目的排列方式和其餘不一樣。align-self
多了一個auto
屬性,表示繼承父元素的align-items
屬性。