flex設計思想和語法簡介

flex彈性盒子模型是新一代的佈局模式,在大部分狀況下能夠徹底替代以前的display屬性 + position屬性 + float屬性的佈局方式,設計友好,目前兼容性已經很好了,不少主流網站都已經開始採用。本文總結一下flex的設計思想和語法,以及在實際的佈局應用中爲咱們帶來了哪些便利。css

flex設計思想

咱們能夠仔細想一下咱們以前佈局的難點和麻煩的地方都有什麼,我總結了幾個:html

  • 自適應,好比最簡單的左側是固定寬度導航欄,右側自適應填充剩餘空間。通常使用float和margin來實現或者利用BFC的特性來實現
  • 居中,特別是垂直居中,一行有多個高度不一致的項目,要垂直居中,通常結合line-height和vertical-align來實現
  • 水平等間距的多項目排列,最兩端的兩側沒有間距,一般使用負margin或者css選擇器來實現
  • 須要解決float形成的高度塌陷問題

其實floatpositionline-heightvertical-align設計之初並非爲了應對這種複雜佈局,只是比較適用於web1.0的圖文佈局界面。後來人以本身的聰明才智利用種種css特性,組合使用,實現了複雜的佈局方案。這種佈局方案相對比較複雜,須要很紮實的基本功,不是太容易理解。flex彈性佈局就是爲了應對這種狀況而生的。web

對於上述種種不便,若是讓咱們本身去要求有一種新的佈局方案,咱們會怎麼要求,我但願的是這樣less

  • 我但願能夠定義某個元素自動擴大或者自動縮小,以實現自適應
  • 我但願能夠定義行或者列的排列方式,從左邊開始、居中、等間隔、從右邊開始等,均可以任意設置
  • 我但願設置垂直方向和設置水平方向同樣簡單

個人要求就這麼簡單知足着3條就能夠解決我平常開發中的大部分問題,提升開發效率。flex的佈局設計就能夠輕鬆知足上述要求,並且還能夠知足咱們更多的要求。佈局

咱們來了解一下flex的設計,首先咱們瞭解一下2個概念:flex

  • flex容器:凡是設置了display: flex的元素都是flex容器
  • flex項目:全部flex容器的子元素都被稱爲flex項目

flex 容器

flex容器默認有兩個軸線分別對應水平方向和垂直方向,叫作主軸和交叉軸。網站

默認主軸是水平方向,交叉軸是垂直方向,可是咱們也能夠經過設置調換,因此在flex設計中水平方向和垂直方向是同樣容易設置的。咱們能夠在flex容器中設置主軸方向、排列方式。容器一共有6個css屬性能夠設置,其實都是圍繞主軸方向、排列方式設置的。ui

  • flex-direction: 決定主軸方向,一共有4個值
    • row(默認): 主軸爲水平方向,從左到右排列
    • row-reverse: 主軸爲水平方向,從右到左排列
    • column:主軸爲垂直方向,從上到下排列
    • column-reverse: 主軸爲垂直方向,從下到上排列

  • flex-wrap: 決定換行:spa

    • nowrap(默認):不換行
    • wrap: 超過主軸空間則換行
    • wrap-reverse: 超過主軸空間則換行,新行在前面
  • flex-flow: flex-direction屬性和flex-wrap屬性的簡寫形式,默認值爲row nowrap設計

  • justify-content: 這個屬性就是決定主軸方向排列方式的,水平居中,等間隔排列均可以用它來實現,應用的比較多,有6個值:

    • flex-start(默認):左對齊
    • flex-end: 右對齊
    • center: 居中
    • space-between: 兩端對齊,項目間的間隔相等
    • space-around: 每一個項目兩側的間隔相等。因此,項目之間的間隔比項目與邊框的間隔大一倍。
    • space-evenly: 項目沿主軸均勻分佈。

  • align-items: 這個屬性決定交叉軸方向的排列方式,能夠很方便地實現垂直居中,也有5個值,以從上到下的垂直方向爲交叉軸方向:
    • flex-start: 上對齊
    • flex-end: 下對齊
    • center: 居中對齊
    • stretch(默認值): 拉伸,若是未設置高度或者高度設爲爲auto,則填充整個容器高度
    • baseline: 項目的第一行文字的基線對齊

  • align-content: 該屬性定義了主軸有多根軸線時,多根軸線在交叉軸的排列方式。只有一根軸線,就是項目沒有換行時,該屬性不起做用。這裏比較複雜的一個地方是多軸線的問題,主軸一旦換行就會造成多個軸線,align-items仍然在每一個軸線內起做用,而軸線的排列方式則由align-content來設置,和justify-content相對應。該屬性有6個值,以從上到下的垂直方向爲交叉軸方向:
    • flex-start:上對齊
    • flex-end: 下對齊
    • center: 居中
    • space-between: 兩端對齊,項目間的間隔相等
    • space-around: 每一個項目兩側的間隔相等。因此,項目之間的間隔比項目與邊框的間隔大一倍
    • stretch(默認值): 軸線佔滿整個交叉軸,strech屬性和其餘屬性的不一樣之處在於,strech會自動擴展軸線的高度,而其餘屬性都是以軸線實際佔用的位置進行排列。具體能夠看下下面的例子。

例子:

<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項目上則主要設置了項目的大小。一樣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-basisauto時,則表示項目佔據主軸空間的大小爲項目原本的大小,此時width便會起做用。

  • flex: flex屬性是flex-grow,flex-shrinkflex-basis的簡寫,默認值爲0 1 autoflex的值使用起來比較複雜,能夠看下面這段代碼,基本包含全部狀況。
/* 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屬性。
相關文章
相關標籤/搜索