轉載請標註本文連接並附帶如下信息: 譯:Cydiacen 做者:CHRIS COYIER 原文:A Complete Guide to Flexbox 原文更新於 2016-11-19css
出於提高自身英語水平和鞏固FlexBox的知識,因而打算翻譯一篇比較知名的FlexBox佈局的文章,固然這篇文章以前網上已有大漠
的譯文,這次翻譯也有部分參考大漠
譯文的內容,因而在此貼上大漠
譯文的地址,以此致敬大佬。《一個完整的Flexbox指南》html
爲了避免浪費你們時間,先說明下flexBox如今的兼容狀況:css3
display:flex;
)display:flexbox;
)display:box;
)Chorme | Safari | Firefox | Opera | IE | Android | IOS |
---|---|---|---|---|---|---|
20- (old) | 3.1+ (old) | 2-21 (old) | 12.1+ (new) | 10 (tweener) | 2.1+ (old) | 3.2+ (old) |
21+ (new) | 6.1+ (new) | 22+ (new) | 11+ (new) | 4.4+ (new) | 7.1+ (new) |
黑莓瀏覽器 10+ 支持新語法。git
關於怎麼樣混合語法能夠獲得更好的瀏覽器支持的信息,能夠跳轉到《CSS-Tricks》或者《DevOpera》。github
Flexbox(彈性盒子)佈局模式(目前是個W3C規範草案)旨在爲佈局,對齊和分佈容器內的子項提供一種更加高效的方式,即便這些玩意兒的大小是未知的或者動態變化的。(正如他的名字所示——Flex,彈性的意思)web
Flex佈局背後的主要思想是——給指定的容器提供修改其子項的寬、高乃至順序的能力,而且足夠完美的去填充可用的空間(主要是爲了適應各類各樣的顯示設備和屏幕大小)。瀏覽器
一個使用了Flex佈局的容器,將會擴展其子項以致於填充起可用的空間,或者縮小他們以防止溢出容器。app
有一個至關重要的一點,FlexBox佈局的方向不像常規佈局(塊就是垂直從上到下,行就是水平從左到右),它是不可預知方向的。而那些常規的適合頁面佈局,但對於做用在大型或者複雜的應用程序(特別是當他涉及到方向改變、大小變化、拉伸和收縮等)就缺少靈活性。ide
注意: FlexBox佈局最適用於應用程序的組件和小規模佈局,而網格佈局更適用於大規模的佈局。佈局
由於FlexBox是一整個模塊並非一個單獨的屬性,它涉及到不少東西包括它的全部設置屬性。一些屬性是須要被設置在容器(父級元素,稱爲『彈性容器』),而一些其餘的屬性須要被設置在子元素(稱爲『彈性項』)中。
若是常規佈局是基於塊佈局與內聯佈局的方向流的,那麼彈性佈局就是基於「flex-flow流」。請看一下來自W3C規範的這張圖,它解釋了彈性佈局的主要思想。
基本上,彈性項(flex item)會沿着主軸方向(main-start
到main-end
)或側軸方向(cross-start
到cross-end
)排列。
main axis
) - 彈性項主要是沿着彈性容器的主軸進行排列的。要注意一點,他不必定是水平的;這主要仍是看flex-direction
屬性(見下文)。main-start | main-end
- 彈性項將由main-start
到main-end
方向放置在容器內。main size
- 彈性項在主軸方向的寬度或高度就是主軸的尺寸。彈性項主要的大小屬性能夠是寬度,也能夠是高度屬性,由哪個對着主軸方向決定。cross axis
- 與主軸垂直相交的軸線就是側軸。它的方向由主軸決定。cross-start | cross-end
- 彈性行是由彈性項填充起來的,它的配置是從容器的cross-start
開始,往cross-end
結束。cross size
- 彈性項在側軸方向的寬度或高度就是cross size
。cross size
根據側軸的方向來取決是寬度仍是高度。這個屬性是定義在彈性容器上的;根據其值決定是內聯仍是塊佈局。這時它的直屬下級將會變成flex文檔流。
.container { display: flex; /* or inline-flex */ }
須要注意CSS的columns在flex容器裏沒有效果。
這個是創建在主軸上的,從而定義了彈性項放置在容器的方向。FlexBox是單方向的佈局概念。能夠將彈性項視爲主要佈置在水平行或垂直列中。
.container { flex-direction: row | row-reverse | column | column-reverse; }
row
(默認):在ltr
排版方式下從左向右排列;在rtl
排版方式下從右向左排列。row-reverse
:與row
排列方向相反,在ltr
排版方式下從右向左排列;在rtl
排版方式下從左向右排列。column
:相似於row
可是是頂部到底部column-reverse
:相似於row-reverse
可是是底部到頂部彈性項默認會所有集中在一行。你可使用這個屬性來改變這種狀況,讓他們根據你的須要進行自動換行。文檔方向在這裏也起做用,決定了新的一行被堆疊的方向。
.container{ flex-wrap: nowrap | wrap | wrap-reverse; }
nowrap
(默認):單行顯示。在ltr
排版下,項目自左向右;在rtl
下,自右向左wrap
:多行顯示。在ltr
排版下,項目自左向右;在rtl
下,自右向左wrap-reverse
:多行顯示。與wrap
相反這個是flex-direction
和flex-wrap
屬性的縮寫版,它同時定義了彈性容器的主軸和側軸。默認是row nowrap
。
flex-flow: <‘flex-direction’> || <‘flex-wrap’>
這屬性是用來定義主軸上的對齊方式的。當全部的彈性項在一行而且沒法彈性伸展,或者可伸展可是達到了最大尺寸,它能幫助分配剩下的多餘空間。而且當他們行內溢出時,這個屬性也能夠對項目對齊施加一些控制。
.container { justify-content: flex-start | flex-end | center | space-between | space-around; }
flex-start
(默認):子項會從一行的起始處開始放置flex-end
:子項會從一行的結尾處開始放置center
:子項會集中在一行的中央space-between
:子項會被均勻的分佈在行內;首項放置在一行的開始,尾項放置在一行的結束space-around
:子項會均勻的按照同等距離分佈在一行。須要注意的是,在視覺上會以爲並不等距,由於全部子項在兩側都須要加上同等的空間。首項會與容器開始邊緣有一個單位空間的距離,可是與下一項會有兩個單位空間的距離,由於下一項也有它本身的適配空間。這用來定義彈性項目在彈性容器的當前側軸上的默認行爲。能夠認爲是側軸版的justity-content
。
.container { align-items: flex-start | flex-end | center | baseline | stretch; }
flex-start
:彈性項在側軸起點邊的外邊距緊靠住該行在側軸起始的邊。flex-end
:彈性項在側軸起點邊的外邊距緊靠改行在側軸結尾的邊。center
:彈性項會被放置在側軸的中央。baseline
:彈性項會根據他們的基線對齊。stretch
(默認):在側軸方向上拉伸彈性項以至填充滿彈性容器。(任聽從min-width/max-width
)這個屬性會根據在側軸上的額外空間來排列容器的行,相似於justify-content
在主軸在對齊單個彈性項的方式。
注意,這個屬性對於只有單行的彈性項來講是沒有效果的。
.container { align-content: flex-start | flex-end | center | space-between | space-around | stretch; }
flex-start
:行會緊靠容器的起始位flex-end
:行緊靠容器的結束位center
:行緊靠容器的中間位space-between
:每行會均勻分佈;首行在容器起始處而最後行在容器結束處space-around
:每行根據相同的距離均勻的分佈stretch
(默認):每行將會伸展以佔用剩餘的空間。通常來講,彈性項會按照文檔流的順序進行佈局。然而,order
屬性能夠控制他們出如今彈性容器中的順序。
.item { order: <integer>; }
這個屬性給予彈性項在須要的時候能夠伸展的能力。它接收一個不帶單位的值做爲比例。它規定了在容器內的彈性項能夠佔用多少的可用空間。
若是全部的子項都設置了flex-grow
爲1,那麼容器內的剩餘空間會被均勻的分配給全部自項。若是其中一項的值爲2,那麼這項的佔用空間會是其餘項的兩倍。
.item { flex-grow: <number>; /* default 0 */ }
設置負數是無效的。
這定義了彈性項在須要的時候具備伸展的能力。
.item { flex-shrink: <number>; /* default 1 */ }
負數是無效的。
這定義了,當一個元素在被分配到剩餘空間以前的默認大小。它能夠是一個長度(如:20%,5rem等)或者一個關鍵字。auto
關鍵字的意思就是『按照個人寬度和高度屬性調整尺寸』(他會暫時根據main-size
來佈局大小直到被棄用)。若是使用關鍵字content
,意思就是『基於內容調整大小』——不過這個關鍵字並必定能很好的工做,所以很難去測試或者知曉它的兄弟們max-content
,min-content
和fit-content
作了什麼。
.item { flex-basis: <length> | auto; /* default auto */ }
若是設置爲0,額外空間內容不會被分解開來。若是設置成auto
,額外空間會基於它的flex-grow
的值進行分佈。
這是flex-grow
,flex-shrink
和flex-basis
組合縮寫版。第二個和第三個參數(flex-shrink
和flex-basis
)是可選的。默認是0 1 auto
。
推薦你使用的這種縮寫屬性,這比設置單獨屬性更好。能夠智能的經過縮寫形式設置值。
用來在單獨的伸縮項目上覆寫默認的對齊方式。
請看下align-items
的解釋,幫助你瞭解可用值。
.item { align-self: auto | flex-start | flex-end | center | baseline | stretch; }
注意,float
,clear
和vertical-align
在彈性項中會失效。
讓咱們從一個很是很是簡單的例子開始,解決一個很是平常的問題:完美居中。若是你使用flexBox
佈局,這將會變得很是簡單。
.parent { display: flex; height: 300px; /* Or whatever */ } .child { width: 100px; /* Or whatever */ height: 100px; /* Or whatever */ margin: auto; /* Magic! */ }
這個依賴於設置margin
值爲auto
值,會自動獲取彈性容器的額外空間。所以設置垂直方向margin
爲auto
可讓彈性項完美的居中在兩個軸。
如今讓咱們使用下一些其餘屬性。
考慮使用一個包含六個項的列表,而且爲了視覺審美給他設置了一個固定大小尺寸,但他們也有可能能夠自動獲取尺寸大小。咱們想要他們能夠均勻的,而且完美分佈在水平軸上,而且當我改變瀏覽器的大小,他們仍是能夠很好的展現(不須要引用媒體查詢!)。
.flex-container { /* 咱們先建立一個彈性佈局環境*/ display: flex; /* 而後若是咱們容許子項換行能夠定義flow-direction * 記住這相等於: * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /* 而後咱們再定義怎麼樣分佈剩餘的空間 */ justify-content: space-around; }
完工。其餘的一切不過是美化樣式。下面提供一些html,css代碼,能夠在codePen
調試而且改變下瀏覽器的大小看看會發生什麼。
codePen
<ul class="flex-container"> <li class="flex-item">1</li> <li class="flex-item">2</li> <li class="flex-item">3</li> <li class="flex-item">4</li> <li class="flex-item">5</li> <li class="flex-item">6</li> </ul>
SASS:
@import "compass/css3"; .flex-container { padding: 0; margin: 0; list-style: none; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-flex-flow: row wrap; justify-content: space-around; } .flex-item { background: tomato; padding: 5px; width: 200px; height: 150px; margin-top: 10px; line-height: 150px; color: white; font-weight: bold; font-size: 3em; text-align: center; }
讓咱們再嘗試下其餘東西。想象下,咱們的網站全部頁面頭部都有個右對齊佈局的導航,可是咱們想讓他在中等大小的屏幕中居中顯示而且在小屏幕設備中單行顯示。很是簡單。
/* Large */ .navigation { display: flex; flex-flow: row wrap; /* This aligns items to the end line on main-axis */ justify-content: flex-end; } /* Medium screens */ @media all and (max-width: 800px) { .navigation { /* When on medium sized screens, we center it by evenly distributing empty space around items */ justify-content: space-around; } } /* Small screens */ @media all and (max-width: 500px) { .navigation { /* On small screens, we are no longer using row direction but column */ flex-direction: column; } }
讓咱們再來試試一些更加靈活性的彈性項!關於移動先行,3列布局與頁眉頁腳全屏。和獨立的文檔順序。
.wrapper { display: flex; flex-flow: row wrap; } /* We tell all items to be 100% width */ .header, .main, .nav, .aside, .footer { flex: 1 100%; } /* We rely on source order for mobile-first approach * in this case: * 1. header * 2. nav * 3. main * 4. aside * 5. footer */ /* Medium screens */ @media all and (min-width: 600px) { /* We tell both sidebars to share a row */ .aside { flex: 1 auto; } } /* Large screens */ @media all and (min-width: 800px) { /* We invert order of first sidebar and main * And tell the main element to take twice as much width as the other two sidebars */ .main { flex: 2 0px; } .aside-1 { order: 1; } .main { order: 2; } .aside-2 { order: 3; } .footer { order: 4; } }
Flexbox
接受一些運營商前綴以支持能夠在更多的瀏覽器上使用。它不只只包括在屬性前添加前綴,它也有徹底不一樣的屬性名字和值名字。這是由於Flexbox
規範隨着時間一直在變化,所以有了old
,tweener
和new
版本。
固然最好的方式是使用最新的語法,而且經過Autoprefixer運行你的css。
這有一段Sass @mixin
可供選擇,他也能夠給你提供一些須要怎樣處理的想法,幫助你處理一些前綴問題。
@mixin flexbox() { display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; } @mixin flex($values) { -webkit-box-flex: $values; -moz-box-flex: $values; -webkit-flex: $values; -ms-flex: $values; flex: $values; } @mixin order($val) { -webkit-box-ordinal-group: $val; -moz-box-ordinal-group: $val; -ms-flex-order: $val; -webkit-order: $val; order: $val; } .wrapper { @include flexbox(); } .item { @include flex(1 200px); @include order(2); }
Grid 屬性的年度條目,好比 grid-row/grid-column
Flex固然不是沒有bug,我見過的關於這些bug收集最好的是Philip Walton
和 Greg Whitworth
的FlexBugs。