我們的 css flexbox 布局綜合指南。這份完整的指南解釋了有關(guān) flexbox 的所有內(nèi)容,重點介紹了父元素(flex 容器)和子元素(flex 項)的所有不同可能屬性。它還包括歷史、演示、模式和瀏覽器支持圖表。
彈性布局的誕生背景
(Flexbox LayoutFlexible Box)模塊(截至 2017 年 10 月的 W3C 候選推薦)旨在提供一種更有效的方式來布局、對齊和分配容器中項目之間的空間,即使它們的大小未知和/或動態(tài)(因此詞“彎曲”)。
flex 布局背后的主要思想是讓容器能夠改變其項目的寬度/高度(和順序)以最好地填充可用空間(主要是為了適應(yīng)各種顯示設(shè)備和屏幕尺寸)。彈性容器擴展項目以填充可用的可用空間或縮小它們以防止溢出。
最重要的是,與常規(guī)布局(基于垂直地塊和基于水平的內(nèi)聯(lián))相比,flexbox 布局與方向無關(guān)。雖然這些適用于頁面,但它們?nèi)狈`活性(不是雙關(guān)語)來支持大型或復(fù)雜的應(yīng)用程序(尤其是在涉及方向更改、調(diào)整大小、拉伸、收縮等方面)。
注意: Flexbox 布局最適合應(yīng)用程序的組件和小規(guī)模布局,而Grid布局適用于更大規(guī)模的布局。
基礎(chǔ)知識和術(shù)語
由于 flexbox 是一個完整的模塊而不是單個屬性,它涉及到很多東西,包括它的整個屬性集。其中一些是要設(shè)置在容器上(父元素,稱為“flex container”),而其他是要設(shè)置在子級(稱為“flex items”)上。
如果“常規(guī)”布局基于塊流方向和內(nèi)聯(lián)流方向,則彈性布局基于“彈性流方向”。請看一下規(guī)范中的這張圖,解釋了 flex 布局背后的主要思想。
解釋 flexbox 術(shù)語的圖表。 穿過flexbox主軸的尺寸稱為主尺寸,另一個方向是橫向尺寸。 這些尺寸有一個主開始、主結(jié)束、交叉開始和交叉結(jié)束。
項目將按照main axis(from main-startto main-end) 或橫軸 (from cross-startto cross-end) 排列。
- 主軸——彈性容器的主軸是彈性項目沿其布置的主軸。請注意,它不一定是水平的;這取決于flex-direction屬性(見下文)。
- 主啟動 | main-end – 彈性項目放置在容器內(nèi),從 main-start 開始到 main-end。
- 主尺寸——一個彈性項目的寬度或高度,無論是在主尺寸,還是項目的主要尺寸。彈性項目的主要尺寸屬性是“寬度”或“高度”屬性,以主要尺寸中的為準(zhǔn)。
- 交叉軸——垂直于主軸的軸稱為交叉軸。它的方向取決于主軸的方向。
- 交叉啟動| cross-end – 彈性線填充了項目,并從彈性容器的交叉開始側(cè)開始放置到容器中,并朝向交叉端側(cè)。
- cross size – 彈性項目的寬度或高度,以交叉維度為準(zhǔn),是項目的交叉大小。橫向尺寸屬性是橫向尺寸中的“寬度”或“高度”中的任何一個。
彈性盒屬性
父級 (彈性容器)的屬性
展示
這定義了一個彈性容器;內(nèi)聯(lián)或塊取決于給定的值。它為其所有直接子級啟用了彈性上下文。
.container {
display: flex; /* or inline-flex */
}
請注意,CSS 列對 flex 容器沒有影響。
彈性方向
這建立了主軸,從而定義了彈性項目放置在彈性容器中的方向。Flexbox 是(除了可選的包裝)一個單向布局的概念。將彈性項目視為主要以水平行或垂直列布局。
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row(默認):從左到右ltr;從右到左rtl
- row-reverse:從右到左ltr;從左到右rtl
- column: 相同,row但從上到下
- column-reverse: 相同,row-reverse但從下到上
彈性包裝
默認情況下,彈性項目都將嘗試適合一行。您可以更改它并允許使用此屬性根據(jù)需要包裝項目。
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
- nowrap(默認):所有彈性項目都將在一行
- wrap: flex 項目將從上到下包裹到多行。
- wrap-reverse: flex 項目將從下到上換行成多行。
彈性流動
這是flex-directionandflex-wrap屬性的簡寫,它們共同定義了 flex 容器的主軸和交叉軸。默認值為row nowrap。
.container {
flex-flow: column wrap;
}
證明內(nèi)容
這定義了沿主軸的對齊方式。當(dāng)一行上的所有 flex 項目都不靈活,或者是靈活的但已達到最大大小時,它有助于分配額外的可用空間。當(dāng)項目出行時,它還會對項目的對齊方式施加一些控制。
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}
- flex-start(默認):項目被打包朝向 flex-direction 的開始。
- flex-end: 項目被打包到 flex-direction 的末尾。
- start: 物品被包裝在方向的開始處writing-mode。
- end: 物品被包裝到方向的盡頭writing-mode。
- left: 物品被包裝在容器的左邊緣,除非這對 . 沒有意義,否則flex-direction它的行為就像start.
- right: 物品被包裝在容器的右邊緣,除非這對 . 沒有意義,否則flex-direction它的行為就像end.
- center:項目沿線居中
- space-between:物品均勻分布在行中;第一項在起始行,最后一項在結(jié)束行
- space-around:項目均勻分布在行中,周圍空間相等。請注意,視覺上的空間是不相等的,因為所有項目的兩邊都有相等的空間。第一個項目將在容器邊緣有一個空間單位,但下一個項目之間有兩個空間單位,因為下一個項目有自己的適用間距。
- space-evenly:項目分布使得任何兩個項目之間的間距(以及邊緣的空間)相等。
請注意,瀏覽器對這些值的支持是有細微差別的。例如,space-between某些版本的 Edge 從未獲得過支持,并且 Chrome 還沒有開始/結(jié)束/左/右。MDN有詳細的圖表。最安全的值是flex-start、flex-end和center。
還有兩個額外的關(guān)鍵字可以與這些值配對:safe和unsafe. 使用safe確保無論您如何進行這種類型的定位,您都不能推動一個元素,使其呈現(xiàn)在屏幕外(例如,離開頂部),這樣內(nèi)容也不能滾動(稱為“數(shù)據(jù)丟失”) .
對齊項目
這定義了彈性項目如何沿當(dāng)前行的交叉軸布局的默認行為。將其視為justify-content橫軸(垂直于主軸)的版本。
.container {
align-items: stretch | flex-start | flex-end | center | baseline | first baseline | last baseline | start | end | self-start | self-end + ... safe | unsafe;
}
- stretch(默認):拉伸以填充容器(仍然尊重最小寬度/最大寬度)
- flex-start// start:self-start項目放置在橫軸的開始處。這些之間的區(qū)別是微妙的,是關(guān)于尊重flex-direction規(guī)則或writing-mode規(guī)則的。
- flex-end// end:self-end項目放置在橫軸的末端。區(qū)別又是微妙的,是關(guān)于尊重flex-direction規(guī)則與writing-mode規(guī)則的。
- center:項目在橫軸上居中
- baseline:項目對齊,例如它們的基線對齊
和修飾符關(guān)鍵字可以與所有其他關(guān)鍵字一起使用(盡管注意safe瀏覽器支持),并幫助您防止對齊元素以使內(nèi)容變得不可訪問。unsafe
對齊內(nèi)容
當(dāng)橫軸上有額外空間時,這將對齊 flex 容器的線,類似于在justify-content主軸內(nèi)對齊單個項目的方式。
注意:該屬性只對多行靈活容器生效,這里flex-wrap設(shè)置為wrap或wrap-reverse)。單行靈活容器(即 whereflex-wrap設(shè)置為其默認值no-wrap)不會反映align-content.
.container {
align-content: flex-start | flex-end | center | space-between | space-around | space-evenly | stretch | start | end | baseline | first baseline | last baseline + ... safe | unsafe;
}
- normal(默認):項目被打包在它們的默認位置,就好像沒有設(shè)置值一樣。
- flex-start/ start:包裝到容器開頭的物品。(更受支持的)flex-start尊重,flex-direction而start尊重writing-mode方向。
- flex-end/ end:包裝到容器末端的物品。(更多支持)flex-end尊重,flex-direction而端尊重writing-mode方向。
- center:在容器中居中的項目
- space-between:項目均勻分布;第一行在容器的開頭,最后一行在結(jié)尾
- space-around:項目在每行周圍均勻分布
- space-evenly:項目均勻分布,周圍空間相等
- stretch: 線條伸展以占用剩余空間
和修飾符關(guān)鍵字可以與所有其他關(guān)鍵字一起使用(盡管注意safe瀏覽器支持),并幫助您防止對齊元素以使內(nèi)容變得不可訪問。unsafe
間隙、行間隙、列間隙
該gap屬性明確控制彈性項目之間的空間。它僅在不在外邊緣的項目之間應(yīng)用該間距。
.container {
display: flex;
...
gap: 10px;
gap: 10px 20px; /* row-gap column gap */
row-gap: 10px;
column-gap: 20px;
}
該行為可以被認為是最小排水溝,就好像排水溝以某種方式更大(因為類似justify-content: space-between;),那么只有當(dāng)該空間最終變得更小時,差距才會生效。
它不僅適用于 flexbox,也gap適用于網(wǎng)格和多列布局。
子項的屬性 (彈性項目)
命令
默認情況下,彈性項目按源順序排列。但是,該order屬性控制它們在彈性容器中出現(xiàn)的順序。
.item {
order: 5; /* default is 0 */
}
具有相同的項目order恢復(fù)到源訂單。
彈性成長
這定義了彈性項目在必要時增長的能力。它接受用作比例的無單位值。它規(guī)定了項目應(yīng)該占用的彈性容器內(nèi)的可用空間量。
如果所有項目都flex-grow設(shè)置為1,則容器中的剩余空間將平均分配給所有子項。如果其中一個孩子的值為2,則該孩子將占用其他孩子之一的兩倍空間(或者至少會嘗試)。
.item {
flex-grow: 4; /* default 0 */
}
負數(shù)無效。
彈性收縮
這定義了彈性項目在必要時收縮的能力。
.item {
flex-shrink: 3; /* default 1 */
}
負數(shù)無效。
彈性基礎(chǔ)
這定義了在分配剩余空間之前元素的默認大小。它可以是長度(例如 20%、5rem 等)或關(guān)鍵字。關(guān)鍵字的auto意思是“看看我的寬度或高度屬性”(這是由main-size關(guān)鍵字臨時完成的,直到被棄用)。關(guān)鍵字的content意思是“根據(jù)項目的內(nèi)容調(diào)整大小”——這個關(guān)鍵字還沒有得到很好的支持,所以很難測試,也很難知道它的兄弟max-content、、min-content和fit-content做什么。
.item {
flex-basis: | auto; /* default auto */
}
如果設(shè)置為0,則不考慮內(nèi)容周圍的額外空間。如果設(shè)置為auto,則根據(jù)其flex-grow值分配額外空間。請參閱此圖。
柔性
這是flex-grow, flex-shrink和flex-basis組合的簡寫。第二個和第三個參數(shù) (flex-shrink和flex-basis) 是可選的。默認值為0 1 auto,但如果您使用單個數(shù)值設(shè)置它,例如flex: 5;,則會將 更改flex-basis為 0%,所以它就像設(shè)置flex-grow: 5; flex-shrink: 1; flex-basis: 0%;。
.item {
flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}
建議您使用此速記屬性,而不是設(shè)置單個屬性。速記智能地設(shè)置其他值。
對齊自我
align-items這允許為單個彈性項目覆蓋默認對齊方式(或由 指定的對齊方式)。
請參閱align-items說明以了解可用值。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
請注意float,clear和vertical-align對彈性項目沒有影響。
為 Flexbox 添加前綴
Flexbox 需要一些供應(yīng)商前綴來支持盡可能多的瀏覽器。它不僅包括帶有供應(yīng)商前綴的屬性,而且實際上還有完全不同的屬性和值名稱。這是因為 Flexbox 規(guī)范隨著時間的推移發(fā)生了變化,創(chuàng)建了“舊”、“補間”和“新”版本。
也許處理這個問題的最好方法是編寫新的(也是最終的)語法并通過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);
}css
例子
讓我們從一個非常簡單的例子開始,解決一個幾乎每天都會遇到的問題:完美居中。如果你使用 flexbox,它再簡單不過了。
.parent {
display: flex;
height: 300px; /* Or whatever */
}
.child {
width: 100px; /* Or whatever */
height: 100px; /* Or whatever */
margin: auto; /* Magic! */
}
這依賴于auto彈性容器中設(shè)置的邊距吸收額外空間的事實。因此,設(shè)置邊距auto將使項目在兩個軸上完美居中。
現(xiàn)在讓我們使用更多的屬性。考慮一個包含 6 個項目的列表,所有項目都具有固定尺寸,但可以自動調(diào)整大小。我們希望它們在水平軸上均勻分布,這樣當(dāng)我們調(diào)整瀏覽器大小時,一切都可以很好地縮放,并且沒有媒體查詢。
.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;
}
完畢。其他一切都只是一些造型問題。
讓我們試試別的。想象一下,我們網(wǎng)站頂部有一個右對齊的導(dǎo)航元素,但我們希望它在中型屏幕上居中,在小型設(shè)備上為單列。很容易。
/* 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;
}
}
讓我們通過玩彈性項目的靈活性來嘗試更好的東西!帶有全寬頁眉和頁腳的移動優(yōu)先 3 列布局怎么樣?并且獨立于源順序。
.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; }
}
瀏覽器支持
此瀏覽器支持數(shù)據(jù)來自Caniuse,其中包含更多詳細信息。數(shù)字表示瀏覽器支持該版本及更高版本的功能。
錯誤
Flexbox 當(dāng)然也不是沒有缺陷。我見過的最好的集合是 Philip Walton 和 Greg Whitworth 的Flexbugs。這是一個跟蹤所有這些的開源地方,所以我認為最好只鏈接到它。