Flexbox 佈局 與 常見佈局需求實現對比

Flexbox 佈局是 CSS 3 新增的佈局模式,在 display 中的值是 display: flex; display: inline-flex;。flex 具備很好的適應性,在電腦瀏覽器和手機瀏覽器中都有很好的表現。雖然其標準仍然是「候選(CR)」,可是在各個瀏覽器已經獲得了很普遍的支持。如圖1,從圖中咱們能夠看出,flex模塊已經獲得了幾乎全部瀏覽器的支持,IE11部分支持,咱們能夠在實際的項目中嘗試使用,若是是IE Version<=11的話,要作必定的 polyfill。css

flex瀏覽器支持程度

what for?

flexbox,是’flexible box’ 的縮寫,聲明爲display: flex/inline-box 的元素能夠改變子元素的高度和/或寬度,來適應不一樣大小的瀏覽器尺寸和顯示設備類型,是響應式佈局的一種技術。利用塊級元素佈局基於垂直方向,行內元素基於水平方向,flexbox 則是水平和垂直方向都能很好的適應。關於 Flexbox ,我以爲記住一點就好,聲明 display: flex;或者 display: inline-flex;的元素的子 flex 條目會充滿父元素的全部空間。html

沒有 flexbox 時,使用 css 佈局時,咱們使用 float 、display 和 position,這些技術沒有問題,可是實現不是很直觀。可是利用這些技術,且對於一些特殊任務實現起來仍然有困難,好比 垂直居中元素。flex 實現這些佈局是至關容易的事情,咱們能夠總結說,Flexbox 就是一種「彈性佈局」模型,能很好支持不一樣視口尺寸和設備。bootstrap

看完整篇文章後,你會以爲這個和 table 佈局十分相似啊!下面說點具體的 【嚴肅臉】。瀏覽器

內容

說明: 主軸爲 flex-direction 指定的方向,側軸是與主軸方向垂直的軸,借用 MDN 上的一張圖說明。main axis 即爲主軸,主軸方向開始叫作‘main start’,結束叫作‘main end’;cross axis 爲側軸,開始爲 cross start,結束爲 cross end。在這裏指出這些知識,是由於如下的 flex 的條目對其將會涉及到相應的概念。佈局

MDN軸方向說明圖

容器能夠設置的屬性:學習

屬性 值及其說明
flex-direction 條目放置的方向(主座標軸),row(默認值),水平放置;column,垂直放置
flex-wrap flex條目溢出父元素時是否應該換行,nowrap(默認值),不換行顯示;wrap表示換行,按照父元素的尺寸來佈局,若是溢出,那麼溢出的將換行顯示,最終結果爲顯示爲多行,且不管哪一行,有幾個子元素,都會自適應填充滿每一行;wrap-reverse,與wrap相同,可是順序相反
flex-flow flex-direction和flex-wrap的簡寫,和margin、padding等簡寫四個方向相似
justify-content 規定flex條目在主軸方向的排布規則。flex-start,條目左對齊,最左邊的元素的margin邊框將會失效;flex-end,條目右對齊,最右邊的元素的margin邊框將會失效;center,居中對齊;space-between,沿主軸方向均勻分佈,開始和結束margins失效;space-around,沿主軸均勻分佈,與space-between不一樣之處在於開始和結束的margins等於相鄰兩個flex條目間距的一半
align-item 規定flex條目在側軸(flex-direction規定的主軸垂直方向)方向的排布規則。flex-start,垂直上對齊;flex-end,垂直下對齊;center,垂直居中對齊;baseline,stretch(默認值),在側軸方向拉伸flex條目,以期在側軸方向填滿整個容器


條目能夠設置的屬性:測試

屬性 值及其說明
flex-grow 主軸方向flex條目所佔比例,值爲Number類型
flex-shrink 主軸方向flex條目縮放比例,值爲Number類型
flex-basis 主軸方向flex條目最小尺寸,px或者%
flex 是 flex-grow、flex-shrink 和 flex-basis 屬性的簡寫,確立彈性項目的伸縮性
order flex條目在全部flex條目中的次序
align-self 同父元素的align-item,定義了單個彈性項目在側軸上應當如何對齊,這個定義將覆蓋由 align-items 所確立的默認值

看完這些說明,咱們來看看如何利用 Flexbox 實現咱們經常使用的佈局。flex

各類常見佈局要求的 Flexbox 實現

水平方向多列自適應佈局

要求:兩列布局,左側列寬度固定,右側列自適應,填充整個容器。

  1. 傳統作法:浮動定位或絕對定位左側列,右側列margin實現與左側列隔離。
<section>

     <article class="left">
       <b>left width-fixed</b>
     </article>

     <article class="right">
       <b>right auto-fill</b>
     </article>

   </section>

樣式:flexbox

html, body{
     height: 100%;
     margin: 0;
     padding: 0;
   }
   section, article{
     height: 100%;
   }
   .left{
     float: left;
     width: 300px;
     background-color: rgb(255, 0, 0);
   }
   .right{
     margin-left: 300px;
     background-color: rgb(0, 255, 0);
   }

效果以下:spa

自適應-窄

自適應-寬

==========附帶一提(可是很重要的點)============

外邊距(margin)疊加問題,簡單的說,就是當兩個或更多的垂直外邊距相遇時,它們將造成一個外邊距,這兩個外邊距的高度等於兩個發生疊加的外邊距的高度中的較大者。好比,我在上面的例子中,每個 article 內的標題都是使用 b 標籤,若是我換成 h* 標籤,那麼就會出現這個問題。如圖,我將b 標籤換成了 h2,h2 是塊級元素,有垂直外邊距,在chorme 中,本例的 h2 默認外邊距是 19.920 像素,外邊距爲0的父元素疊加外邊距爲 19.920 像素的子元素,將會出現 19.920 像素的垂直外邊距:

外邊距疊加

須要注意,若是父元素是float 定位,那麼該問題不會出現,因此你會看到左側 article 中的 h2 元素外邊距在 article 元素中。

  1. 使用 Flexbox 實現

一樣是上面的 HTML 結構,樣式以下。

html, body{
        height: 100%;
        margin: 0;
        padding: 0;
      }
      section, article{
        height: 100%;
      }
      section{
        display: flex;
      }
      .left{
        width: 300px;
        background-color: rgb(2,138,201);
      }
      .right{
        flex-grow: 1;
        background-color: rgb(78,55,115);
      }

效果以下圖,這下好了,h* 的外邊距都在裏邊了,沒有出現外邊距疊加了,可見,article元素已經不是普通的定位了。可是要注意,article 高度必須大於 h2 的盒模型總的高度,不然仍然會溢出。

Flexbox實現

垂直方向多行自適應佈局

要求:三行佈局,第一行和第三行高度固定,第二行自適應,填充整個容器。

  1. 傳統作法,使用 table 佈局。
<section>

      <header>
        <h2>header</h2>
      </header>

      <article class="content">
        <h2>content</h2>
      </article>

      <footer>
        <h2>footer</h2>
      </footer>

    </section>

樣式:

html, body{
     height: 100%;
     margin: 0;
     padding: 0;
   }
   section{
     height: 100%;
     width: 100%;
     display: table;
   }
   .content{
     display: table-row;
     background-color: rgb(2,138,201);
   }
   header, footer{
     display: table-row;
     background-color: rgb(72,82,94);
   }
   header{
     height: 90px;
   }
   footer{
     height: 80px;
   }

效果和使用 Flexbox 實現的效果徹底一致,這裏就不貼圖了,能夠看 Flexbox 的實現效果圖。

  1. Flexbox 實現
html, body{
     height: 100%;
     margin: 0;
     padding: 0;
   }
   section{
     height: 100%;
     display: flex;
     flex-direction: column;
   }
   .content{
     flex-grow: 1;
     background-color: rgb(2,138,201);
   }
   header, footer{
     background-color: rgb(72,82,94);
   }
   header{
     height: 90px;
   }
   footer{
     height: 80px;
   }

這裏寫圖片描述

這裏寫圖片描述

看完效果是否是感受很 nice 呢。之後遇到這種佈局需求,就是用 Flexbox 吧!結合水平的和垂直的佈局,能夠作出一些複雜的單頁應用佈局。

水平居中且垂直居中

使用 Flexbox 作頁面居中也很容易,

<section class="container">
     <div class="spacer"></div>

     <section class="horizontal">
       <div class="spacer"></div>

       <article class="content">
           居中的內容
       </article>

       <div class="spacer"></div>
     </section>

     <div class="spacer"></div>
   </section>

樣式:

html, body{
      height: 100%;
      margin: 0;
      padding: 0;
    }
    .container{
      height: 100%;
      display: flex;
      flex-direction: column;
      background-color: rgba(0, 0, 0, 0.8);
    }
    .spacer{
      flex: 1;
    }
    .horizontal{
      display: flex;
      flex-direction: row;
    }
    .content{
      height: 200px;
      width: 400px;
      background-color: rgb(255, 255, 255);
      color: rgb(0, 0, 0);
      border-radius: 4px;
      padding: 10px;
    }

HTML 中咱們使用了四個名爲spacer類的墊片,這裏主要利用了 flex 條目會佔據全部可用空間的特性,讓它們把主要的內容擠到中間的位置 ^_^。我給內同區域添加了圓角效果和內邊距,最終效果以下圖。看到沒,就這麼簡單就作出了一個彈出層,再加上一點鼠標和鍵盤事件,這不就是一個咱們經常使用的 bootstrap「模態框」麼 【笑】。

頁面居中的彈出層

有一個叫作絕對居中的技術,我從其餘博客做者看到的,內容較多,這裏咱們再也不介紹,找個機會咱們和 Flexbox 實現作一個對比。

大屏和小屏之間的響應性

結合 flex-direction , flex-wrap,order 和 媒體查詢,作出的佈局會有比較好的跨設備的特性。下面舉個例子,咱一塊兒看看它們的威力。

<section>
    <nav>
      <button> 測試 </button>
      <button> 測試 </button>
      <button> 測試</button>
    </nav>

    <article>
      主要內容
    </article>

  </section>

樣式:

html, body{
     height: 100%;
     margin: 0;
     padding: 0;
   }
   section{
     height: 100%;
     display: flex;
   }
   nav{
     width: 200px;
     display: flex;
     background-color: rgb(2,138,201);
   }
   button{
     height: 30px;
     flex: 1;
   }
   article{
     flex: 1;
     background-color: rgb(72,82,94);
   }
   @media screen and (max-width: 640px) {
     section{
       flex-direction: column;
     }
     nav{
       width: 100%;
       flex: 1;
       order: 2;
       flex-direction: row;
     }
     article{
       flex: 3;
     }
   }
   @media screen and (max-width: 320px) {
     nav{
       flex-direction: column;
     }
   }

效果,例子中利用媒體查詢,根據瀏覽器寬度分了三個階段,固然 640,320都是胡謅的,真實狀況下,並非這個界限,合適的尺寸能夠參考 Bootstrap 的分段閾值或者根據實際狀況制定。多餘的我就不說了,你確定能看懂。

  • >640px,判斷爲電腦瀏覽器;
  • 640px > width >320px,判斷爲平板瀏覽器;
  • <320px,判斷爲手機瀏覽器。

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

總結

只要理解了 Flexbox 的設計初衷,並瞭解其屬性和值的含義及用處,那麼在實際的需求面前就能夠很從容的應用這項技術了。這也是個人學習新東西的思路,首先想爲何有這個東西,爲解決什麼問題的,有什麼 API,而後和其它技術的對比,而後在具體問題面前靈活運用。

相關文章
相關標籤/搜索