HTML5+CSS3前端入門教程---從0開始通過一個商城實(shí)例手把手教你學(xué)習(xí)PC端和移動端頁面開發(fā)第8章FlexBox布局

本教程案例在線演示

有路網(wǎng)PC端
有路網(wǎng)移動端

免費(fèi)配套視頻教程

免費(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;
}

你將看到的效果如下圖所示:


image

默認(rèn)情況下,li是塊級元素噪奄,在CSS中垂直排布的死姚,也就是說從上到下排列顯示,就像下圖這樣:

image

然而勤篮,簡單的寫一行代碼display:flex都毒,你立即就可以看到布局改變了。

現(xiàn)在列表元素(li)水平排列碰缔,從左到右账劲。

image

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è)置如下所示跌捆。

image

通俗的說徽职,感覺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從左向右水平排列。

image

如果把flex-direction的屬性值修改成column膊毁,這時Flex項(xiàng)目將沿著Cross-Axis從上到下垂直排列胀莹。不再是從左向右排列。

image

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容器栈顷。

image

再深入一點(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>
image

同樣的,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)目厌秒。

image

除此之外,還有一個值:wrap-reverse擅憔。

是的,你猜對了檐晕。它讓Flex項(xiàng)目在容器中多行排列暑诸,只是方向是反的。

image

flex-flow

flex-flowflex-directionflex-wrap兩個屬性的速記屬性辟灰。

你還記得使用border的速記寫法个榕?border: 1px solid red。這里的概念是相同的芥喇,多個值寫在同一行西采,比如下面的示例:

ul {
    flex-flow: row wrap;
}

image

相當(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;
}

你將看到的效果是這樣:


image

通過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;
}

image

flex-end

flex-end讓所有Flex項(xiàng)目靠Main-Axis結(jié)束邊緣(右對齊)翎卓。

ul {
    justify-content: flex-end;
}

image

center

和你預(yù)期的一樣,center讓所有Flex項(xiàng)目排在Main-Axis中間(居中對齊)负懦。

ul {
    justify-content: center;
}

image

space-between

space-between讓除了第一個和最一個Flex項(xiàng)目的兩者間間距相同(兩端對齊)揍愁。

ul {
    justify-content: space-between;
}

image

你注意到有什么不同?看看下圖的描述:

image

space-around

最后冯挎,space-around讓每個Flex項(xiàng)目具有相同的空間底哥。

ul {
    justify-content: space-around;
}

image

space-between有點(diǎn)不同,第一個Flex項(xiàng)目和最后一個Flex項(xiàng)目距Main-Axis開始邊緣和結(jié)束邊緣的的間距是其他相鄰Flex項(xiàng)目間距的一半房官≈夯眨看看下圖的描述:

image

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-itemsjustify-content兩個屬性之間的不同之處了袁。

下面是不同的值對Flex項(xiàng)目產(chǎn)生的影響。不要忘記這些屬性只對Cross-Axis軸有影響湿颅。

首先载绿,讓我們設(shè)置ul的高度高于li的高度

ul {
      height: 200px;
    }

stretch

align-items的默認(rèn)值是stretch。讓所有的Flex項(xiàng)目高度和Flex容器高度一樣油航。

image

flex-start

正如你所希望的flex-start讓所有Flex項(xiàng)目靠Cross-Axis開始邊緣(頂部對齊)崭庸。

image

flex-end

flex-end讓所有Flex項(xiàng)目靠Cross-Axis結(jié)束邊緣(底部對齊)。

image

center

center讓Flex項(xiàng)目在Cross-Axis中間(居中對齊)。

image

baseline

讓所有Flex項(xiàng)目在Cross-Axis上沿著他們自己的基線對齊怕享。

image
<!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)該能幫助你更好的理解搀玖。

image

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>
image

flex-start

之前你看到過flex-start。這次是讓多行Flex項(xiàng)目靠Cross-Axis開始邊緣牵囤。沿著Cross-Axis從上到下排列爸黄。因此Flex項(xiàng)目在Flex容器中頂部對齊。

image

flex-end

flex-end剛好和flex-start相反揭鳞,讓多行Flex項(xiàng)目靠著Cross-Axis結(jié)束位置炕贵。讓Flex項(xiàng)目沿著Cross-Axis從下到上排列,即底部對齊野崇。

image

center

你猜到了称开,center讓多行Flex項(xiàng)目在Cross-Axis中間。在Flex容器中居中對齊乓梨。

image

這是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-growflex-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>

添加更多的樣式,看起來像這樣:

image

默認(rèn)情況下稳强,flex-grow屬性值設(shè)置為0场仲。表示Flex項(xiàng)目不會增長,填充Flex容器可用空間退疫。取值為0就是一個開和關(guān)的按鈕渠缕。表示flex-grow開關(guān)是關(guān)閉的。

如果把flex-grow的值設(shè)置為1褒繁,會發(fā)生:

image

現(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-growflex-shrink屬性在各種情況下的效果,這樣能更好的幫助你理解谎替。

flex-basis

flex-basis屬性可以指定Flex項(xiàng)目的初始大小偷溺。也就是flex-growflex-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值)。

image

這意味著,如果你增加Flex項(xiàng)目中的內(nèi)容鸠按,它可以自動調(diào)整大小礼搁。

<ul>
    <li>I am a simple list AND I am a simple list</li>
</ul>

image

然而,如果你想將Flex項(xiàng)目設(shè)置一個固定的寬度目尖,你也可以這樣做:

li {
    flex-basis: 150px;
}

現(xiàn)在Flex項(xiàng)目的寬度受到了限制馒吴,它的寬度是150px

image

flex速記

flexflex-grow瑟曲、flex-shrinkflex-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-growflex-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)行為蘑志。

image

很容易理解這一點(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)目效果就是這樣子:

image

注意: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)容脖律。

image

應(yīng)該注意到的第一件事情是谢肾,這兩個彈性項(xiàng)目的寬度是不同的。因?yàn)閷挾仁腔趦?nèi)容寬度而自動計算的小泉,所以這是預(yù)料得到的芦疏。

試著縮放一下瀏覽器,你會注意到彈性項(xiàng)目不會收縮其寬度微姊。它們從父元素中突出來了酸茴,要看到所有內(nèi)容,必須橫向滾動瀏覽器柒桑。

image

在縮放瀏覽器時弊决,彈性項(xiàng)目不會收縮,而是從彈性容器中突出來了魁淳。

flex: 1 1 auto

這與 flex: auto 項(xiàng)目相同飘诗。

還是按我前面立的規(guī)矩。即界逛,自動計算初始化寬度昆稿,但是如果有必要,會伸展或者收縮以適應(yīng)整個可用寬度息拜。

伸展和收縮開關(guān)打開了溉潭,寬度自動被計算净响。

image

此時,項(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)都打開了低矮。不過,伸展度是不同的被冒,12军掂。

二者都會填滿可用空間轮蜕,不過是按比例的。

它是這樣工作的:前一個占 1/3 的可用空間蝗锥,后一個占 2/3 的可用空間跃洛。

image

即使兩個彈性項(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é)果:

image

如果你已經(jīng)忘了的話寸莫,flex: 1 1 auto 是與 flex-grow: 1捺萌、flex-shrink: 1flex-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)容相同再試試牵祟。

image

上面示例中的Flex項(xiàng)目是相對Flex項(xiàng)目痪蝇。

下面我們把Flex項(xiàng)目變成絕對的, 就是說這次它們的寬度是基于 flex 屬性涮阔,而不是內(nèi)容的大小猜绣。一行代碼就可以出奇跡。

li {
    flex: 1 ; /*與 flex: 1 1 0 相同*/
}

效果如下:

image

這次看到兩個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>

你可以看到如下的效果:

image

這里有幾件事情要注意:

  • flex-grow 值為設(shè)置為0懊蒸。這就解釋了為什么列表項(xiàng)不會伸展。
  • Flex項(xiàng)目向Main-Axis的開頭對齊(這是默認(rèn)行為)悯搔。
  • 由于項(xiàng)目被對齊到Main-Axis開頭骑丸,右邊就有一些多余的空間《拭玻看到了吧者娱?

image

現(xiàn)在在第一個列表項(xiàng)(branding)上使用 margin: auto,看看會出啥情況苏揣。

li:nth-child(1) {
    margin-right: auto; /*只應(yīng)用到右外邊距*/
}

image

剛剛發(fā)生了什么黄鳍?之前的剩余空間現(xiàn)在已經(jīng)被分配到第一個Flex項(xiàng)目的右邊了。

image

還記得我前面說的話吧平匈?當(dāng)在Flex項(xiàng)目上使用 margin: auto 時框沟,值為 auto 的方向(左、右或者二者都是)會占據(jù)所有剩余空間增炭。

如果想讓一個Flex項(xiàng)目的兩邊都用自動外邊距對齊忍燥,該怎么辦呢?

/* 如果愿意的話隙姿,也可以用 margin 簡寫來設(shè)置兩個邊 */
li:nth-child(1) {
    margin-left: auto;
    margin-right: auto
}

image

現(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;
}

image

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)航

image

AirBnB PC端導(dǎo)航

image

Twitter PC端導(dǎo)航

image

建議你自己寫代碼码党。試著自己實(shí)現(xiàn)這些導(dǎo)航系統(tǒng)。

切換flex-direction會發(fā)生什么斥黑?

還記得我說過默認(rèn)的Main-Axis方向是從左到右揖盘,Cross-Axis方向是從上到下吧?

image

好吧锌奴,現(xiàn)在你也可以改變這個方向兽狭。

正如在較早的小節(jié)中所描述的那樣,用 flex-direction: column 時鹿蜀,確實(shí)是這樣箕慧。

當(dāng)用 flex-direction: column 時,Main-Axis和Cross-Axis會向如下所看到的那樣改變:

image

如果曾用英語寫過文字茴恰,那么你就知道英語是從左到右颠焦,從上到下來寫的。

Flexbox的默認(rèn)Main-Axis和Cross-Axis也是采用同樣的方向往枣。

不過伐庭,如果將 flex-direction 切換為 column,它就不再遵循英語的范式分冈,而是日語的范式圾另!

是的,日語雕沉。

如果你用日語寫過文字集乔,那么應(yīng)該很熟悉了。(鄭重聲明坡椒,我從沒用過日語寫過文字)扰路。

日文通常是從上到下寫的尤溜!沒那么怪,對吧幼衰?

這就解釋了為嘛這對英語寫作者可能有點(diǎn)惱火靴跛。

image

看看下面這個例子。標(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>

如下是方向變化之前的樣子:

image

如下是方向變化之后的樣子:

image

現(xiàn)在文字是以日語風(fēng)格寫的:沿Main-Axis從上到下识椰。

你會看到項(xiàng)目的寬度填滿了空間绝葡,對吧?

如果在之前要變成這樣子腹鹉,得處理 flex-basis 以及 flex-grow 屬性藏畅。

下面來看看這些會如何影響新的布局。

li {
    flex-basis: 100px;
}

下面是你會得到的功咒。

image

什么愉阎?高度是被影響了,但是寬度沒有傲Ψ堋榜旦?我之前說過,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;
}

image

如果想把列表項(xiàng)移到屏幕中間該怎么辦呢?

在英語中纳本,這是你到目前為止處理彈性容器的方式窍蓝。就是說, 把Flex項(xiàng)目移到Main-Axis的中間 繁成。

所以吓笙,你會用 justify-content: center。但是這樣做不起作用巾腕。因?yàn)榉较蜃兞嗣婢Γ行氖茄刂鳦ross-Axis,而不是Main-Axis尊搬。

再來看看:


image

所以請用日語文字來思考叁鉴。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)居中了吧。

image

參考:
https://medium.freecodecamp.com/understanding-flexbox-everything-you-need-to-know-b4013d4dc9af#.pr6cltk9j

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末您没,一起剝皮案震驚了整個濱河市鸟召,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氨鹏,老刑警劉巖欧募,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仆抵,居然都是意外死亡跟继,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門镣丑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來舔糖,“玉大人,你說我怎么就攤上這事莺匠〗鹇穑” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長摇庙。 經(jīng)常有香客問我旱物,道長,這世上最難降的妖魔是什么卫袒? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任宵呛,我火速辦了婚禮,結(jié)果婚禮上夕凝,老公的妹妹穿的比我還像新娘宝穗。我一直安慰自己,他們只是感情好迹冤,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布讽营。 她就那樣靜靜地躺著,像睡著了一般泡徙。 火紅的嫁衣襯著肌膚如雪橱鹏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天堪藐,我揣著相機(jī)與錄音莉兰,去河邊找鬼。 笑死礁竞,一個胖子當(dāng)著我的面吹牛糖荒,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播模捂,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼捶朵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狂男?” 一聲冷哼從身側(cè)響起综看,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岖食,沒想到半個月后红碑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泡垃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年析珊,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔑穴。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡忠寻,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出存和,到底是詐尸還是另有隱情锡溯,我是刑警寧澤赶舆,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站祭饭,受9級特大地震影響芜茵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜倡蝙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一九串、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寺鸥,春花似錦猪钮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至笆载,卻和暖如春扑馁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背凉驻。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工腻要, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人涝登。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓雄家,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胀滚。 傳聞我的和親對象是個殘疾皇子趟济,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344