Flexbox 佈局是 CSS 3 新增的佈局模式,在 display 中的值是 display: flex; display: inline-flex;
。flex 具備很好的適應性,在電腦瀏覽器和手機瀏覽器中都有很好的表現。雖然其標準仍然是「候選(CR)」,可是在各個瀏覽器已經獲得了很普遍的支持。如圖1,從圖中咱們能夠看出,flex模塊已經獲得了幾乎全部瀏覽器的支持,IE11部分支持,咱們能夠在實際的項目中嘗試使用,若是是IE Version<=11的話,要作必定的 polyfill。css
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 的條目對其將會涉及到相應的概念。佈局
容器能夠設置的屬性:學習
屬性 | 值及其說明 |
---|---|
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
<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 元素中。
一樣是上面的 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 的盒模型總的高度,不然仍然會溢出。
<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 的實現效果圖。
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 的分段閾值或者根據實際狀況制定。多餘的我就不說了,你確定能看懂。
只要理解了 Flexbox 的設計初衷,並瞭解其屬性和值的含義及用處,那麼在實際的需求面前就能夠很從容的應用這項技術了。這也是個人學習新東西的思路,首先想爲何有這個東西,爲解決什麼問題的,有什麼 API,而後和其它技術的對比,而後在具體問題面前靈活運用。