本教程案例在線演示
免費(fèi)配套視頻教程
教程配套源碼資源
Flex容器
<ul> <!--parent element-->
<li></li> <!--first child element-->
<li></li> <!--second child element-->
<li></li> <!--third child element-->
</ul>
這就是一個無序列表(ul
)里有三個列表元素(li
)地回。
你可以把ul
稱為父元素胡岔,li
稱為子元素。
要開始使用Flexbox屹篓,必須先讓父元素變成一個Flex容器莉御。
你可以在父元素中顯式的設(shè)置display:flex
或者display:inline-flex
撇吞。這樣你就可以開始使用Flexbox模塊。
實(shí)際是顯式聲明了Flex容器之后礁叔,一個Flexbox格式化上下文(Flexbox formatting context)就立即啟動了梢夯。
使用一個無序列表(ul
)和一群列表元素(li
),啟動Flexbox格式化上下文的方式如下:
/* 聲明父元素為flex容器 */
ul {
display:flex; /*或者 inline-flex*/
}
給列表元素(li
)添加一點(diǎn)基本樣式晴圾。
li {
width: 100px;
height: 100px;
background-color: #8cacea;
margin: 8px;
list-style: none;
}
你將看到的效果如下圖所示:
默認(rèn)情況下,li
是塊級元素噪奄,在CSS中垂直排布的死姚,也就是說從上到下排列顯示,就像下圖這樣:
然而勤篮,簡單的寫一行代碼display:flex
都毒,你立即就可以看到布局改變了。
現(xiàn)在列表元素(li
)水平排列碰缔,從左到右账劲。
Flexbox模塊的開始,正如前面的介紹金抡,在任何父元素上使用display:flex
瀑焦。
一旦你顯式的設(shè)置了display
屬性的值為flex
,無序列表ul
就會自動變成Flex容器梗肝,而其子元素(在本例中是指列表元素li
)就變成了Flex項(xiàng)目榛瓮。
使用了兩個關(guān)鍵詞,我們把重點(diǎn)放到他們身上巫击。了解他們對于理解后面的知識至關(guān)重要禀晓。
-
Flex容器(Flex Container):父元素顯式設(shè)置了
display:flex
- Flex項(xiàng)目(Flex Items):Flex容器內(nèi)的子元素
這些只是Flexbox模塊的基礎(chǔ)精续。
Flex容器屬性
flex-direction || flex-wrap || flex-flow || justify-content || align-items || align-content
通過上面的內(nèi)容,我們了解了一些基礎(chǔ)知識粹懒。知道了Flex容器和Flex項(xiàng)目是什么重付,以及如何啟動Flexbox模塊。
有設(shè)置一個父元素作為一個Flex容器凫乖,幾個對齊屬性可以使用在Flex容器上确垫。
正如你的塊元素的width
設(shè)置了200px
,有六種不同的屬性可以用于Flex容器拣凹。
flex-direction
flex-direction
屬性控制Flex項(xiàng)目沿著主軸(Main Axis)的排列方向森爽。
它具有四個值:
/* ul 是一個flex容器 */
ul {
flex-direction: row || column || row-reverse || column-reverse;
}
簡單點(diǎn)來說,就是flex-direction
屬性讓你決定Flex項(xiàng)目如何排列嚣镜。它可以是行(水平)爬迟、列(垂直)或者行和列的反向。
從技術(shù)上講菊匿,水平和垂直在Flex世界中不是什么方向(概念)付呕。它們常常被稱為主軸(Main-Axis)和側(cè)軸(Cross-Axis)。默認(rèn)設(shè)置如下所示跌捆。
通俗的說徽职,感覺Main-Axis就是水平方向,從左到右佩厚,這也是默認(rèn)方向姆钉。Cross-Axis是垂直方向,從上往下抄瓦。
默認(rèn)情況下潮瓶,flex-direction
屬性的值是row
。它讓Flex項(xiàng)目沿著Main-Axis排列(從左向右钙姊,水平排列)毯辅。這就解釋了本文開始部分時無序列表的表現(xiàn)效果。
盡管flex-direction
屬性并沒有顯式的設(shè)置煞额,但它的默認(rèn)值是row
思恐。Flex項(xiàng)目將沿著Main-Axis從左向右水平排列。
如果把flex-direction
的屬性值修改成column
膊毁,這時Flex項(xiàng)目將沿著Cross-Axis從上到下垂直排列胀莹。不再是從左向右排列。
flex-wrap
flex-wrap
屬性有三個屬性值:
ul {
flex-wrap: wrap || nowrap || wrap-reverse;
}
我將通過一個例子來解釋如何使用flex-wrap
屬性媚媒。首先在前面的無序列表的HTML結(jié)構(gòu)中多添加幾個列表項(xiàng)li
嗜逻。
<ul> <!--parent element-->
<li></li> <!--first child element-->
<li></li> <!--second child element-->
<li></li> <!--third child element-->
<li></li>
<li></li>
<li></li>
</ul>
幸運(yùn)的是,新添加的Flex項(xiàng)目剛好適合Flex容器大小缭召。也就是Flex項(xiàng)目能剛好填充Flex容器栈顷。
再深入一點(diǎn)逆日。
繼續(xù)給Flex容器內(nèi)添加Flex項(xiàng)目,比如說添加到10
個Flex項(xiàng)目萄凤。這個時候會發(fā)生什么室抽?
<ul> <!--parent element-->
<li></li> <!--first child element-->
<li></li> <!--second child element-->
<li></li> <!--third child element-->
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
同樣的,F(xiàn)lex容器還是能容納所有的子元素(Flex項(xiàng)目)排列靡努,這是每一個Flex容器的默認(rèn)行為坪圾。Flex容器會在一行內(nèi)容納所有的Flex項(xiàng)目。這是因?yàn)?code>flex-wrap屬性的默認(rèn)值是nowrap
惑朦。也就是說兽泄,F(xiàn)lex項(xiàng)目在Flex容器內(nèi)不換行排列。
ul {
flex-wrap: nowrap; /*Flex容器內(nèi)的Flex項(xiàng)目不換行排列*/
}
no-wrap
不是不可改變的漾月。我們可以改變病梢。
當(dāng)你希望Flex容器內(nèi)的Flex項(xiàng)目達(dá)到一定數(shù)量時,能換行排列梁肿。當(dāng)Flex容器中沒有足夠的空間放置Flex項(xiàng)目(Flex項(xiàng)目默認(rèn)寬度)蜓陌,那么Flex項(xiàng)目將會換行排列。把它(flex-wrap
)的值設(shè)置為wrap
就有這種可能:
ul {
flex-wrap: wrap;
}
現(xiàn)在Flex項(xiàng)目在Flex容器中就會多行排列吩蔑。
在這種情況下钮热,當(dāng)一行再不能包含所有列表項(xiàng)的默認(rèn)寬度,他們就會多行排列烛芬。即使調(diào)整瀏覽器大小隧期。
就是這樣子。注意:Flex項(xiàng)目現(xiàn)在顯示的寬度是他們的默認(rèn)寬度赘娄。也沒有必要強(qiáng)迫一行有多少個Flex項(xiàng)目厌秒。
除此之外,還有一個值:wrap-reverse
擅憔。
是的,你猜對了檐晕。它讓Flex項(xiàng)目在容器中多行排列暑诸,只是方向是反的。
flex-flow
flex-flow
是flex-direction
和flex-wrap
兩個屬性的速記屬性辟灰。
你還記得使用border
的速記寫法个榕?border: 1px solid red
。這里的概念是相同的芥喇,多個值寫在同一行西采,比如下面的示例:
ul {
flex-flow: row wrap;
}
相當(dāng)于:
ul {
flex-direction: row;
flex-wrap: wrap;
}
除了這個組合之外,你還可以嘗試一些其它的組合继控。flex-flow: row nowrap
械馆,flex-flow: column wrap
胖眷,flex-flow: column nowrap
。
justify-content
Flexbox模塊真得很好霹崎。如果你仍然不相信它的魅力珊搀,那么justify-content
屬性可能會說服你。
justify-content
屬性可以接受下面五個值之一:
ul {
justify-content: flex-start || flex-end || center || space-between || space-around
}
justify-content
屬性又能給我們帶來什么呢尾菇?提醒你一下境析,你是否還記得text-align
屬性。其實(shí)justify-content
屬性主要定義了Flex項(xiàng)目在Main-Axis上的對齊方式派诬。
來看一個簡單的例子劳淆,還是考慮下面這個簡單的無序列表:
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
添加一些基本樣式:
ul {
display:flex;
border: 1px solid red;
padding: 0;
list-style: none;
background-color: #e8e8e9;
}
li {
background-color: #8cacea;
width: 100px;
height: 100px;
margin: 8px;
padding: 4px;
}
你將看到的效果是這樣:
通過justify-content
屬性,可以讓Flex項(xiàng)目在整個Main-Axis上按照我自己的欲望設(shè)置其對齊方式默赂。
可能會有以下幾種類型沛鸵。
flex-start
justify-content
的默認(rèn)屬性值是flex-start
。
flex-start
讓所有Flex項(xiàng)目靠Main-Axis開始邊緣(左對齊)放可。
ul {
justify-content: flex-start;
}
flex-end
flex-end
讓所有Flex項(xiàng)目靠Main-Axis結(jié)束邊緣(右對齊)翎卓。
ul {
justify-content: flex-end;
}
center
和你預(yù)期的一樣,center
讓所有Flex項(xiàng)目排在Main-Axis中間(居中對齊)负懦。
ul {
justify-content: center;
}
space-between
space-between
讓除了第一個和最一個Flex項(xiàng)目的兩者間間距相同(兩端對齊)揍愁。
ul {
justify-content: space-between;
}
你注意到有什么不同?看看下圖的描述:
space-around
最后冯挎,space-around
讓每個Flex項(xiàng)目具有相同的空間底哥。
ul {
justify-content: space-around;
}
和space-between
有點(diǎn)不同,第一個Flex項(xiàng)目和最后一個Flex項(xiàng)目距Main-Axis開始邊緣和結(jié)束邊緣的的間距是其他相鄰Flex項(xiàng)目間距的一半房官≈夯眨看看下圖的描述:
align-items
align-items
屬性類似于justify-content
屬性。只有理解了justify-content
屬性翰守,才能更好的理解這個屬性孵奶。
align-items
屬性可以接受這些屬性值:flex-start || flex-end || center || stretch || baseline
。
ul {
align-items: flex-start || flex-end || center || stretch || baseline
}
它主要用來控制Flex項(xiàng)目在Cross-Axis對齊方式蜡峰。這也是align-items
和justify-content
兩個屬性之間的不同之處了袁。
下面是不同的值對Flex項(xiàng)目產(chǎn)生的影響。不要忘記這些屬性只對Cross-Axis軸有影響湿颅。
首先载绿,讓我們設(shè)置ul的高度高于li的高度
ul {
height: 200px;
}
stretch
align-items
的默認(rèn)值是stretch
。讓所有的Flex項(xiàng)目高度和Flex容器高度一樣油航。
flex-start
正如你所希望的flex-start
讓所有Flex項(xiàng)目靠Cross-Axis開始邊緣(頂部對齊)崭庸。
flex-end
flex-end
讓所有Flex項(xiàng)目靠Cross-Axis結(jié)束邊緣(底部對齊)。
center
center
讓Flex項(xiàng)目在Cross-Axis中間(居中對齊)。
baseline
讓所有Flex項(xiàng)目在Cross-Axis上沿著他們自己的基線對齊怕享。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul {
border: 1px solid red;
display: flex;
height: 200px;
align-items: baseline;
}
li {
width: 100px;
background-color: #8cacea;
margin: 8px;
list-style: none;
font-size: 28px;
}
li:nth-child(2){
font-size: 12px;
}
</style>
</head>
<body>
<ul> <!--parent element-->
<li>1</li> <!--first child element-->
<li>2</li> <!--second child element-->
<li>333 33333 33 </li> <!--third child element-->
</ul>
</body>
</html>
結(jié)果看上去有點(diǎn)像flex-start
执赡,但略有不同。那“baseline”到底是什么呢熬粗?下圖應(yīng)該能幫助你更好的理解搀玖。
align-content
還記得前面討論的wrap
屬性嗎?我們在Flex容器中添加了更多的Flex項(xiàng)目驻呐。讓Flex容器中的Flex項(xiàng)目多行排列灌诅。
align-content
屬性用于多行的Flex容器。它也是用來控制Flex項(xiàng)目在Flex容器里的排列方式含末,排列效果和align-items
值一樣猜拾,但除了baseline
屬性值。
像align-items
屬性一樣佣盒,它的默認(rèn)值是stretch
挎袜。你現(xiàn)在應(yīng)該熟悉這些值。那它又是如何影響Flex容器里的10個Flex項(xiàng)目多行排列方式肥惭。
stretch
使用stretch
會拉伸Flex項(xiàng)目盯仪,讓他們沿著Cross-Axis適應(yīng)Flex容器可用的空間。
你看到的Flex項(xiàng)目間的間距蜜葱,是Flex項(xiàng)目自身設(shè)置的margin
值全景。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
ul {
border: 1px solid red;
display: flex;
height: 400px;
flex-wrap: wrap;
align-content:center;
}
li {
width: 100px;
background-color: #8cacea;
margin: 8px;
list-style: none;
font-size: 28px;
}
li:nth-child(2){
font-size: 12px;
}
</style>
</head>
<body>
<ul> <!--parent element-->
<li>1</li> <!--first child element-->
<li>2</li> <!--second child element-->
<li>333 33333</li> <!--third child element-->
<li>1</li> <!--first child element-->
<li>2</li> <!--second child element-->
<li>333 33333 33 </li> <!--third child element-->
<li>1</li> <!--first child element-->
<li>2</li> <!--second child element-->
<li>333 33333 33 </li> <!--third child element-->
</ul>
</body>
</html>
flex-start
之前你看到過flex-start
。這次是讓多行Flex項(xiàng)目靠Cross-Axis開始邊緣牵囤。沿著Cross-Axis從上到下排列爸黄。因此Flex項(xiàng)目在Flex容器中頂部對齊。
flex-end
flex-end
剛好和flex-start
相反揭鳞,讓多行Flex項(xiàng)目靠著Cross-Axis結(jié)束位置炕贵。讓Flex項(xiàng)目沿著Cross-Axis從下到上排列,即底部對齊野崇。
center
你猜到了称开,center
讓多行Flex項(xiàng)目在Cross-Axis中間。在Flex容器中居中對齊乓梨。
這是Flex容器的最后一個屬性钥弯。你現(xiàn)在知道如何使用各種Flex容器屬性。你可以在工作中實(shí)踐這些屬性督禽。
Flex項(xiàng)目屬性
flex-grow || flex-shrink || flex-basis
現(xiàn)在我們把注意力從Flex容器轉(zhuǎn)移到Flex項(xiàng)目及其對齊屬性。
像Flex容器总处,對齊屬性也可以用在所有的Flex項(xiàng)目狈惫。
flex-grow 和 flex-shrink
flex-grow
和flex-shrink
屬性控制Flex項(xiàng)目在容器有多余的空間如何放大(擴(kuò)展),在沒有額外空間又如何縮小。
他們可能接受0
或者大于0
的任何正數(shù)胧谈。0 || positive number
忆肾。
接下來闡述它們的使用。使用一個簡單的無序列表做為例子菱肖,它只包含一個列表項(xiàng)客冈。
ul {
display:flex;
border: 1px solid red;
padding: 0;
list-style: none;
}
li {
background-color: #8cacea;
height: 100px;
margin: 8px;
padding: 10px;
}
<ul>
<li>I am a simple list</li>
</ul>
添加更多的樣式,看起來像這樣:
默認(rèn)情況下稳强,flex-grow
屬性值設(shè)置為0
场仲。表示Flex項(xiàng)目不會增長,填充Flex容器可用空間退疫。取值為0
就是一個開和關(guān)的按鈕渠缕。表示flex-grow
開關(guān)是關(guān)閉的。
如果把flex-grow
的值設(shè)置為1
褒繁,會發(fā)生:
現(xiàn)在Flex項(xiàng)目擴(kuò)展了亦鳞,占據(jù)了Flex容器所有可用空間。也就是說開關(guān)打開了棒坏。如果你試著調(diào)整你瀏覽器的大小燕差,F(xiàn)lex項(xiàng)目也會縮小,以適應(yīng)新的屏幕寬度坝冕。
為什么徒探?默認(rèn)情況下,flex-shrink
的值是1
徽诲,也就是說flex-shrink
開關(guān)也是打開的刹帕。
可以仔細(xì)看看flex-grow
和flex-shrink
屬性在各種情況下的效果,這樣能更好的幫助你理解谎替。
flex-basis
flex-basis
屬性可以指定Flex項(xiàng)目的初始大小偷溺。也就是flex-grow
和flex-shrink
屬性調(diào)整它的大小以適應(yīng)Flex容器之前。
flex-basis
默認(rèn)的值是auto
钱贯。flex-basis
可以取任何用于width
屬性的任何值挫掏。比如 % || em || rem || px
等。
注意:如果flex-basis
屬性的值是0
時秩命,也需要使用單位尉共。即flex-basis: 0px
不能寫成flex-basis:0
。
這里同樣使用只有一個列表項(xiàng)的列表做為示例弃锐。
/* 聲明父元素為flex容器 */
ul {
display:flex;
border: 1px solid red;
padding: 0;
list-style: none;
}
li {
background-color: #8cacea;
height: 100px;
margin: 8px;
padding: 10px;
}
<ul>
<li>I am a simple list</li>
</ul>
默認(rèn)情況袄友,F(xiàn)lex項(xiàng)目的初始寬度由flex-basis
的默認(rèn)值決定,即:flex-basis: auto
霹菊。Flex項(xiàng)目寬度的計算是基于內(nèi)容的多少來自動計算(很明顯剧蚣,加上了padding
值)。
這意味著,如果你增加Flex項(xiàng)目中的內(nèi)容鸠按,它可以自動調(diào)整大小礼搁。
<ul>
<li>I am a simple list AND I am a simple list</li>
</ul>
然而,如果你想將Flex項(xiàng)目設(shè)置一個固定的寬度目尖,你也可以這樣做:
li {
flex-basis: 150px;
}
現(xiàn)在Flex項(xiàng)目的寬度受到了限制馒吴,它的寬度是150px
。
flex速記
flex
是flex-grow
瑟曲、flex-shrink
和flex-basis
三個屬性的速記(簡寫)饮戳。
在適當(dāng)?shù)臅r候,我建議你使用flex
测蹲,這樣比使用三個屬性方便莹捡。
li {
flex: 0 1 auto;
}
上面的代碼相當(dāng)于:
li {
flex-grow: 0;
flex-shrink: 1;
flex-basis: auto;
}
注意它們之間的順序。flex-grow
第一扣甲,然后是flex-shrink
篮赢,最后是flex-basis
×鹜冢縮寫成GSB启泣,可以幫助你更好的記憶。
如果flex
屬性值中少一個值示辈,會發(fā)生什么呢寥茫?
如果你只設(shè)置了flex-grow
和flex-shrink
值,flex-basis
可能是默認(rèn)值0
矾麻。這就是所謂的絕對flex項(xiàng)目纱耻。只有當(dāng)你設(shè)置了flex-basis
,你會得到一個相對flex項(xiàng)目险耀。
/* 這是一個絕對的Flex項(xiàng)目 */
li {
flex: 1 1; /*flex-basis 默認(rèn)值為 0*/
}
/* 這是一個相對的Flex項(xiàng)目 */
li {
flex-basis: 200px; /* 只設(shè)置了flex-basis的值 */
}
你肯定想知道相對和絕對的Flex項(xiàng)目是什么弄喘?將在后面回答這個問題。
讓我們看看一些非常有用的flex
值甩牺。
flex: 0 1 auto
li {
flex: 0 1 auto;
}
這相當(dāng)于寫了flex
默認(rèn)屬性值以及所有的Flex項(xiàng)目都是默認(rèn)行為蘑志。
很容易理解這一點(diǎn),首先看看flex-basis
屬性贬派。flex-basis
設(shè)置為auto
急但,這意味著Flex項(xiàng)目的初始寬度計算是基于內(nèi)容的大小。
把注意力放到下一個屬性搞乏,flex-grow
設(shè)置為0
波桩。這意味著flex-grow
不會改變Flex項(xiàng)目的初始寬度。也就是說请敦,flex-grow
的開關(guān)是關(guān)閉的镐躲。
flex-grow
控制Flex項(xiàng)目的增長柏卤,如果其值設(shè)置為0
,F(xiàn)lex項(xiàng)目不會放大以適應(yīng)屏幕(Flex容器大性扔汀)。
最后勾笆,flex-shrink
的值是1
敌蚜。也就是說,F(xiàn)lex項(xiàng)目在必要時會縮小窝爪。
應(yīng)用到Flex項(xiàng)目效果就是這樣子:
注意:Flex項(xiàng)目沒有增長(寬度)弛车。如果有必要,如果調(diào)整瀏覽器(調(diào)小瀏覽器寬度)蒲每,F(xiàn)lex項(xiàng)目會自動計算寬度纷跛。
flex: 0 0 auto
li {
flex: 0 0 auto;
}
這個相當(dāng)于flex: none
。
還是老規(guī)矩:寬度是被自動計算邀杏,不過彈性項(xiàng)目不會伸展或者收縮(因?yàn)槎叨急辉O(shè)置為零)贫奠。伸展和收縮開關(guān)都被關(guān)掉了。
它基本上是一個固定寬度的元素望蜡,其初始寬度是基于彈性項(xiàng)目中內(nèi)容大小唤崭。
看看這個 flex 簡寫是如何影響兩個彈性項(xiàng)目的。一個彈性項(xiàng)目會比另一個容納更多內(nèi)容脖律。
應(yīng)該注意到的第一件事情是谢肾,這兩個彈性項(xiàng)目的寬度是不同的。因?yàn)閷挾仁腔趦?nèi)容寬度而自動計算的小泉,所以這是預(yù)料得到的芦疏。
試著縮放一下瀏覽器,你會注意到彈性項(xiàng)目不會收縮其寬度微姊。它們從父元素中突出來了酸茴,要看到所有內(nèi)容,必須橫向滾動瀏覽器柒桑。
在縮放瀏覽器時弊决,彈性項(xiàng)目不會收縮,而是從彈性容器中突出來了魁淳。
flex: 1 1 auto
這與 flex: auto
項(xiàng)目相同飘诗。
還是按我前面立的規(guī)矩。即界逛,自動計算初始化寬度昆稿,但是如果有必要,會伸展或者收縮以適應(yīng)整個可用寬度息拜。
伸展和收縮開關(guān)打開了溉潭,寬度自動被計算净响。
此時,項(xiàng)目會填滿可用空間喳瓣,在縮放瀏覽器時也會隨之收縮馋贤。剩余寬度被2個item平均分配,一人一半畏陕。
flex: "positive number"
一般應(yīng)用于有多個彈性項(xiàng)目的情形配乓。
這里正數(shù)可以代表任何正數(shù)(沒有引號)。這與 flex: “正數(shù)” 1 0
相同惠毁。
flex: 2 1 0
與寫為 flex: 2
是一樣的犹芹,2
表示任何正數(shù)。
li {
flex: 2 1 0; / *與 flex: 2相同 */
}
與前面我立的規(guī)矩一樣鞠绰,即腰埂,將彈性項(xiàng)目的初始寬度設(shè)置為零(嗯?沒有寬度蜈膨?)屿笼,伸展項(xiàng)目以填滿可用空間,并且最后只要有可能就收縮項(xiàng)目丈挟。
彈性項(xiàng)目沒有寬度刁卜,那么寬度該如何計算呢?
這個時候 flex-grow
值就起作用了曙咽,它決定彈性項(xiàng)目變寬的程度蛔趴。由它來負(fù)責(zé)沒有寬度的問題。
當(dāng)有多個彈性項(xiàng)目例朱,并且其初始寬度 flex-basis
被設(shè)置為基于零的任何值時孝情,比如 0px
,使用這種 flex
簡寫更實(shí)用洒嗤。
實(shí)際發(fā)生的是箫荡,彈性項(xiàng)目的寬度被根據(jù) flex-grow
值的比例來計算。
考慮如下兩個列表項(xiàng)標(biāo)記及 CSS:
<ul>
<li>I am One</li>
<li>I am Two</li>
</ul>
<style>
/* 聲明父元素為flex容器 */
ul {
display:flex;
border: 1px solid red;
padding: 0;
list-style: none;
}
li {
background-color: #8cacea;
height: 100px;
margin: 8px;
padding: 10px;
/* flex-basis: 150px; */
}
/* 第一個彈性項(xiàng)目 */
li:nth-child(1) {
flex: 2 1 0; /* 與寫成 flex: 2 相同*/
}
/* 第二個彈性項(xiàng)目 */
li:nth-child(2){
flex: 1 1 0;
background-color: #8cacea;
}
</style>
記住設(shè)置 flex-grow : 1
渔隶,會讓彈性項(xiàng)目填滿可用空間羔挡。伸展開關(guān)打開了。
這里有兩個彈性項(xiàng)目间唉。一個的 flex-grow
屬性值是 1
绞灼,另一個是 2
,那么會出現(xiàn)啥情況呢呈野?
兩個項(xiàng)目上的伸展開關(guān)都打開了低矮。不過,伸展度是不同的被冒,1
和 2
军掂。
二者都會填滿可用空間轮蜕,不過是按比例的。
它是這樣工作的:前一個占 1/3
的可用空間蝗锥,后一個占 2/3
的可用空間跃洛。
即使兩個彈性項(xiàng)目內(nèi)容一樣大(近似),它們所占空間還是不同终议。寬度不是基于內(nèi)容的大小税课,而是伸展值。一個是另一個的約兩倍痊剖。
絕對和相對Flex項(xiàng)目
前面了解了一些基本概念,但重要的是要澄清一些重要的概念垒玲。那絕對和相對Flex項(xiàng)目之間到底有啥區(qū)別呢陆馁?二者之間主要的區(qū)別在于間距及如何計算間距。
一個相對Flex項(xiàng)目內(nèi)的間距是根據(jù)它的內(nèi)容大小來計算的合愈。而在絕對Flex項(xiàng)目中叮贩,只根據(jù) flex
屬性來計算,而不是內(nèi)容佛析。
考慮如下的標(biāo)記:
<ul>
<li>
This is just some random text to buttress the point being explained.
Some more random text to buttress the point being explained.
</li>
<li>This is just a shorter random text.</li>
</ul>
兩個列表項(xiàng)元素益老,一個比另一個的文本多得多。
加點(diǎn)樣式:
ul {
display: flex; /*觸發(fā)彈性盒*/
}
li {
flex: auto; /*記住這與 flex: 1 1 auto; 相同*/
border: 2px solid red;
margin: 2em;
}
如下是結(jié)果:
如果你已經(jīng)忘了的話寸莫,flex: 1 1 auto
是與 flex-grow: 1
捺萌、flex-shrink: 1
和 flex-basis: auto
相同的。
Flex項(xiàng)目的初始寬度是被自動計算的(flex-basis: auto
)膘茎,然后會伸展以適應(yīng)可用空間(flex-grow: 1
)桃纯。
當(dāng)Flex項(xiàng)目因?yàn)楸辉O(shè)置為 flex-basis: auto
,而導(dǎo)致寬度被自動計算時披坏,是基于Flex項(xiàng)目內(nèi)包含的內(nèi)容的大小而計算态坦。
上面示例中Flex項(xiàng)目的內(nèi)容大小不相同乃沙。因此盗飒,F(xiàn)lex項(xiàng)目的大小就會不相等岳悟。
既然各個寬度開始就不是相等的(它是基于內(nèi)容的)芹血,那么當(dāng)項(xiàng)目伸展時变姨,寬度也保持不相等捡遍。
可以試試讓兩個li的內(nèi)容相同再試試牵祟。
上面示例中的Flex項(xiàng)目是相對Flex項(xiàng)目痪蝇。
下面我們把Flex項(xiàng)目變成絕對的, 就是說這次它們的寬度是基于 flex
屬性涮阔,而不是內(nèi)容的大小猜绣。一行代碼就可以出奇跡。
li {
flex: 1 ; /*與 flex: 1 1 0 相同*/
}
效果如下:
這次看到兩個Flex項(xiàng)目的寬度相同了嗎敬特?
Flex項(xiàng)目的初始寬度是零(flex-basis: 0
)掰邢,并且它們會伸展以適應(yīng)可用空間牺陶。當(dāng)有兩到多個Flex項(xiàng)目的 flex-basis
取值為0
時,它們會基于 flex-grow
值共享可用空間辣之。
現(xiàn)在寬度不會基于內(nèi)容大小而計算掰伸,而是基于指定的 flex
屬性值來計算。
絕對Flex項(xiàng)目的寬度只基于 flex
屬性怀估,而相對Flex項(xiàng)目的寬度基于初始內(nèi)容大小狮鸭。
Auto-margin 對齊
當(dāng)心Flex項(xiàng)目上的 margin: auto
對齊。當(dāng)在Flex項(xiàng)目上使用 margin: auto
時多搀,事情看起來就很怪異了歧蕉。
你需要理解會發(fā)生什么。它會導(dǎo)致不可預(yù)料的結(jié)果康铭,不過我打算解釋解釋惯退。
當(dāng)在Flex項(xiàng)目上使用 margin: auto
時,值為 auto
的方向(左从藤、右或者二者都是)會占據(jù)所有剩余空間催跪。
這玩意有點(diǎn)難理解。下面我來說明一下夷野。
考慮如下的導(dǎo)航欄標(biāo)記以及 CSS 樣式:
<ul>
<li>Branding</li>
<li>Home</li>
<li>Services</li>
<li>About</li>
<li>Contact</li>
</ul>
<style>
/* 聲明父元素為flex容器 */
ul {
display:flex;
border: 1px solid red;
padding: 0;
list-style: none;
}
li {
background-color: #8cacea;
margin: 8px;
padding: 10px;
flex: 0 0 auto;
border: 2px solid red;
}
</style>
你可以看到如下的效果:
這里有幾件事情要注意:
-
flex-grow
值為設(shè)置為0
懊蒸。這就解釋了為什么列表項(xiàng)不會伸展。 - Flex項(xiàng)目向Main-Axis的開頭對齊(這是默認(rèn)行為)悯搔。
- 由于項(xiàng)目被對齊到Main-Axis開頭骑丸,右邊就有一些多余的空間《拭玻看到了吧者娱?
現(xiàn)在在第一個列表項(xiàng)(branding)上使用
margin: auto
,看看會出啥情況苏揣。
li:nth-child(1) {
margin-right: auto; /*只應(yīng)用到右外邊距*/
}
剛剛發(fā)生了什么黄鳍?之前的剩余空間現(xiàn)在已經(jīng)被分配到第一個Flex項(xiàng)目的右邊了。
還記得我前面說的話吧平匈?當(dāng)在Flex項(xiàng)目上使用 margin: auto
時框沟,值為 auto
的方向(左、右或者二者都是)會占據(jù)所有剩余空間增炭。
如果想讓一個Flex項(xiàng)目的兩邊都用自動外邊距對齊忍燥,該怎么辦呢?
/* 如果愿意的話隙姿,也可以用 margin 簡寫來設(shè)置兩個邊 */
li:nth-child(1) {
margin-left: auto;
margin-right: auto
}
現(xiàn)在空白被分配到Flex項(xiàng)目的兩邊了梅垄。
那么,這是不是對很酷的自動外邊距對齊的一種折衷方案呢输玷?看起來是队丝。如果沒注意的話靡馁,它也可能是受挫之源。當(dāng)在一個Flex項(xiàng)目上使用自動外邊距(margin: auto
)時机久,justify-content
屬性就不起作用了臭墨。
例如,在上面的Flex容器上通過 justify-content
屬性膘盖,設(shè)置不同的對齊選項(xiàng)時胧弛,對布局沒有影響。
ul {
justify-content: flex-end;
}
Flexbox實(shí)戰(zhàn)
導(dǎo)航系統(tǒng)是每個網(wǎng)站或者應(yīng)用程序的重要組成部分侠畔。這個世界上的每個網(wǎng)站都會有某種導(dǎo)航系統(tǒng)结缚。
下面我們看看這些熱門網(wǎng)站,以及它們是如何實(shí)現(xiàn)其導(dǎo)航系統(tǒng)的软棺。你看到Flexbox是如何幫助你更高效地創(chuàng)建這些布局嗎掺冠?
也仔細(xì)看看哪里會用得上自動外邊距特性。
Bootstrap導(dǎo)航
AirBnB PC端導(dǎo)航
Twitter PC端導(dǎo)航
建議你自己寫代碼码党。試著自己實(shí)現(xiàn)這些導(dǎo)航系統(tǒng)。
切換flex-direction會發(fā)生什么斥黑?
還記得我說過默認(rèn)的Main-Axis方向是從左到右揖盘,Cross-Axis方向是從上到下吧?
好吧锌奴,現(xiàn)在你也可以改變這個方向兽狭。
正如在較早的小節(jié)中所描述的那樣,用 flex-direction: column
時鹿蜀,確實(shí)是這樣箕慧。
當(dāng)用 flex-direction: column
時,Main-Axis和Cross-Axis會向如下所看到的那樣改變:
如果曾用英語寫過文字茴恰,那么你就知道英語是從左到右颠焦,從上到下來寫的。
Flexbox的默認(rèn)Main-Axis和Cross-Axis也是采用同樣的方向往枣。
不過伐庭,如果將 flex-direction
切換為 column
,它就不再遵循英語的范式分冈,而是日語的范式圾另!
是的,日語雕沉。
如果你用日語寫過文字集乔,那么應(yīng)該很熟悉了。(鄭重聲明坡椒,我從沒用過日語寫過文字)扰路。
日文通常是從上到下寫的尤溜!沒那么怪,對吧幼衰?
這就解釋了為嘛這對英語寫作者可能有點(diǎn)惱火靴跛。
看看下面這個例子。標(biāo)準(zhǔn)無序列表(ul
)渡嚣,帶有 3
個列表項(xiàng)(li
)梢睛。不過這次我要改變一下flex-direction
。
<ul>
<li></li>
<li></li>
<li></li>
</ul>
<style>
/* 聲明父元素為flex容器 */
ul {
display:flex;
border: 1px solid red;
padding: 0;
list-style: none;
flex-direction: column;
}
li {
background-color: #8cacea;
margin: 8px;
padding: 10px;
flex: 0 0 auto;
border: 2px solid red;
}
</style>
如下是方向變化之前的樣子:
如下是方向變化之后的樣子:
現(xiàn)在文字是以日語風(fēng)格寫的:沿Main-Axis從上到下识椰。
你會看到項(xiàng)目的寬度填滿了空間绝葡,對吧?
如果在之前要變成這樣子腹鹉,得處理 flex-basis
以及 flex-grow
屬性藏畅。
下面來看看這些會如何影響新的布局。
li {
flex-basis: 100px;
}
下面是你會得到的功咒。
什么愉阎?高度是被影響了,但是寬度沒有傲Ψ堋榜旦?我之前說過,flex-basis
屬性定義每個Flex項(xiàng)目的初始寬度景殷。
在切換 flex-direction
時溅呢,請注意,影響Main-Axis的每一個屬性現(xiàn)在會影響新Main-Axis猿挚。像 flex-basis
這種會影響Main-Axis上Flex項(xiàng)目寬度的屬性咐旧,現(xiàn)在會影響項(xiàng)目的高度,而不是寬度绩蜻。
方向已經(jīng)被切換了铣墨!
所以,即使你使用 flex-grow
屬性办绝,它也是影響高度踏兜。本質(zhì)上,每個作用于橫向軸(即Main-Axis)上的 flex 屬性八秃,現(xiàn)在都會作用于縱向上的新Main-Axis碱妆。它只是在方向上的一個切換。
這里再來一個例子昔驱。我發(fā)誓在這個例子之后你會有更好的理解疹尾。減少之前看到過的Flex項(xiàng)目的寬度,它們就不再填滿整個空間了:
li {
width: 200px;
}
如果想把列表項(xiàng)移到屏幕中間該怎么辦呢?
在英語中纳本,這是你到目前為止處理彈性容器的方式窍蓝。就是說, 把Flex項(xiàng)目移到Main-Axis的中間 繁成。
所以吓笙,你會用 justify-content: center
。但是這樣做不起作用巾腕。因?yàn)榉较蜃兞嗣婢Γ行氖茄刂鳦ross-Axis,而不是Main-Axis尊搬。
再來看看:
所以請用日語文字來思考叁鉴。Main-Axis是從上到下,你不需要這樣佛寿。Cross-Axis是從左到右幌墓。貌似是你所要的。
你需要 把Flex項(xiàng)目移到Cross-Axis的中間 冀泻。這里想起哪個Flex容器屬性了么常侣?
是的,align-items
屬性弹渔。align-items
屬性處理Cross-Axis上的對齊胳施。
所以要把這些項(xiàng)目移到中間,得這樣做:
li {
align-items: center;
}
瞧瞧捞附!Flex項(xiàng)目已經(jīng)居中了吧。