CSS3 Flexbox佈局那些事

相信研究過CSS3的同窗對Flexbox佈局必定不會陌生(做爲一個將來主流的佈局方式,至少有所耳聞)。最近完成了兩個項目:一個是移動端H5項目,一個是嵌入HTML頁面的mac客戶端項目。爲了慶祝這兩個項目不用再兼容萬惡的IE,同時要體現出現代瀏覽器的優點,決定在項目中嘗試使用Flexbox佈局。項目第一個版本完成後回過頭來看,仍是有很多須要注意的地方。現將項目中的一些經驗總結一下,但願可以對想嘗試使用Flexbox的同窗有所幫助,在恰當的地方使用恰當的佈局方法。css

初識Flexbox

Flexbox佈局俗稱伸縮佈局,它能夠簡單快速的建立一個具備彈性功能的佈局。一個Flexbox佈局是由一個伸縮容器(flex containers)和在這個容器裏的伸縮項目(flex items)組成。伸縮容器(flex containers)是一個HTML標籤元素,而且「display」屬性顯式的設置了「flex」屬性值。在伸縮容器中的全部子元素都會自動變成伸縮項目(flex items)。當在一個小屏幕上顯示的時候,Flexbox可讓元素在容器(伸縮容器)中進行自由擴展和收縮,從而容易調整整個佈局。html

Flexbox佈局可以讓咱們很輕鬆的實現如下效果:前端

  • 在不設置元素的具體寬度的情形下將元素排成橫排,並在一排的空間不夠的時候折行。
  • 快速的將元素排成豎排。
  • 將元素沿着父容器的左邊、右邊或中間或者兩端(以前只能使用text-align:justify,還須要爲低版本瀏覽器作不少兼容)排齊。
  • 改變元素顯示的順序而不改變HTML代碼。
  • 將每一個元素佔有的空間設置爲父元素寬度/高度的一個比例,卻不用擔憂在父元素的尺寸設置爲百分比值的時候或是窗口的尺寸變化的時候佈局會壞掉。
  • 實現元素的水平,垂直居中。

這些效果是否是很誘人,爲了咱們都能更好的理解接下來的內容,須要對Flexbox有一個初步的認識。沒有了解過Flexbox知識的同窗請先移步伸縮佈局--打開佈局天堂之門!android

Flexbox佈局實戰

若是已經對Flex有了初步瞭解,那讓咱們來舉例說明何時更適合使用該佈局。ios

1. 看看哪些產品使用了Flexbox佈局

【No.1】youku H5播放頁的控制區域css3

將瀏覽器的UA改成ios或者android,而後訪問youku的播放頁。先來看下示意圖:web

播放區域分爲四個部分:mod-one爲播放按鈕區域,mod-two爲時間顯示區域,mod-three爲切換視頻質量和其餘操做區域,mod-four爲全屏按鈕區域。瀏覽器

該播放區域的排版需求以下:mod-one和mod-two定寬依次居左,mod-four定寬居右,mod-three自動填充剩餘的寬度且該區域內的元素依次居右排列(除了切換視頻質量按鈕外還有其餘操做按鈕)。ide

下面來看看youku如何使用Flexbox進行html佈局以及css實現:佈局

 

x-controls爲Flexbox伸縮容器,核心樣式以下:

display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
x-controls code

該css設置了x-controls爲Flexbox容器,子元素(伸縮項目)橫向排列。box-pack沒有設置,默認爲start,即彈性盒模型對象的子元素從開始位置對齊。 

PS:使用Flexbox佈局的時候儘可能使用兼容語法,避免使用最新語法致使舊版系統(android2.2,ios5)出現不兼容的狀況。

若是要兼容Windows Phone(IE10+)須要加入IE專有語法(IE和其餘瀏覽器語法稍有區別,必定要注意),詳見最後附上的兼容代碼。

回到youku播放頁,x-play-control爲播放按鈕區域,根據需求只須要設置寬度便可。x-time-display爲時間顯示區域,css設置同播放按鈕區域。

x-settings須要設置自動填充屏幕剩餘寬度,同時該模塊內的子元素須要居右顯示,所以它既要做爲一個伸縮項目,又要做爲一個伸縮容器。css代碼以下:

display: -webkit-box;
display: -moz-box;
display: box;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-pack: end;
-moz-box-pack: end;
box-pack: end;
-webkit-box-flex: 1;
-moz-box-flex: 1;
box-flex: 1;
x-settings code

爲告終構的合理性,youku將x-fullscreen放到了x-settings中,所以須要絕對定位到最右側。不然能夠將x-fullscreen做爲兄弟節點放到x-settings後,一樣也能實現該效果。

【NO.2】UC網址導航

某天使用UC瀏覽器的網址導航,下意識的查看了一下源碼,發現其導航部分也使用了Flexbox佈局。內心暗喜,這也算是爲推動CSS3在國內的普及作出了一點貢獻。

直接用瀏覽器訪問該網址,示意圖以下:

該需求比較簡單,8個標籤兩兩一組。4組平均分配屏幕寬度。

html結構及樣式以下:

block爲伸縮容器,設置以下樣式:

display: -webkit-box;
-webkit-box-pack: justify;
block code

block-list爲伸縮項目,設置以下樣式:

-webkit-box-flex: 1;
width: 25%;
block-list code

簡單的幾句css就實現了自動伸縮的佈局。固然,這個例子比較簡單,使用css2的技術也能夠實現,好比block-list中的width: 25%; 我想就是起了優雅降級的做用。

2. 何時使用Flexbox佈局

先讓咱們看一個需求:

一樣是一個播放器的操做區域,分爲三部分:左邊爲視頻質量選擇按鈕,居左顯示;中間爲控制視頻進度的按鈕組,居中顯示;右邊爲分享和全屏按鈕,居右顯示。

瞭解需求後我很興奮,剛剛學習的Flexbox佈局終於有用武之地了。無論三七二十一便爲這版UI制定了兩套方案:

兩套方案html結構相同,如圖:

CSS方案略有不一樣,方案一:

不給伸縮項目定寬,直接使用box-pack:justify將3個伸縮項目定位到圖中的位置,代碼:

display: -webkit-box;
display: -ms-flexbox;
display: box;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
box-pack: justify;
-webkit-box-orient: horizontal;
-ms-box-orient: horizontal;
box-orient: horizontal;
fbJustify

不用給伸縮項目寫任何css便可實現UI中的效果,完成後感慨Flexbox簡直是逆天的存在!

方案二:

給三個伸縮項目div設置-webkit-box-flex:1; 而後分別給第一個設置text-align: left; 第二個設置text-align: center; 第三個設置text-align: right; 能夠經過css3的:first-child和:last-child完成。

某天,前端開發的過程當中,產品跑來對我說:分享按鈕這期先不上。so easy,我直接使用display: none隱藏了分享對應的 a 標籤。

而後……相信已經有同窗發現會出現神馬情況了。

我去,中間的按鈕往右移動了。不論使用方案一仍是方案二都會出現此問題。經過分析後發現,在方案一中,因爲我伸縮項目的寬度都是根據其內容撐開的。因此右側子內容不見了,伸縮項目的寬度天然也就發生了變化,從新分配三個伸縮項目後就是圖中的效果。而方案二雖然設置了伸縮比flex:1; 可是整體寬度仍是和容器的內容有關係。後來仔細想一想,雖然此次歪打正着提早遇到了問題,但就算分享功能定期上線,並非全部視頻都提供分享,所以最終仍是會出現這個問題。

如何解決呢?

對於這種包含居中顯示的佈局(且需求可能隨時會變化),最好的方法是左右兩個伸縮項目定寬。中間的伸縮項目設置flex:1,具備固定寬度的伸縮項目不會對彈性的伸縮項目產生影響。這個例子告訴咱們,在瞭解需求的基礎上,儘可能將佈局作的通用性強一點,可以適應更多的突發狀況。CSS近幾年一直推崇的OOCSS理念即如此。

最後說一個Flexbox實現的水平、垂直居中例子:

伸縮容器設置以下樣式,伸縮項目不管是否認義寬高均可實現水平、垂直居中效果。

html代碼:<div class="flexbox"><div>這裏能夠聽任何元素</div></div>

/* 舊版語法 */
display: -webkit-box;
display: -ms-flexbox;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-box-align: center;
-ms-flex-align: center;

/* 新版語法 */
display: -webkit-flex;
display: flex;
-webkit-align-item: center;
align-item: center;
-webkit-justify-content: center;
justify-content: center;
Flexbox居中

附上一段Flexbox新老版本兼容及對應語法的代碼,供你們參考。

/* display */
display: -webkit-box;      /* OLD - iOS 6-, Safari 3.1-6 */
display: -moz-box;         /* OLD - Firefox 19- (doesn't work very well) */
display: -ms-flexbox;      /* TWEENER - IE 10+ */
display: -webkit-flex;      /* NEW - Chrome */
display: flex;                  /* NEW, Spec - Opera 12.1, Firefox 20+ */

/* 沿着主軸方向對齊項目 */
-webkit-box-pack: start;
-moz-box-pack: start;
-webkit-justify-content: flex-start;
-ms-flex-pack: start;
justify-content: flex-start;

/* 沿着側軸方向對齊項目 */
-webkit-box-align: start;
-moz-box-align: start;
-webkit-align-item: flex-start;
-ms-flex-align: start;
align-item: flex-start;

/* 伸縮項排列方式 */
-webkit-box-direction: normal;    /* 舊版伸縮項對齊方式,在新版中已經合併到了flex-direction */
-moz-box-direction: normal;
-webkit-box-orient: horizontal;
-moz-box-orient: horizontal;       /* vertical */
-webkit-flex-direction: row;        /* column, row-reverse, column-reverse */
-ms-flex-direction: row;
flex-direction: row;

/* 伸縮項目是否換行 */
-webkit-flex-wrap: nowrap;
-ms-flex-wrap: nowrap;
flex-wrap: nowrap;

/* 多行伸縮容器的對齊 */
-webkit-align-content: stretch;
-ms-flex-line-pack: stretch;
align-content: stretch;

/* 改變伸縮項佈局順序和使伸縮項目可適應伸縮容器 */
-webkit-box-ordinal-group: 1;
-moz-box-ordinal-group: 1;
-ms-flex-order: 1;
-webkit-order: 1;
order: 1;

-webkit-box-flex: 1;
-moz-box-flex: 1;
-webkit-flex: 1;
-ms-flex: 1;
flex: 1; 
Flexbox兼容

結語

本篇文章目的是起到拋磚引玉的做用,幫助你們可以更快的將Flexbox佈局運用到本身的項目中。我相信CSS將來發展的方向就是採用Flexbox這種佈局方式。

因爲本人也是剛開始接觸Flexbox這種佈局方式,有不少地方還須要繼續研究。文中有任何不妥,或有任何建議歡迎你們提出!

相關文章
相關標籤/搜索