【轉】深入瞭解 Flexbox 伸縮盒模型

來源:互聯網
上載者:User

標籤:

Flexbox(伸縮布局盒) 是 CSS3 中一個新的配置模式,為了現代網路中更為複雜的網頁需求而設計。本文將介紹 Flexbox 文法的技術細節。瀏覽器的支援越來越快,所以當 Flexbox 被廣泛支援並應用時你將會快人一步。如果你想知道它是什麼並是如何工作的,不妨仔細瞭解下吧!

 

為什麼需要伸縮布局盒(Flexbox)?

作者長期以來使用表格、浮動、行內塊元素和其他 CSS 屬性來布局網站內容。然而,這些並不是為複雜的頁面和網頁應用而設計的。不管是簡單的垂直置中,還是靈活的網格布局都很難靠一己之力輕易實現,因此成就了 CSS 網格架構。但是,如果真的需要那麼多項目來實現做這些事,為什麼不讓它來的更簡單些呢?Flexbox 的目的就是改變這一切。

規範狀態和瀏覽器支援情況

Flexbox 規範的相關工作已經進展了3年。不同的瀏覽器也實現了不同的實驗版本。在2012年9月,Flexbox 文法的第三個主要修訂版本進入到候選推薦階段。這意味著 W3C 認為當前的文法是穩定的,並鼓勵瀏覽器開發商去實現它。

Flexbox 規範時間表:

  • 2009年7月 工作草案 (display: box;)
  • 2011年3月 工作草案 (display: flexbox;)
  • 2011年11月 工作草案 (display: flexbox;)
  • 2012年3月 工作草案 (display: flexbox;)
  • 2012年6月 工作草案 (display: flex;)
  • 2012年9月 候選推薦 (display: flex;)

Flexbox 已經被瀏覽器快速支援。Chrome 22+, Opera 12.1+, 和 Opera Mobile 12.1+ 已經支援了本文中所描述的 Flexbox。Firefox 18 和 Blackberry 10 也很快就會實現。我推薦大家使用已經支援的瀏覽器來閱讀本文和查看例子。

概念和術語

雖然現在我們可以使用 Flexbox 輕鬆建立布局,而不會像以前那樣難以理解,但我們仍然需要花一些時間去熟悉到底如何使用 Flexbox。新的術語和概念可能會是我們使用 Flexbox 時的一個障礙,所以讓我們先來瞭解以下它們。

Flexbox 由 伸縮容器 和 伸縮項目 組成。通過設定元素的 display 屬性為 flex 或 inline-flex 可以得到一個伸縮容器。設定為 flex 的容器被渲染為一個區塊層級元素,而設定為 inline-flex 的容器則渲染為一個行內元素。

這裡的樣本建立了一個伸縮容器。

.flex-container {display: -webkit-flex;display: flex;}

本文中所有的樣本都會帶有相應的瀏覽器廠商首碼。

伸縮容器中的每一個子項目都是一個伸縮項目。伸縮項目可以是任意數量的。伸縮容器外和伸縮項目內的一切元素都不受影響。簡單地說,Flexbox 定義了伸縮容器內伸縮項目該如何布局。

Flex Lines 伸縮行

伸縮項目沿著伸縮容器內的一個 伸縮行 定位。通常每個伸縮容器只有一個伸縮行。

這個樣本展示了2個項目在預設情況下的定位:沿著一個水平伸縮行從左至右顯示。

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><style type="text/css">.flex-container {    display: -webkit-flex;    display: flex;    width: 300px;    height: 240px;    background-color: Silver;}.flex-item {    background-color: DeepSkyBlue;    width: 100px;    height: 100px;    margin: 5px;}</style><body><div class="flex-container"><div class="flex-item">flex item 1</div><div class="flex-item">flex item 2</div></div></body></html>

Writing Modes 書寫入模式

在你設計 Flexbox 時的有一個重要的部分是更改伸縮行的方向。預設情況下,伸縮行和文本方向一致:從左至右,從上往下。

這是 W3C 關於一個名為書寫入模式的新特性工作草稿。書寫入模式是一個新的方法,讓你可以從右往左寫,甚至豎著寫,就像你知道的某些語言一樣。

書寫入模式是一個進行中的計劃,但是 Chrome 已經率先支援了 direction CSS 屬性。如果我們在上一個例子中設定方向為rtl (從右往左) 那麼不僅僅文字會從右往左書寫,而且 伸縮行也改變了方向,並更改了頁面的布局。

這也許就是 Flexbox 為什麼如此抽象難懂的地方。當你正在製作一個語言不確定的頁面時你不能簡單的只是說“上”、“下”、“左”、“右”。

The Main Axis and the Cross Axis 主軸和側軸

為了描述抽象的書寫入模式,Flexbox 使用 主軸 和 側軸的概念。伸縮行跟隨主軸。側軸則垂直於主軸。

起點、終點和各軸的方向的名稱如下:

  • 主軸起點 Main Start
  • 主軸終點 Main End
  • 主軸方向 Main Direction (有時候也成為伸縮流方向 Flow Direction)
  • 側軸起點 Cross Start
  • 側軸終點 Cross End
  • 側軸方向 Cross Direction

在繼續瞭解之前明白主軸和側軸是至關重要的。Flexbox 中的一切都和這些軸有關。在我們所有的例子中,書寫入模式都是從左至右,從上到下,但是你需要記住並不是所有的 Flexbox 都是這樣的。

伸縮容器的屬性flex-direction 伸縮流的方向

flex-direction 允許你更改伸縮容器的主軸方向。flex-direction 的預設值是 row。該值表示伸縮項目根據書寫入模式的方向布局。再次提醒,預設是從左至右,從上到下。其他的值如下:

  • row-reverse: 主軸起點和主軸終點交換。如果書寫入模式是從左至右,伸縮項目則是從右往左顯示。
  • column: 主軸和側軸交換。如果書寫系統是垂直的,那麼伸縮項目也是垂直顯示的。
  • column-reverse: 和 column 一樣,但是方向相反。

讓我們把前一個樣本中的 flex-direction 改為 column

現在我們的伸縮項目就是垂直顯示的了。

justify-content 主軸對齊

伸縮容器的 justify-content 屬性用於調整主軸上伸縮項目的位置。可能的值為:

  • flex-start (預設)
  • flex-end
  • center
  • space-between
  • space-around

這裡我們設定 justify-content 為 center 讓伸縮項目在主軸上置中對齊:

flex-startflex-end, 和 center 一看就懂。space-between 和 space-around 則是分配伸縮項目之間空白空間的不同方法。這張規範中的圖示很好的解釋了一切:

align-items 側軸對齊

align-items 是一個和 justify-content 相呼應的屬性。align-items 調整伸縮項目在側軸上的定位方式。可能的值有:

  • flex-start (預設)
  • flex-end
  • center
  • baseline
  • stretch

這裡我們設定 align-items 為 center 讓伸縮項目在側軸上置中對齊:

和之前一樣,flex-startflex-end, 和 center 的意義顯而易見。stretch 也很簡單:它會將伸縮項目從側軸起點展開到側軸終點。baseline 則是讓伸縮項目與它們的基準對齊。基準根據伸縮項目的內容計算得到。下面這張來自W3C標準的圖例很好的解釋了這些屬性:

flex-wrap 伸縮行換行

目前為止,每個伸縮容器都有且只有一個伸縮行。使用 flex-wrap 你可以為伸縮容器建立多個伸縮行。這個屬性接受以下值:

  • nowrap (預設)
  • wrap
  • wrap-reverse

如果 flex-wrap 設定為 wrap,在一個伸縮行容不下所有伸縮項目時,伸縮項目會換行到一條新增的伸縮行上。新增的伸縮行根據側軸的方向添加。

我們使用 flex-wrap 來看個例子:

wrap-reverse 和 wrap 一樣,只是新的伸縮行會被添加到側軸的反方向上。

align-content 堆棧伸縮行

align-content 會更改 flex-wrap 的行為。它和 align-items 相似,但是不是對齊伸縮項目,它對齊的是伸縮行。可能你已經想到了,它接受的值也很相似:

  • stretch (預設)
  • flex-start
  • flex-end
  • center
  • space-between
  • space-around

這些值與 justify-content 和 align-items 中的值一樣。

在這個例子中,我們設定 align-content 為 center

flex-flow 伸縮方向與換行

flex-flow 是 flex-direction 和 flex-wrap 的縮寫。

flex-flow: [flex-direction] [flex-wrap]

舉個例子:

 

1 2 3 4 .flex-container {-webkit-flex-flow: column nowrap;flex-flow: column nowrap;}
view rawgistfile1.cssThis Gist brought to you by GitHub.

 

伸縮項目的屬性

一個伸縮項目是一個伸縮容器的子項目。伸縮容器中的文本也被視為一個伸縮項目。

伸縮項目中內容與普通流一樣。舉例來說,當一個伸縮項目被設定為浮動,你依然可以在這個伸縮項目中放置一個浮動元素。

伸縮項目都有一個 主軸長度(Main Size) 和一個 側軸長度(Cross Size)。主軸長度是伸縮項目在主軸上的尺寸。側軸長度是伸縮項目在側軸上的尺寸。或者說,一個伸縮項目的寬或高取決於伸縮容器的軸,可能就是它的主軸長度或側軸長度。

下面的屬性可以調整伸縮項目的行為:

order 顯示順序

order 是最簡單明了的屬性。設定伸縮項目的 order 可以調整它們渲染時的順序。在這個例子中,我們設定其中一個伸縮項目的order 為 -1,於是它被提前到了其他伸縮項目的最前面。

如果需要文檔順序和顯示順序不同時,這就是個很有用的功能了。

margin 外邊距

你應該對 margin: auto; 的這種用法很熟悉。在伸縮盒中,它也能做同樣的事情,但是更加強大。一個 "auto" 的 margin 會合并剩餘的空間。它可以用來把伸縮項目擠到其他位置。

這裡我們在第一個伸縮項目上聲明了 margin-right: auto;,導致了所有的剩餘空間被合并到那個元素的右邊去了:

這裡我們使用 margin: auto; 來重現經典CSS布局中的聖杯:真·垂直置中:

align-self 側軸對齊

伸縮項目的 align-self 屬性會覆蓋該項目的伸縮容器的 align-items 屬性。它的值和 align-items 一樣:

  • stretch (預設)
  • flex-start
  • flex-end
  • center
  • baseline

在這個例子中我們為每個伸縮項目應用了不同的 align-self 值:

我在例子中包含了2個基準對齊的伸縮項目,因為它們的對齊需要互相作用。

flex 伸縮性

現在我們終於要開始設定伸縮盒的伸縮性了。flex 指定了一個伸縮項目該如何分配主軸上的剩餘空間。

讓我們一次把所有的常見值都看一遍吧。

flex: [number]

這個文法指定了一個數字,代表了這個伸縮項目該佔用的剩餘空間比例。

在這個例子中,第一個伸縮項目佔用了 2/4 的剩餘空間,而另外兩個各佔用了 1/4 的剩餘空間。

如果把每個伸縮項目都設定為 1 的話,那麼剩餘空間就會被平均分配了。

flex: initial

一個 flex 屬性值被設為 initial 的伸縮項目,在有剩餘空間的情況下不會有任何變化,但是在必要的情況下會被收縮。

flex: auto

一個 flex 屬性值被設為 auto 的伸縮項目,會根據主軸自動調整以佔用所有剩餘空間。

auto 目前僅在 Opera 12.11 尚有效,在 Chrome 23.0.1271.95 上無效。你可以通過使用 flex: 1; 來達到一樣的效果。

flex: none

一個 flex 屬性值被設為 none 的伸縮項目,在任何情況都不會發生伸縮。

flex 縮寫

flex 也可以把 flex-growflex-shrink, 和 flex-basis 這3個縮寫為1個聲明:

flex: [flex-grow] [flex-shrink] [flex-basis]

大多數情況下沒必要使用這種文法。另外,它需要一個更容易理解的伸縮演算法。如果你覺得自己挺厲害的,到規範裡看一下吧。

當然你也可以將 flex-growflex-shrink, 和 flex-basis 作為單個屬性分開來設定。但我強烈反對這種方式:當使用flex 縮寫時,即使沒有某些值沒有設定也能獲得更合理的預設值。

visibility 疊加項目

當該值生效時,應用 visibility: collapse; 和 visibility: hidden; 與 display: none; 的效果是不一樣的。如果是 collapse,該元素會影響伸縮容器的側軸長度,但不會被現實或佔用主軸的空間。如果你想動態添加或移除伸縮項目又不會影響伸縮容器的側軸長度,這將會非常有用。

目前為止,visibility: collapse; 還沒有被讓任何瀏覽器正確的實現。現在 visibility: collapse; 還和visibility: hidden; 實現著一樣的效果。我希望能儘快得到改觀。

你可以在 這裡 看到 collapse 應該是如何工作的。

總結

如你所見,伸縮布局盒(Flexbox) 是一個強大的新型配置模式,將會給網站帶來革命性的布局方法,但它也需要一種全新的思考方式。希望這篇文章能為你使用伸縮布局盒構建網站帶來協助。我不知道你怎麼想,但是在我看來未來是美好的。

原文:Dive into Flexbox (http://weblog.bocoup.com/dive-into-flexbox)
參考資料:Css3-flexbox (http://www.w3.org/html/ig/zh/wiki/Css3-flexbox)

轉自:[譯]深入瞭解 Flexbox 伸縮盒模型:http://c7sky.com/dive-into-flexbox.html

【轉】深入瞭解 Flexbox 伸縮盒模型

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.