【譯】Flexbox完全指南
本人能力尚缺,經驗稍淺,翻譯中存在的不足之處望大家批評指正,以便及時更正。
Github: Duggud
文章描述的是CSS flexbox佈局綜合指南。該完全指南解釋了有關flexbox的所有內容,重點介紹了父元素(flex容器)和子元素(flex專案)的所有可能的不同屬性。它還包括歷史記錄,演示,模式和瀏覽器支援圖表。
背景
Flexbox佈局(靈活盒子)模組( 截至2017年10月的W3C候選推薦標準 )旨在提供一種更有效的方式來佈置,對齊和分配容器中專案之間的空間,即使它們的大小未知或是動態變化的( 這也是“flex”這個詞的由來)。
Flex佈局的主要思想是使容器能夠改變其專案的寬度、高度以及順序,以最好地填充可用空間(主要是為了適應所有型別的顯示裝置和螢幕尺寸)。Flex容器擴充套件專案以填充可用空間,或縮小它們以防止溢位。
最重要的是,與常規佈局(基於垂直的塊和基於水平的內聯塊)相反,flexbox佈局與方向無關。雖然前者適用於頁面,但它缺乏靈活性來支援大型或複雜的應用程式(特別是在方向更改,調整大小,拉伸,縮小等方面)。
注意:Flexbox佈局最適合應用程式的元件和小規模佈局,而Grid佈局則適用於更大規模的佈局。
基礎與術語

父的屬性(彈性容器)

display
這定義了一個flex容器;內聯或塊取決於給定的值。它為所有直接子專案提供了flex上下文。
<!--css--> .container { display: flex; /* or inline-flex */ } 複製程式碼
注意: CSS列對flex容器沒有影響。
order

屬性可以控制它們在Flex容器中的顯示順序。
flex-direction

這將建立主軸(main-axis),從而定義Flex專案放置在Flex容器中的方向。除了可選wrapping外,flexbox採用單向佈局概念。可以將flex項看作是水平行或垂直列的佈局。
<!--css--> .container { flex-direction: row | row-reverse | column | column-reverse; } 複製程式碼
- row (預設): ltr 表示從左至右; rtl 表示從右至左;
- row-reverse (反向行: rtl 表示從左至右; ltr 表示從右至左;
- column : 與 row 一樣,只是方向從上至下;
- column reserse : 與 row reserse 一樣,只是方向從下至上。
flex-wrap

預設情況下,flex專案都會嘗試在一行中自適應佈局。你可以根據需要利用此屬性更改它並允許專案進行換行。
<!--css--> .container{ flex-wrap: nowrap | wrap | wrap-reverse; } 複製程式碼
- nowrap : 所有的flex專案會在同一行;
- wrap : flex專案將從上到下被換行成多行;
- wrap-reverse :flex專案將從下到上被換行成多行;
更多視覺化 flex-wrap 例程可訪問 visual demos of flex-wrap here
flex-flow(適用於父flex元素)
這是一個簡寫的 flex-direction 和 flex-wrap 屬性,它們共同定義了flex容器的主軸(main-axis)和交叉軸(across-axis)。預設值為 row nowrap 。
<!--css--> flex-flow: <‘flex-direction’> || <‘flex-wrap’> 複製程式碼
flex-grow

設定為1,則容器中的剩餘空間將平均分配給所有子專案。如果其中一個子專案的值設為2,那麼將佔用兩倍於其他子專案的空間(或者至少會嘗試這樣做)。
<!--css--> .item { flex-grow: <number>; /* default 0 */ } 複製程式碼
flex-grow 設定為負值時無效。
flex-shrink
這定義了flex項在必要時收縮的能力。
<!--css--> .item { flex-shrink: <number>; /* default 1 */ } 複製程式碼
flex-shrink 設定為負值時無效。
flex-basis
這定義了剩餘空間分佈之前元素的預設大小。它可以是長度(例如20%,5rem等)或關鍵字。 auto 關鍵字的意思是“檢視我的寬度或高度屬性”(這是由 main-size 關鍵字臨時完成的,直到棄用)。 content 關鍵字的意思是“根據專案的內容調整大小”,這個關鍵字還沒有得到很好的支援,因此很難測試它,也很難知道它的兄弟屬性 max-content 、 min-content 和 fit-content 的功能。
<!--css--> .item { flex-basis: <length> | auto; /* default auto */ } 複製程式碼
如果設定為0,則不考慮內容周圍的額外空間。如果設定為auto,則根據其彈性增長值分佈額外的空間。點選檢視示例圖表。
flex
這是 flex-grow 、 flex-shrink 和 flex-basis 組合的簡寫。第二個和第三個引數( flex-shrink 和 flex-basis )是可選的。預設值是 0 1 auto 。
<!--css--> .item { flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ] } 複製程式碼
建議你使用這個簡寫屬性,而不是設定各個獨立屬性。簡寫可以智慧地設定其他值。
justify-content

這定義了沿主軸的對齊方式。當一行中的所有flex項無論是不靈活的,或者是靈活的但已經達到自身最大值時,它可以幫助分配剩餘的可用空間。此外,當flex專案溢位行時,它還對對齊方式進行了一些控制。
<!--css--> .container { justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly; } 複製程式碼
- flex-start : flex專案在行開始處緊密排列;
- flex-end :flex專案在行結尾處緊密排列;
- center :flex專案行居中排列;
- space-between :flex專案均勻分佈;第一項在起始行,最後一項在結束行;
- space-around :flex專案在行中均勻分佈,專案周圍的空間相等。注意,咋一看,空間是不相等的,因為 所有的項在兩邊都有相等的空間 。第一項在容器邊緣有一個單位的空間,但是與下一項之間有兩個單位的空間,因為下一項有它自身空間。
align-self

這允許為單個flex專案重置預設的對齊方式(或由align-items指定的對齊方式)。
請參閱 align-items 說明以瞭解可用的值。
<!--css--> .item { align-self: auto | flex-start | flex-end | center | baseline | stretch; } 複製程式碼
注意: float 、 clear 和 vertical-align 對flex項沒有影響。
align-items

這定義了flex項在當前行的cross- axis軸(c垂直於main-axis軸)上佈局的預設行為。可以將其視為justify-content作用於cross- axis軸的版本。
<!--css--> .container { align-items: stretch | flex-start | flex-end | center | baseline; } 複製程式碼
- stretch (default): 拉伸以填充容器(仍然遵循最小寬度/最大寬度)
- flex-start : flex專案的橫軸方向起始邊距(margin)邊緣位於橫軸起始行處;
- flex-end :flex專案的橫軸方向結束邊距(margin)邊緣位於橫軸結尾行處;
- center : flex專案沿橫軸居中對齊;
- baseline : flex專案根據 baseline 基線對齊;
align-content

當cross-axis軸存在額外空間時,這會對flex專案沿cross-axis軸進行行對齊,類似於 justify-content 沿main-axis軸對flex專案進行對齊。
注意:當只有flex專案只有一行時,此屬性不起作用。
<!--css--> .container { align-content: flex-start | flex-end | center | space-between | space-around | stretch; } 複製程式碼
- flex-start : 行於flex容器開始處緊密排列;
- flex-end : 行於flex容器末尾處緊密排列;
- center : 行於flex容器居中緊密排列;
- space-between : 行均勻分佈;第一行位於容器的開末尾頭,而最後一行位於容器的末尾;
- space-around :行均勻分佈,每行周圍的空間相等;
- stretch (default): 行伸展以佔據剩餘空間。
例子
讓我們以一個非常簡單的例子開始,解決一個幾乎每天都會遇到的問題:完美居中。如果您使用flexbox,它將變得不能更簡單。
<!--css--> .parent { display: flex; height: 300px; /* Or whatever */ } .child { width: 100px;/* Or whatever */ height: 100px; /* Or whatever */ margin: auto;/* Magic! */ } 複製程式碼
這取決於flex容器中設定為“ auto ”的 margin 會吸收額外的空間。因此,設定垂直邊距為 auto 將使專案完美地在兩個軸上居中排列。
現在讓我們新增更多的屬性。考慮一個包含6個專案的列表,它們的尺寸都是固定的,但是可以自動調整大小。我們希望它們均勻地分佈在橫軸上,以便在調整瀏覽器大小時一切正常(不使用媒體查詢!)。
<!--css--> .flex-container { /* We first create a flex layout context */ display: flex; /* Then we define the flow direction and if we allow the items to wrap * Remember this is the same as: * flex-direction: row; * flex-wrap: wrap; */ flex-flow: row wrap; /* Then we define how is distributed the remaining space */ justify-content: space-around; } 複製程式碼
Done.其他都只是一些樣式問題。下面是一個測試例程。請訪問CodePen,試著調整視窗大小,看看會發生什麼。
我們試下別的例子。想象一下,我們的網站頂部有一個靠右對齊的導航,但我們希望它中型螢幕上居中,在小型裝置上則呈現為單列導航。這也足夠簡單。
<!--css--> /* 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; } } 複製程式碼
讓我們使用flex專案的靈活性來做更好的實現!比如移動優先的3列布局,具有全寬度的頁首和頁尾。與源順序無關。
<!--css--> .wrapper { display: flex; flex-flow: row wrap; } /* We tell all items to be 100% width, via flex-basis */ .wrapper > * { flex: 1 100%; } /* We rely on source order for mobile-first approach * in this case: * 1. header * 2. article * 3. aside 1 * 4. aside 2 * 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需要一些供應商的字首來支援儘可能多的瀏覽器。它不僅包括帶有供應商字首的前置屬性,實際上還有完全不同的屬性和值名稱。這是因為隨著時間的推移,Flexbox規範已經發生了變化,建立了 "old", "tweener", and "new" 版本。
或許處理這個問題的最好方法是使用新的(也是最終的)語法,並通過Autoprefixer執行CSS, Autoprefixer可以很好地處理回退。
另外,這裡有一個Sass @mixin來幫助新增一些字首,這也讓你知曉需要處理的事情:
<!--scss--> @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); } 複製程式碼
相關屬性
其他資源
- Flexbox in the CSS specifications
- Flexbox at MDN
- Flexbox at Opera
- Diving into Flexbox by Bocoup
- Mixing syntaxes for best browser support on CSS-Tricks
- Flexbox by Raphael Goetter (FR)
- Flexplorer by Bennett Feely
Bugs
Flexbox當然也有bugs。我見過的最好bugs收集是Philip Walton和Greg Whitworth的 Flexbugs 。它是開源的,你可以跟蹤所有的資料,所以我認為最好檢視一下。