Web App中的Flexbox應用

雖然語法可能比較混雜,但 Flexbox 仍是名不虛傳的。它創造的是可伸縮的、有彈性的、可改變視覺順序的智能盒子。它提供了簡單的CSS佈局方案範例讓容器老是處於垂直水平居中的位置。使用盒模型來工做是很是通用的。css

Chris Coyier 對Flexbox的總結很好:html

彩蛋爆料直擊現場前端

Flexbox Layout(彈性盒模型)模塊(目前W3C工做草案正在最後經過)的目的是爲了提供一種更有效的方式來佈局,使各模塊即便大小是未知或者動態的也能夠在項目空間中合理分配位置(就像「彈性」這個詞同樣)。 彈性佈局的主要思想是:讓這個容器有能力自動改變寬高(和順序)來儘量地填充可用空間(大多用來適應全部類型的顯示器的屏幕尺寸)。Flex容器能夠擴展它的模塊來填充可用空間或縮小來防止溢出。css3

Flexbox真正的發光是在HTML5 Web應用上。大多數Web Apps 由一系列模塊化、可重用的組件組成。你可使用Flexbox來爲那些令你頭痛的和依賴於脆弱的CSS hack 的地方佈局。好的方法是使用Flexbox對小模塊的地方進行佈局,而後用float和其它工具來佈局更普遍的地方。git

我正在作的Web應用程序上使用了不少的Flexbox,我很是喜歡它處理佈局和盒子的智能計算。我想要分享一些關於盒模型的例子,若是有什麼反饋我將感激涕零。github

本文假定你已經有必定相關的Flexbox工做經驗。網上也有大量關於這方面的信息。請記住,它的規範已經經歷了不少年的變化。web

若是你對Flexbox一無所知,或者從未了解,譯者建議您先點擊這裏瞭解有關於Flexbox的相關知識。瀏覽器

Flexfox經歷過三個版本,主要區別是2009年到2012年之間的語法變化。sass

  1. 最新的語法和如今規範是同步的(例display:flex)。
  2. 在這之間的語法是2012年出現的非官方語法,只能被IE識別(例display: -ms-flexbox)。
  3. 最老的語法產生於2009年(例display: box

瀏覽器支持狀況

讓咱們來具體看看那些瀏覽器支持那些語法以及支持狀況前端框架

支持新語法的瀏覽器

PC端:

  • 無前綴:Chrome 29+, Firefox 28+, IE 11+, Opera 17+
  • 須要前綴:Chrome 21+, Safari 6.1+, Opera 15+須要前綴-webkit-

提示:舊版本的Firefox(22-27)支持除了flex-wrapflex-flow以外的新語法。Opera (12.1+ - 17+)使用flex能夠沒有私有前綴,可是中間的15和16版本須要私有前綴。

移動端:

  • 無前綴:Android 4.4+, Opera mobile 12.1+, BlackBerry 10+, Chrome for Android 39+, Firefox for Android 33+, IE 11+ mobile
  • 須要前綴:iOS 7.1+須要前綴-webkit-

幾乎上述全部瀏覽器的舊版本都支持Flexbox的版本退化,除了一些像flex-wrapflex-wrap的屬性(後者是flex-directionflex-wrap屬性的簡寫)。經過避免flex-wrap咱們獲得了瀏覽器對於合併新舊語法驚人的支持。

支持中間語法的瀏覽器

PC端和移動端:IE10(使用-ms-私有前綴)。

支持舊語法的瀏覽器

全部PC端和移動端的瀏覽器都須要加-webkit-的私有前綴(除了firefox須要使用-moz-前綴)。

  • PC端:Firefox 2 – 21, Chrome 4 – 20, Safari 3.1 – 6
  • 移動端Android 2.1 – 4.3, iOS 3.2 – 6.1, UC browser 9.9 on Android, BlackBerry 7

對於具備自動更新功能的現代瀏覽器(好比Chrome, Firefox, IE and Opera的桌面瀏覽器),能夠直接使用新的語法形式。

不支持flexbox語法的瀏覽器

  • PC端:IE9和Opera12如下
  • 移動端Opera Mini

若是你被私有前綴的數量和語法的改變所嚇到,你須要看一下Chris Coyier的建議

你開能夠經過如下工具去得到瀏覽器私有前綴最好的支持

  • Autoprefixer有了這個通用的私有前綴編寫工具,就能夠爲你寫的css或預處理文件添加相應的前綴
  • Sass flexbox mixins
  • Less:LESS mixin 有兩種形式:對於IE10 而言或者沒有中間語法。

根據如下這些緣由我會建議使用Autoprefixer。我尚未嘗試過其它預處理器的解決方案,若是你有歡迎提出任何意見。須要注意的是,若是你使用一個mixin的輔助庫(例如Bourbon或Sass的Compass,Stylus的Nib和LESS的LESS Hat),它須要創建在對flexbox私有前綴支持的基礎上。

有了這樣一個Autoprefixer工具,實際上你獲得了除了IE9和Opera Mini以外的,對flexbox很大程度上的支持。固然,你依舊須要在全部瀏覽器上完全測試你的應用程序,以確保對不一樣語法的支持。

讓咱們來看看幾個不錯的關於使用flexbox的web app的例子

一個父元素包含不定數量的子元素

用例:個人App具備搜索過濾功能。搜索過濾器的數量取決於用戶是否登錄。匿名用戶能夠看到兩個過濾器(「公衆」和「最新」),登錄用戶可同時看到四個(還有「主要」和「收藏」)。

問題:我想要在不對CSS樣式作任何改變的狀況下適應這兩種選項。

討論:你們一般在你的模板裏使用if聲明來處理登錄用戶的狀態。若是你使用float來佈局,你還須要爲匿名用戶的過濾器設置50%的寬度,爲登錄用戶的過濾器設置25%的寬度。

解決方法:使用Flexbox,你只須要經過爲父容器設置display:flex而後給子元素的flex屬性設爲1,這將讓每一個子元素在父容器內佔據相等的寬度。因此,不管視圖怎麼改變css樣式都不須要改變。請記住flex屬性是flex-grow``flex-shrinkflex-basis的簡寫。

示例:

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox:一個父元素包含不定數量的子元素

帶圖標的輸入框

用例:我想要在個人表單輸入框上加一個有意義的圖標。

問題:我想要一個沒必要規定寬高的靈活的優雅的解決方案。

討論:這是一個經典問題。不一樣的前端框架有不一樣的處理方法,大多數是用display:table-cell或者使用絕對定位。

解決方法這裏有一個Flexbox的方法。全部咱們須要作的就只是把input 框和圖標包在一個父元素內部,併爲這個父元素設置display:flex,而後,爲input 框添加flex:1,讓它佔用父元素減去圖標寬度的剩餘空間。

示例:(經過CDN使用Font Awesome 字符圖標很方便)

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox:帶有圖標的輸入框

視覺順序

Flexbox能夠用來改變文檔的視覺順序但依舊會根據文檔的原順序來保留導航的完整性。咱們做爲開發人員的主要工做是負責使用Flexbox排序機制所產生的巨大能量。

事實上,咱們能夠經過對源文件使用適當的輔助技術來構建咱們的文件像屏幕閱讀器那樣(好比:在源順序裏把側邊欄放在主內容以前),而且使用flexbox簡單的改變可視順序來使用戶圖形界面更加友好化(經過orderflex-direction屬性來把側邊欄豎立在主內容的右側)。讓咱們倆看看這些細節。

flex-direction 產生的視覺獨立

用例:我有一個側邊欄定位在主內容的右側。在小屏幕上,我想改變順序把側邊欄放在主內容的頂部。

問題:我不想使用JavaScript或者CSS hack的方式來改變視覺順序。

討論:Flexbox在佈局方面是不可知論的。這是它成爲一個響應式佈局的神奇工具。咱們能夠經過兩種方式來作到這一點:使用flex-direction屬性或order屬性。讓咱們來看看這裏的第一個方法。

解決方法:讓咱們把側邊欄放在咱們代碼佈局中的第一部分。這符合邏輯的緣由有兩個:它堅持移動優先的佈局原則,吧側邊欄連接放在元順序的優先位置是對屏幕閱讀器有益的。而後咱們在父元素中聲明flex-direction(由於row是默認值)。在咱們的大屏幕上,咱們將把flex-direction替換成row-reverse,這樣就解決了咱們的問題。

做爲獎勵,咱們將放一個fixed-width 的側邊欄(它在大屏幕和移動屏幕上始終是180px)。

示例:

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox:使用flex-direction讓側邊欄與源順序無關

order 產生的視覺獨立

咱們的用例與問題和上面的例子相同。

討論:order屬性能夠比flex-direction更精確的控制視覺順序。

解決方法:咱們在父元素上聲明flex-direction:column讓它在手機上兩列疊加。而後,設置一個媒體查詢的min-width,咱們將把flex-direction變成row,這樣將把側邊欄放在左側,把主內容放在右側。爲了改變順序,咱們爲主內容設置order:1爲側邊欄設置order:2

示例:

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox:使用order讓側邊欄與源順序無關

切換升序和降序

用例:我想要顯示2013年好萊塢收入最高的五個演員名單,容許切換順序。

問題:我無來由的想使用純CSS來實現這個效果,但我並不肯定它是否可行。

討論:這是一個簡單的沒有JavaScript演示,來展現Flexbox的強大。也許有一點瘋狂、不切實際,但讓咱們來看看是否有這樣一種方式。

解決方法: 咱們將添加一個有label的複選框,經過複選框的選中來切換成由低到高的順序。下面,咱們將添加演員的名單。使用CSS的:checked僞類來檢查是否被選中。咱們選擇複選框後當即反轉無序列表的順序(經過使用flex-direction)。雖然這很奇怪,但它是完美的做品,除非你使用屏幕閱讀器或鍵盤導航。在下面的演示中,選擇複選框使用鍵盤導航能夠看到這種影響。規範中提到order既不影響tabindex也不影響視覺媒體。所以,我不推薦把這種解決方案放在你的項目中。或許它能夠在一個快速原型中派上用場。

提示:在Firefox如今的版本中有一個bug(Ubuntu的34版本,Mac OS X 和Windows的33版本)會致使tableindex準守改變後的順序而不是源順序。你能夠看一下CSS社區的測試用例

示例:

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox:切換列表順序

註釋模塊

用例:我有一個典型的註釋模塊,圖片在左面,內容在右面。圖片頭像始終是一樣的寬高(注:這不是響應式的)。

問題:我使用Flexbox,但這樣內容和圖片會重疊:

註釋模塊

若是你在圖片上設置max-width:100%;height:auto,就會變成下面這樣:

註釋模塊

討論:這個例子相似於上面帶圖標的輸入框的例子。可是咱們能夠用它來討論flex-shrink屬性,這在你某些狀況下是很是方便的。

解決方法:在包裹圖片和文字的父元素上添加display:flex。你會發現文本覆蓋在頭像圖片上(或者該頭像圖片很是的小,就像上面那張圖片那樣)。爲了克服這個狀況,你能夠在圖片上聲明flex-shrink:0,這確保了它不會收縮來適應其它flex項目的寬度。另外一種方法是爲註釋的文本添加flex:1。這種狀況下,你不須要在頭像上設置flex-shrink:0。總的來講,規範推薦使用flex速記的方法,但它可讓你很好的理解flex-shrink屬性。

示例:

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox的註釋模塊

複雜的菜單

用例:個人app上有一個菜單,其中包括搜索和排序部件。它融合了按鈕,輸入框,圖標和文本。

問題:我擔憂在不一樣尺寸的屏幕上佈局會被打亂。

討論:這是一個完美的flexbox用例。有些地方須要固定寬度,而有些地方則需根據屏幕的寬度進行填充。

解決方法:咱們能夠經過Flexbox進行垂直居中並用相對較少的代碼靈活書寫查找排序模塊。

示例:(經過CDN使用Font Awesome 字符圖標很方便)

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox示例:搜索和過濾

卡片

用例:我想基於Google Material Design文檔的卡片組件爲個人app建立一個卡片模塊。這個卡片要支持移動端。

問題:在大屏幕上,我但願卡片是內聯的。卡片在同一水平線上的高度應該是相同的,儘管沒有在行上爲它們設置標記。「查看更多」按鈕應該始終位於卡片底部。

討論:咱們能夠看一下Flexbox模塊中的附加屬性。好比說用margin:auto智能的處理間距。

解決方法:Flexbox提供了一個使人難以置信的解決方案來解決一個龐大的CSS問題:高度相同。事實上,Flexbox很是靈活,它容許一行裏的卡片等高,儘管這組卡片沒有被包裹在一個div裏。它也容許「查看更多」出如今底部就像使用絕對定位放在了卡片的底部同樣。使用一個margin:auto就能夠了。

示例:(若是某些舊的瀏覽器不兼容就使用flex-wrap屬性。)

能夠在CodePen上看到Karen Menezes(@imohkay)作的示例Felxbox:卡片模型

結論

若是受衆是那些在智能手機上使用新版本瀏覽器的人,Flexbox多是最合適的混合web app。事實上,一些流行的前端框架也有使用Flexbox,包括ZURB的 Foundation for Apps(也能夠在GitHub上看到)和Ionic

若是你的應用程序只須要現代瀏覽器的支持,歡迎加入!使用像Autoprefixer這樣的工具,很容易過渡到flexbox多個版本和語法湯羹的世界裏。雖然Flexbox和float很搭配,它也能夠代替它作一些目前沒有其餘佈局模式能夠作到的佈局,包括內聯塊、表格顯示、絕對定位。「CSS網格佈局模塊」的目的是取代像相似float的解決方法和hack。但它如今正處於起步階段,只有不多的瀏覽器支持。在將來的某一天,我很願意想象咱們將所有使用CSS網格和Flexbox來構建更直觀的用戶界面,由於他們的發揮更好。

Flexbox須要一段時間才能讓你「啊哈!」,由於他涉及到要你忘記那些你已經知道的CSS佈局方式。一旦你講了一口流利的Flexbox語言,你設計響應式應用程序的過程將變得輕鬆,你的樣式表也將更加的簡潔。

擴展閱讀

本文根據@Karen Menezes的《Harnessing Flexbox For Today’s Web Apps》所譯,整個譯文帶有咱們本身的理解與思想,若是譯得很差或有不對之處還請同行朋友指點。如需轉載此譯文,需註明英文出處:http://www.smashingmagazine.com/2015/03/02/harnessing-flexbox-for-todays-web-apps/

相關文章
相關標籤/搜索