前端入門5-CSS彈性布局flex

聲明

本系列文章內(nèi)容全部梳理自以下四個來源:

作為一個前端小白充岛,入門跟著這四個來源學(xué)習(xí)虱岂,感謝作者的分享,在其基礎(chǔ)上蚂四,通過自己的理解哟忍,梳理出的知識點梅屉,或許有遺漏筐带,或許有些理解是錯誤的鹅经,如有發(fā)現(xiàn)寂呛,歡迎指點下。

正文-彈性布局flex

彈性布局的作用有點兒類似 Android 中 LinearLayout 和 RelativeLayout 兩者的合成版瘾晃,即:支持橫向布局贷痪,縱向布局,start蹦误,end劫拢,center 布局肉津,寬高按比例瓜分等等,當然它還有很多其他功能舱沧,比如自動換行妹沙,按指定 order 排列等」钒Γ總之有了 Android 基礎(chǔ)初烘,理解彈性布局 flex 蠻容易的。

可以這么的理解分俯,傳統(tǒng)的網(wǎng)頁布局方式是通過 display 和 position 以及 float 三者完成的肾筐,借助塊級元素,行內(nèi)元素特性缸剪,結(jié)合 position 指定的相對布局吗铐、絕對布局、固定布局方式來實現(xiàn)各種排版效果杏节。如果需要浮動唬渗,則借助 float。

但這種傳統(tǒng)的方式奋渔,一來使用較復(fù)雜镊逝,二來某些排版效果不好實現(xiàn),如列表嫉鲸、居中撑蒜、響應(yīng)式布局等效果。

而 flex 則能夠很好的完成傳統(tǒng)的布局工作玄渗,而且座菠,它還可以支持響應(yīng)式布局。

1.基礎(chǔ)概念

兩根軸線

當使用 flex 布局時藤树,首先想到的是兩根軸線:主軸和交叉軸浴滴。主軸由 flex-direction 定義,另一根軸垂直于它岁钓。我們使用 flexbox 的所有屬性都跟這兩根軸線有關(guān), 所以有必要在一開始首先理解它升略。

image

理解主軸和交叉軸的概念對于對齊 flexbox 里面的元素是很重要的;因為 flexbox 的特性是沿著主軸或者交叉軸對齊之中的元素屡限。

布局空白

布局空白:available space降宅,大概來說,flex 容器大小扣掉 items 的 flex-basis 指定的占據(jù)的空間大小之外剩余的區(qū)域囚霸,flex-basis 通常是指 item 本身的大小腰根,當然也可以手動設(shè)置。

flex 的一些屬性就是通過改變 flex 容器中的布局空白分配來達到對齊等效果的拓型。

比如 items 的 flex-grow 拉伸或者 flex 容器的 justify-content 主軸對齊等额嘿,其實就是將這些布局空白按照不同算法分配給各個 item瘸恼,分給 item 時,是要直接填充進 item 的內(nèi)容里達到拉伸效果册养,還是就簡單的將空白圍繞在 item 周圍達到類似 margin 效果來實現(xiàn) item 的居中东帅、靠左、靠右球拦、均分等對齊方式靠闭。

具體屬性不了解沒關(guān)系,下面的章節(jié)會講坎炼,知道概念即可愧膀。

2.flex相關(guān)屬性

對任意塊級元素標簽設(shè)置 display: flex 即可讓這個元素作為 flex 容器存在,也就可以使用 flex 的相關(guān)屬性了谣光。

flex 的屬性并不多檩淋,目前只有 13 個,其中有 7 個是 flex 彈性盒子容器本身所使用的屬性萄金,6 個是 flex-item 彈性盒子的子項使用的屬性蟀悦。其中,有些屬性只是將其他屬性的集中簡化使用氧敢,因此日戈,真正具有布局用途的屬性并不多,很好掌握孙乖。

作用于 flex 彈性盒子容器身上的屬性:

flex-direction

語法格式:

flex-direction: row(default) | row-reverse | column | column-reverse

用于設(shè)置主軸的方向涎拉,flex 分主軸和交叉軸兩個概念,items 布局時的圆,默認延主軸方向進行,因此通過設(shè)置主軸是水平方向還是垂直方向就可以實現(xiàn) items 的水平或垂直布局半火。

  • row:默認值越妈,設(shè)置主軸為水平方向
  • column:設(shè)置主軸為垂直方向

其他屬性就不介紹了,因為主軸方向就兩個钮糖,要么水平梅掠,要么垂直,其他的區(qū)別僅在于水平時是從左到右店归,還是從右到左阎抒,所以這個屬性的影響因素之一的 LTR 和 RTL,但沒必要考慮這么多消痛,這些場景應(yīng)該不多且叁,知道這個是用來設(shè)置主軸方向就夠了,我覺得秩伞。

示例:

image

flex-wrap

語法格式:

flex-wrap: nowrap(default) | wrap | wrap-reverse

用于設(shè)置是否允許換行逞带,默認值 nowrap欺矫。

當設(shè)置了 wrap 時,允許 items 在主軸方向溢出時自動進行換行布局展氓,這點可以很好的用來實現(xiàn)響應(yīng)式布局穆趴,比如當空間逐漸縮小時,原本水平排列的控件換成垂直方向排版遇汞。

示例:

image

flex-flow

語法格式:

flex-flow: <'flex-direction'> || <'flex-wrap'>

這個屬性并沒有另外的含義未妹,它只是 flex-direction 和 flex-wrap 的簡寫用法而已。

如果你不想單獨使用上述兩個屬性空入,可以將它們一起在 flex-flow 使用络它,如:

flex-flow: row wrap
//等效于
flex-direction: row;
flex-wrap: wrap;

justify-content

語法格式:

justify-content: normal(default) | <content-distribution> | <overflow-position>? [ <content-position> | left | right ]
where 
<content-distribution> = space-between | space-around | space-evenly | stretch
<overflow-position> = unsafe | safe
<content-position> = center | start | end | flex-start | flex-end

用于設(shè)置 items 在主軸方向上的對齊方式,可以靠左执庐,靠右酪耕,居中或者按比例均分等效果。

需要先明確一點概念轨淌,對齊是指 items 在 flex 容器中的排版對齊方式迂烁,那么要想 flex 容器可以控制 items 的對齊方式,那主軸方向上自然就還需要有布局空白递鹉,如果都沒有布局空白了,不就表明 items 已充滿 flex 容器了躏结,那談何對齊。

那么黄橘,如果存在至少一個 item绍昂,它的 flex-grow 屬性不等于 0絮供,justify-content 這個屬性就失效了帆赢,因為 flex-grow 表示允許 item 按照比例瓜分布局空白,這樣一來布局空白被瓜分完了线梗,flex 容器在主軸方向上已被 items 充滿椰于, 也就沒有對齊一說了。

所以要能夠正確的使用該屬性來控制 items 在主軸方向的對齊方式仪搔,那么就需要注意 item 中會影響布局空白的屬性瘾婿,如 flex-grow,flex-basis 這些的使用。

下面看看各屬性值介紹(下面的介紹不考慮 RTL 的情況憋他,默認都以 LTR 為主):

  • start:主軸是水平方向的話孩饼,左對齊方式排版;主軸是垂直方向的話竹挡,上對齊方式排版镀娶;
  • end:主軸是水平方向的話,右對齊方式排版揪罕;主軸是垂直方向的話梯码,下對齊方式排版;
  • center:居中方式排版好啰;
  • space-between:等比例瓜分布局空白轩娶,每行首元素對齊,末元素對齊框往,每行各元素間距一致鳄抒;
  • space-around:與上述的類似效果,區(qū)別僅在于椰弊,每行首元素并不是在 flex 容器內(nèi)容區(qū)域左邊就開始布局许溅,它距離 flex 容器左邊的距離等于各個元素之間間距的一半。說白點秉版,就是行首元素和末尾元素的周邊有類型 margin 值存在贤重。

剩余的屬性值不介紹了,因為我也還沒有搞懂它們的含義和應(yīng)用場景清焕。

示例:

image

(ps:flex 容器設(shè)置了 padding,所以 start 和 end 才沒有貼靠邊界 )

align-items

語法格式:

align-items: normal | stretch | <baseline-position> | [ <overflow-position>? <self-position> ]
where 
<baseline-position> = [ first | last ]? baseline
<overflow-position> = unsafe | safe
<self-position> = center | start | end | self-start | self-end | flex-start | flex-end

用于控制 items 在交叉軸方向上的排版布局方式滚停,justify-content 是能控制主軸上的排版键畴,而這個屬性則是用于控制交叉軸,通常兩個都會一起使用挂签,相互結(jié)合饵婆,可以達到一些類似頁面居中效果侨核。

看看屬性值:

  • flex-start:交叉軸方向悲柱,從起點開始布局排版
  • flex-end:交叉軸方向些己,從末尾開始布局排版
  • center:交叉軸方向涯冠,從中間開始布局排版
  • stretch:交叉軸方向逼庞,如果 items 在交叉軸方向沒有設(shè)置大小,那么讓 items 在交叉軸的方向充滿 flex 容器的高度派任。

其他屬性不介紹了吨瞎,不熟悉颤诀。

示例:

image

(ps:flex 容器設(shè)置了 padding,所以 start 和 end 才沒有貼靠邊界 )

stretch 要能夠生效拍柒,需要在 items 在交叉軸方向的不設(shè)置大小脂男,如上圖中主軸是水平方向宰翅,那么 items 需要不設(shè)置 height汁讼,此時 stretch 才能夠讓 items 拉伸占據(jù)交叉軸的高度瓶珊。

有一點需要注意耸彪,當 flex 容器的 items 在主軸方向上只有一行時丑瞧,可以很明確的使用這個屬性來控制在交叉軸的排版方式绊汹。但西乖,如果 items 在主軸上超過一行获雕,那么最終的效果可能就不是想要的了,比如下圖:

image

如果是想實現(xiàn)多行的 items 都作為一個整體居中罢艾,那么用 align-items 就無法實現(xiàn)了,針對這種有多行的情況童漩,需要用另外一個屬性來控制:align-content矫膨。

align-content

語法格式:

align-content: normal | <baseline-position> | <content-distribution> | <overflow-position>? <content-position>
where 
<baseline-position> = [ first | last ]? baseline
<content-distribution> = space-between | space-around | space-evenly | stretch
<overflow-position> = unsafe | safe
<content-position> = center | start | end | flex-start | flex-end

當 flex 容器的 items 設(shè)置了溢出換行屬性,且當前在交叉軸方向上存在多行 item 的情況下呐萌,該屬性才會生效搁胆。

網(wǎng)上有種翻譯渠旁,說這個屬性是用于軸對齊粤铭,我不是很理解梆惯,我自己粗俗的分兩種情況理解:

當需要進行 start, center, end 這些排版時垛吗,是將這些多行的 items 都看成一個整體,然后進行交叉軸方向上的排版控制饵沧。此時羡儿,將多行 item 看成一行之后掠归,那么這個 align-content 之后的排版布局就跟 align-items 一樣的效果了拂到。

其他的 space-around,space-between 究竟是如何計算排版的领铐,不熟悉绪撵。

屬性值含義不看了音诈,跟 align-items 一樣的效果褥傍,直接看示例:

image

(ps:flex 容器設(shè)置了 padding恍风,所以 start 和 end 才沒有貼靠邊界 )

place-content

語法格式:

place-content: <'align-content'> <'justify-content'>?

這個屬性并沒有另外的含義,它只是 align-content 和 justify-content 的簡寫用法而已锦募。

如果你不想單獨使用上述兩個屬性,可以將它們一起在 place-content 使用削解,如:

place-content: center center
//等效于
align-content: center;
justify-content: center;

作用于 flex-item 彈性盒子的子項身上的屬性:

flex-basis

語法格式:

flex-basis: content | <'width'>

where 
<'width'> = [ <length> | <percentage> ] && [ border-box | content-box ]? | available | min-content | max-content | fit-content | auto

用于設(shè)置 items 在主軸方向的大小氛驮,如果主軸是水平方向,相當于設(shè)置 width蓖扑,此時律杠,該屬性值會覆蓋掉 width 設(shè)置的大小。

image

嘗試了下,在 chorme 瀏覽器上 content 屬性不生效浑厚,不清楚物蝙,可能不同瀏覽器行為還不一樣,既然這樣丽惭,就先暫時不深入了解這個屬性了责掏,大概知道用于設(shè)置主軸方向上的 item 大小即可换衬。

就算要使用,先直接用指定數(shù)值大小的方式好了证芭。

flex-grow

語法格式:

flex-grow: <number>

用于設(shè)置 item 在主軸方向上的拉伸因子瞳浦,即如果 flex 容器還有剩余空間,會按照各 item 設(shè)置的拉伸因子比例關(guān)系分配废士。默認值為 0叫潦,即不拉伸。

作用很像 Andorid 中的 LinearLayout 的 child 里設(shè)置了 layout_weight 用途一樣官硝。

示例:

image

flex-shrink

語法格式:

flex-shrink: <number>

用于設(shè)置 item 在主軸方向上的收縮因子矗蕊,跟 flex-grow 剛好反著來傻咖。當 flex 容器空間不夠,item 要溢出時筝家,設(shè)置次屬性可控制 item 按比例進行相應(yīng)收縮移国,以便不讓 item 溢出祝懂,默認 1,值越大收縮倍數(shù)越大,最后 item 就越小响鹃,0 表示不收縮蓉冈,負值無效伐弹。

另外日川,如果設(shè)置了換行屬性傀蓉,那么這個就無效了蹄胰。換行和收縮都是用于解決 item 在主軸方向上溢出的問題,既然是互斥绅络,且換行優(yōu)先級高此叠,那么設(shè)置了換行,就不會再對 item 進行收縮了智玻。

示例:

image

flex

語法格式:

flex: none | auto | initial | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]

這屬性是 flex-grow,flex-shrink沪饺,flex-basis 三個屬性的簡化使用攘烛,有三種屬性值:

  • none:元素會根據(jù)自身寬高來設(shè)置尺寸麻敌。它是完全非彈性的:既不會縮短乙漓,也不會伸長來適應(yīng)flex容器嚼贡。相當于將屬性設(shè)置為 flex: 0 0 auto剩辟。
  • auto:元素會根據(jù)自身的寬度與高度來確定尺寸艇棕,但是會自行伸長以吸收flex容器中額外的自由空間彩扔,也會縮短至自身最小尺寸以適應(yīng)容器。這相當于將屬性設(shè)置為 flex: 1 1 auto.
  • initial:屬性默認值洋措, 元素會根據(jù)自身寬高設(shè)置尺寸济蝉。它會縮短自身以適應(yīng)容器,但不會伸長并吸收flex容器中的額外自由空間來適應(yīng)容器 菠发。相當于將屬性設(shè)置為"flex: 0 1 auto"王滤。

flex 屬性可以指定 1 個,2 個或 3 個值滓鸠。

單值語法: 值必須為以下其中之一:

  • 一個無單位數(shù)(<number>): 它會被當作 <flex-grow>的值雁乡。
  • 一個有效的寬度(width)值: 它會被當作 <flex-basis>的值。
  • 關(guān)鍵字 none, auto,或initial.

雙值語法: 第一個值必須為一個無單位數(shù)糜俗,并且它會被當作<flex-grow>的值踱稍。第二個值必須為以下之一:

  • 一個無單位數(shù):它會被當作<flex-shrink>的值。
  • 一個有效的寬度值: 它會被當作<flex-basis>的值悠抹。

三值語法:

  • 第一個值必須為一個無單位數(shù)珠月,并且它會被當作<flex-grow>的值。
  • 第二個值必須為一個無單位數(shù)楔敌,并且它會被當作 <flex-shrink>的值啤挎。
  • 第三個值必須為一個有效的寬度值, 并且它會被當作<flex-basis>的值卵凑。

align-self

語法格式:

align-self: auto | normal | stretch | <baseline-position> | <overflow-position>? <self-position>
where 
<baseline-position> = [ first | last ]? baseline
<overflow-position> = unsafe | safe
<self-position> = center | start | end | self-start | self-end | flex-start | flex-end

用于給單個 item 設(shè)置交叉軸方向上的排版布局方式庆聘,屬性值和作用跟 align-items 一樣,區(qū)別僅在于 align-items 是 flex 容器的屬性勺卢,它會作用于所有的 items 上伙判;而 align-self 允許對單個 item 設(shè)置,該值會覆蓋 align-items 設(shè)置的屬性值值漫。

這樣就可以實現(xiàn)控制交叉軸上的每個 item 的不同布局方式澳腹,如下:

image

order

語法格式:

order: <integer>

用于控制 items 的排版順序织盼,item 將按照 order 屬性值的增序進行布局。擁有相同 order 屬性值的元素按照它們在源代碼中出現(xiàn)的順序進行布局酱塔。默認值為 0沥邻,可設(shè)置負值,排序?qū)⒃谀J不設(shè)置的 item 前面羊娃。

示例:

image

小結(jié)

我覺得唐全,這些屬性大體記得每個屬性的主要用途即可,至于每個屬性值如何設(shè)置蕊玷,如何相互結(jié)合使用可以達到什么樣的效果邮利,寫代碼的時候再調(diào)就是了。

3.應(yīng)用場景

以下場景中垃帅,如沒有特別指明延届,flex 容器基本樣式和 item 基本樣式如下:

.flex
{
    width: 200px;
    height: 200px;
    border-radius: 20px;
    background-color: #FFFFFF;
}

.dot {
    width: 50px;
    font-size: 28px;
    line-height: 50px;
    text-align: center;
    color: #FFFFFF;
    height: 50px;
    border-radius: 25px;
    background-color: black;
}

長這個樣子:

image

白色區(qū)域是 flex 容器,黑色圓圈是 item贸诚。

場景1:

在頁面中把一個元素居中:item 水平方庭、垂直方向都居中

.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
    justify-content: center;/*水平居中*/
    align-items: center;/*垂直居中*/
}

image

場景2:

前后有固定大小 item,中間區(qū)域自動拉伸占據(jù)可用空間酱固。

<style >
.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
}
</style>

<div class="flex">
    <div class="dot" >1</div>
    <div class="dot" style="flex-grow: 1">2</div>
    <div class="dot" >3</div>
</div>

image

場景3:

響應(yīng)式布局械念,在屏幕尺寸允許的情況下呈水平布局,但是在屏幕不允許的情況下可以水平折疊运悲。

.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
    flex-wrap: wrap;/*溢出時換行*/
}

image

場景4:

水平排列的一組 item 中龄减,前幾個左對齊,后幾個右對齊班眯。

這個需要結(jié)合塊級元素的 margin 屬性使用希停,當設(shè)置 margin: auto 時表示,將盡可能占據(jù)足夠多的空間鳖敷。

<style >
.flex
{
    display: flex;/* 聲明這個元素作為 flex 容器 */
    flex-direction: row;/*主軸為水平方向*/
}
</style>

<div class="flex">
    <div class="dot" >1</div>
    <div class="dot" >2</div>
    <div class="dot" margin-left="auto">3</div>
</div>

image

鏈接:http://www.reibang.com/p/e4906a31767f

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脖苏,一起剝皮案震驚了整個濱河市程拭,隨后出現(xiàn)的幾起案子定踱,更是在濱河造成了極大的恐慌,老刑警劉巖恃鞋,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件崖媚,死亡現(xiàn)場離奇詭異,居然都是意外死亡恤浪,警方通過查閱死者的電腦和手機畅哑,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來水由,“玉大人荠呐,你說我怎么就攤上這事。” “怎么了泥张?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵呵恢,是天一觀的道長。 經(jīng)常有香客問我媚创,道長渗钉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任钞钙,我火速辦了婚禮鳄橘,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘芒炼。我一直安慰自己瘫怜,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布本刽。 她就那樣靜靜地躺著宝磨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盅安。 梳的紋絲不亂的頭發(fā)上唤锉,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音别瞭,去河邊找鬼窿祥。 笑死,一個胖子當著我的面吹牛蝙寨,可吹牛的內(nèi)容都是我干的晒衩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼墙歪,長吁一口氣:“原來是場噩夢啊……” “哼听系!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起虹菲,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤靠胜,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后毕源,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體浪漠,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年霎褐,在試婚紗的時候發(fā)現(xiàn)自己被綠了址愿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡冻璃,死狀恐怖响谓,靈堂內(nèi)的尸體忽然破棺而出损合,到底是詐尸還是另有隱情,我是刑警寧澤娘纷,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布塌忽,位于F島的核電站,受9級特大地震影響失驶,放射性物質(zhì)發(fā)生泄漏土居。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一嬉探、第九天 我趴在偏房一處隱蔽的房頂上張望擦耀。 院中可真熱鬧,春花似錦涩堤、人聲如沸眷蜓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吁系。三九已至,卻和暖如春白魂,著一層夾襖步出監(jiān)牢的瞬間汽纤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工福荸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蕴坪,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓敬锐,卻偏偏與公主長得像背传,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子台夺,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容