我們的 CSS flexbox 布局綜合指南袱瓮。這份完整的指南解釋了有關(guān) flexbox 的所有內(nèi)容侦啸,重點(diǎn)介紹了父元素(flex 容器)和子元素(flex 項(xiàng))的所有不同可能屬性归斤。它還包括歷史、演示按厘、模式和瀏覽器支持圖表抵恋。
彈性布局的誕生背景
(Flexbox LayoutFlexible Box)模塊(截至 2017 年 10 月的 W3C 候選推薦)旨在提供一種更有效的方式來布局、對齊和分配容器中項(xiàng)目之間的空間挠日,即使它們的大小未知和/或動態(tài)(因此詞“彎曲”)疮绷。
flex 布局背后的主要思想是讓容器能夠改變其項(xiàng)目的寬度/高度(和順序)以最好地填充可用空間(主要是為了適應(yīng)各種顯示設(shè)備和屏幕尺寸)。彈性容器擴(kuò)展項(xiàng)目以填充可用的可用空間或縮小它們以防止溢出肆资。
最重要的是矗愧,與常規(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é)束金矛。
項(xiàng)目將按照main axis(from main-startto main-end) 或橫軸 (from cross-startto cross-end) 排列。
- 主軸——彈性容器的主軸是彈性項(xiàng)目沿其布置的主軸倘潜。請注意绷柒,它不一定是水平的;這取決于flex-direction屬性(見下文)涮因。
- 主啟動 | main-end – 彈性項(xiàng)目放置在容器內(nèi)废睦,從 main-start 開始到 main-end。
- 主尺寸——一個彈性項(xiàng)目的寬度或高度养泡,無論是在主尺寸嗜湃,還是項(xiàng)目的主要尺寸。彈性項(xiàng)目的主要尺寸屬性是“寬度”或“高度”屬性澜掩,以主要尺寸中的為準(zhǔn)购披。
- 交叉軸——垂直于主軸的軸稱為交叉軸。它的方向取決于主軸的方向肩榕。
- 交叉啟動| cross-end – 彈性線填充了項(xiàng)目刚陡,并從彈性容器的交叉開始側(cè)開始放置到容器中,并朝向交叉端側(cè)株汉。
- cross size – 彈性項(xiàng)目的寬度或高度筐乳,以交叉維度為準(zhǔn),是項(xiàng)目的交叉大小乔妈。橫向尺寸屬性是橫向尺寸中的“寬度”或“高度”中的任何一個蝙云。
彈性盒屬性
父級 (彈性容器)的屬性
展示
這定義了一個彈性容器;內(nèi)聯(lián)或塊取決于給定的值路召。它為其所有直接子級啟用了彈性上下文勃刨。
.container {
display: flex; /* or inline-flex */
}
請注意波材,CSS 列對 flex 容器沒有影響。
彈性方向
這建立了主軸身隐,從而定義了彈性項(xiàng)目放置在彈性容器中的方向廷区。Flexbox 是(除了可選的包裝)一個單向布局的概念。將彈性項(xiàng)目視為主要以水平行或垂直列布局抡医。
.container {
flex-direction: row | row-reverse | column | column-reverse;
}
- row(默認(rèn)):從左到右ltr躲因;從右到左rtl
- row-reverse:從右到左ltr;從左到右rtl
- column: 相同忌傻,row但從上到下
- column-reverse: 相同,row-reverse但從下到上
彈性包裝
默認(rèn)情況下搞监,彈性項(xiàng)目都將嘗試適合一行水孩。您可以更改它并允許使用此屬性根據(jù)需要包裝項(xiàng)目。
.container {
flex-wrap: nowrap | wrap | wrap-reverse;
}
- nowrap(默認(rèn)):所有彈性項(xiàng)目都將在一行
- wrap: flex 項(xiàng)目將從上到下包裹到多行琐驴。
- wrap-reverse: flex 項(xiàng)目將從下到上換行成多行俘种。
彈性流動
這是flex-directionandflex-wrap屬性的簡寫,它們共同定義了 flex 容器的主軸和交叉軸绝淡。默認(rèn)值為row nowrap宙刘。
.container {
flex-flow: column wrap;
}
證明內(nèi)容
這定義了沿主軸的對齊方式。當(dāng)一行上的所有 flex 項(xiàng)目都不靈活牢酵,或者是靈活的但已達(dá)到最大大小時悬包,它有助于分配額外的可用空間。當(dāng)項(xiàng)目出行時馍乙,它還會對項(xiàng)目的對齊方式施加一些控制布近。
.container {
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly | start | end | left | right ... + safe | unsafe;
}
- flex-start(默認(rèn)):項(xiàng)目被打包朝向 flex-direction 的開始。
- flex-end: 項(xiàng)目被打包到 flex-direction 的末尾丝格。
- start: 物品被包裝在方向的開始處writing-mode撑瞧。
- end: 物品被包裝到方向的盡頭writing-mode。
- left: 物品被包裝在容器的左邊緣显蝌,除非這對 . 沒有意義预伺,否則flex-direction它的行為就像start.
- right: 物品被包裝在容器的右邊緣,除非這對 . 沒有意義曼尊,否則flex-direction它的行為就像end.
- center:項(xiàng)目沿線居中
- space-between:物品均勻分布在行中酬诀;第一項(xiàng)在起始行,最后一項(xiàng)在結(jié)束行
- space-around:項(xiàng)目均勻分布在行中涩禀,周圍空間相等料滥。請注意,視覺上的空間是不相等的艾船,因?yàn)樗许?xiàng)目的兩邊都有相等的空間葵腹。第一個項(xiàng)目將在容器邊緣有一個空間單位高每,但下一個項(xiàng)目之間有兩個空間單位,因?yàn)橄乱粋€項(xiàng)目有自己的適用間距践宴。
- space-evenly:項(xiàng)目分布使得任何兩個項(xiàng)目之間的間距(以及邊緣的空間)相等鲸匿。
請注意,瀏覽器對這些值的支持是有細(xì)微差別的阻肩。例如带欢,space-between某些版本的 Edge 從未獲得過支持,并且 Chrome 還沒有開始/結(jié)束/左/右烤惊。MDN有詳細(xì)的圖表乔煞。最安全的值是flex-start、flex-end和center柒室。
還有兩個額外的關(guān)鍵字可以與這些值配對:safe和unsafe. 使用safe確保無論您如何進(jìn)行這種類型的定位渡贾,您都不能推動一個元素,使其呈現(xiàn)在屏幕外(例如雄右,離開頂部)空骚,這樣內(nèi)容也不能滾動(稱為“數(shù)據(jù)丟失”) .
對齊項(xiàng)目
這定義了彈性項(xiàng)目如何沿當(dāng)前行的交叉軸布局的默認(rèn)行為。將其視為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(默認(rèn)):拉伸以填充容器(仍然尊重最小寬度/最大寬度)
- flex-start// start:self-start項(xiàng)目放置在橫軸的開始處囤屹。這些之間的區(qū)別是微妙的,是關(guān)于尊重flex-direction規(guī)則或writing-mode規(guī)則的逢渔。
- flex-end// end:self-end項(xiàng)目放置在橫軸的末端肋坚。區(qū)別又是微妙的,是關(guān)于尊重flex-direction規(guī)則與writing-mode規(guī)則的复局。
- center:項(xiàng)目在橫軸上居中
- baseline:項(xiàng)目對齊冲簿,例如它們的基線對齊
和修飾符關(guān)鍵字可以與所有其他關(guān)鍵字一起使用(盡管注意safe瀏覽器支持),并幫助您防止對齊元素以使內(nèi)容變得不可訪問亿昏。unsafe
對齊內(nèi)容
當(dāng)橫軸上有額外空間時峦剔,這將對齊 flex 容器的線,類似于在justify-content主軸內(nèi)對齊單個項(xiàng)目的方式角钩。
注意:該屬性只對多行靈活容器生效吝沫,這里flex-wrap設(shè)置為wrap或wrap-reverse)。單行靈活容器(即 whereflex-wrap設(shè)置為其默認(rèn)值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(默認(rèn)):項(xiàng)目被打包在它們的默認(rèn)位置递礼,就好像沒有設(shè)置值一樣惨险。
- flex-start/ start:包裝到容器開頭的物品。(更受支持的)flex-start尊重脊髓,flex-direction而start尊重writing-mode方向辫愉。
- flex-end/ end:包裝到容器末端的物品。(更多支持)flex-end尊重将硝,flex-direction而端尊重writing-mode方向恭朗。
- center:在容器中居中的項(xiàng)目
- space-between:項(xiàng)目均勻分布屏镊;第一行在容器的開頭,最后一行在結(jié)尾
- space-around:項(xiàng)目在每行周圍均勻分布
- space-evenly:項(xiàng)目均勻分布痰腮,周圍空間相等
- stretch: 線條伸展以占用剩余空間
和修飾符關(guān)鍵字可以與所有其他關(guān)鍵字一起使用(盡管注意safe瀏覽器支持)而芥,并幫助您防止對齊元素以使內(nèi)容變得不可訪問。unsafe
間隙膀值、行間隙棍丐、列間隙
該gap屬性明確控制彈性項(xiàng)目之間的空間。它僅在不在外邊緣的項(xiàng)目之間應(yīng)用該間距沧踏。
.container {
display: flex;
...
gap: 10px;
gap: 10px 20px; /* row-gap column gap */
row-gap: 10px;
column-gap: 20px;
}
該行為可以被認(rèn)為是最小排水溝歌逢,就好像排水溝以某種方式更大(因?yàn)轭愃苆ustify-content: space-between;),那么只有當(dāng)該空間最終變得更小時悦冀,差距才會生效趋翻。
它不僅適用于 flexbox,也gap適用于網(wǎng)格和多列布局盒蟆。
子項(xiàng)的屬性 (彈性項(xiàng)目)
命令
默認(rèn)情況下,彈性項(xiàng)目按源順序排列师骗。但是历等,該order屬性控制它們在彈性容器中出現(xiàn)的順序。
.item {
order: 5; /* default is 0 */
}
具有相同的項(xiàng)目order恢復(fù)到源訂單辟癌。
彈性成長
這定義了彈性項(xiàng)目在必要時增長的能力寒屯。它接受用作比例的無單位值。它規(guī)定了項(xiàng)目應(yīng)該占用的彈性容器內(nèi)的可用空間量黍少。
如果所有項(xiàng)目都flex-grow設(shè)置為1寡夹,則容器中的剩余空間將平均分配給所有子項(xiàng)。如果其中一個孩子的值為2厂置,則該孩子將占用其他孩子之一的兩倍空間(或者至少會嘗試)菩掏。
.item {
flex-grow: 4; /* default 0 */
}
負(fù)數(shù)無效。
彈性收縮
這定義了彈性項(xiàng)目在必要時收縮的能力昵济。
.item {
flex-shrink: 3; /* default 1 */
}
負(fù)數(shù)無效智绸。
彈性基礎(chǔ)
這定義了在分配剩余空間之前元素的默認(rèn)大小。它可以是長度(例如 20%访忿、5rem 等)或關(guān)鍵字瞧栗。關(guān)鍵字的auto意思是“看看我的寬度或高度屬性”(這是由main-size關(guān)鍵字臨時完成的,直到被棄用)海铆。關(guān)鍵字的content意思是“根據(jù)項(xiàng)目的內(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) 是可選的。默認(rèn)值為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這允許為單個彈性項(xiàng)目覆蓋默認(rèn)對齊方式(或由 指定的對齊方式)。
請參閱align-items說明以了解可用值捧韵。
.item {
align-self: auto | flex-start | flex-end | center | baseline | stretch;
}
請注意float市咆,clear和vertical-align對彈性項(xiàng)目沒有影響。
為 Flexbox 添加前綴
Flexbox 需要一些供應(yīng)商前綴來支持盡可能多的瀏覽器再来。它不僅包括帶有供應(yīng)商前綴的屬性蒙兰,而且實(shí)際上還有完全不同的屬性和值名稱。這是因?yàn)?Flexbox 規(guī)范隨著時間的推移發(fā)生了變化芒篷,創(chuàng)建了“舊”搜变、“補(bǔ)間”和“新”版本。
也許處理這個問題的最好方法是編寫新的(也是最終的)語法并通過Autoprefixer運(yùn)行你的 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í)。因此拌滋,設(shè)置邊距auto將使項(xiàng)目在兩個軸上完美居中骤竹。
現(xiàn)在讓我們使用更多的屬性快鱼“溃考慮一個包含 6 個項(xiàng)目的列表,所有項(xiàng)目都具有固定尺寸魏铅,但可以自動調(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;
}
}
讓我們通過玩彈性項(xiàng)目的靈活性來嘗試更好的東西球榆!帶有全寬頁眉和頁腳的移動優(yōu)先 3 列布局怎么樣朽肥?并且獨(dú)立于源順序。
.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; }
}
瀏覽器支持
此瀏覽器支持?jǐn)?shù)據(jù)來自Caniuse持钉,其中包含更多詳細(xì)信息鞠呈。數(shù)字表示瀏覽器支持該版本及更高版本的功能。
錯誤
Flexbox 當(dāng)然也不是沒有缺陷右钾。我見過的最好的集合是 Philip Walton 和 Greg Whitworth 的Flexbugs。這是一個跟蹤所有這些的開源地方旱爆,所以我認(rèn)為最好只鏈接到它舀射。