JavaScript五十問——對比來講CSS的Grid與FlexBox(上篇)

前言

春節假期有幸拜讀了張鑫旭大大的關於Flex與Grid的兩篇文章(見參考文獻),頗有收穫;本身在開發的過程當中,不少時候都會採用Flex佈局,而Float與inline-box這種方式已經不多使用了;此次在春假期間學習了Grid,深感Grid的好用與便利。趁着此次機會總結一下Grid與Flex的使用。css

瀏覽器支持

  • Flex 瀏覽器支持狀況

Flex瀏覽器支持狀況.png

  • Grid瀏覽器支持狀況

Grid瀏覽器支持狀況.png

能夠看出來,相對於Grid來講,Flex不管實在PC端仍是移動端都獲得了很好的支持,而Grid,在移動端的支持仍是差強人意。html

FlexBox

在flex佈局中,有兩個概念須要謹記:容器與元素。在一個html標籤中聲明樣式:display:flexordisplay:inline-flex即聲明瞭一個flex的容器,在這個容器裏面的元素即爲flex元素。而flex全部的樣式屬性分爲兩類:容器屬性元素屬性,他們均做用於flex元素,只不過flex容器中聲明的屬性統領flex全部元素總體顯示與排布方式,而flex元素的屬性表示單一元素的排布方式。css3

Flex屬性腦圖.png

下面,根據上面腦圖的思路,依次介紹flex的屬性。
聲明:
下面師範的全部元素都聽從如下HTML結構 和基本樣式面試

<style>
.container{
  height:200px;
  background-color:#999;
}
.container >.item{
  background-color:#456;
  width:80px;
  font-size:30px;
  color:white;
  text-align:center;
}
</style>
<div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    ...
</div>

容器屬性

flex-direction

flex-direction顧名思義,是控制flex元素的總體佈局方向的,它包括四個屬性:瀏覽器

1.row //從左到右 默認
2.row-reverse //從右到左
3.column //從上到下
4.column-reverse //從下到上

一、flex-direction:row
row.pngwordpress

2.flex-direction:row-reverse
row-reverse.png佈局

3.flex-direction:column
column.png
4.flex-direction: column-reverse
columu-reverse.png學習

上面四個圖是分別在容器上(.container)設置flex-direction四個屬性獲得的效果。flex

flex-wrap

flex-wrap是控制元素是換行顯示仍是單行顯示,它共有三個屬性spa

1.no-wrap //不換行 默認
2.wrap // 換行
3.wrap-reverse //換行反序

爲了更加明顯的看出區別,我特別添加了一個難看的邊框。
在容器屬性上添加flex-wrap,分別設置三個wrap屬性
1.flex-wrap: no-wrap

no-wrap.png

2.flex-wrap: wrap
wrap.png

3.flex-wrap: wrap-reverse
wrap-reverse.png
在這裏須要注意no-wrap屬性:
若是容器元素設置了最小寬度,並且元素的最小寬度之和>父容器的寬度,則顯示內容溢出。
若是容器元素沒有設置最小寬度或者最小寬度之和<父容器的寬度,則容器元素收縮並將父元素填滿,在上面no-wrap例子中,就沒有設置子元素的最小寬度,讀者能夠自行添加驗證。

設置wrap-reverse屬性後,咱們能夠看到它的換行結果與wrap的換行結果在這一維度上是相反的。

讀者能夠試試將flex-direction設置爲column或者其餘非默認值,再查看在不一樣的flex-wrap值下的顯示,會有不一樣的結果喲。

flex-flow

flex-flow是 flex-direction與flex-wrap的統寫,語法是
flex-flow:<‘flex-direction’> || <‘flex-wrap’>

justify-content

justify-content控制flex元素水平方向的對齊方式,它共有 個屬性:

1.flex-start // 默認值 默認狀況下左對齊
2.flex-end // 右對齊
3.center // 居中
下面以space開頭的屬性都是描述剩餘空間的排布方式的
4.space-around //剩餘空間圍繞在每一個子元素的周圍
5.space-between //剩餘空間只分布在子元素之間,兩端元素左右沒有剩餘空間
6.space-evenly // 剩餘空間均勻分佈在元素兩端、之間

下面看例子:
1.flex-start

flex-start.png

2.flex-end

flex-end.png

3.center

center.png

4.space-between

space-between.png

5.space-around

space-around.png

6.space-evenly
clipboard.png
爲了更加明顯的看出不一樣space下的額外空間分佈特色,我使用紅框框出每一屬性下的剩餘元素。幾個屬性分佈不一樣不言而喻了。

align-content

align-content與justify-content對應,表明元素垂直方向上的分佈。而這種分佈方式只有在多行的狀況下才可以凸顯出來,單行狀況下設置此屬性無效。
相對於justify-content,它多出來一個stretch的屬性,表明拉伸,默認屬性。

1.stretch

clipboard.png

2.flex-start

clipboard.png

3.flex-end

clipboard.png

4.space-between

clipboard.png

5.space-around

clipboard.png

6.space-evenly

clipboard.png

能夠看出,它的排布方式與justify-content的邏輯是一致的,只不過方向不一樣而已。

align-items

既然有了多行狀況下控制元素排布方式,就會有單行狀況下元素排布方式。align-items就是在單行狀況下,控制元素排布方式的。共有5個屬性:
1.stretch 默認屬性,會將元素的高度拉伸至父容器的高度

clipboard.png

2.flex-start 頂部對齊

clipboard.png

3.flex-end 底部對齊

clipboard.png

4.baseline 基線對齊

clipboard.png

5.center 居中

clipboard.png

注意:以上全部的例子展現都是在其餘屬性默認狀況的顯示狀況,若是更改其餘屬性(如:
flex-directionflex-wrap)值,會有不一樣的顯示效果。

元素屬性

order

order屬性能夠控制flex元素的排布順序,flex元素會根據order從小到大依次排布,order的默認值爲0,所以若是想要某個元素排在前面,只須要將他的order值設爲比0小的值便可。

flex-grow

flex-grow控制元素所佔寬度,默認值爲0,當容器內有剩餘空間時,flex-grow不爲0的元素將會按照如下規則擴展:

  • 容器中只有一個元素設置了flex-grow
    一、flex-grow 值>=1 那麼這個元素會填充容器的剩餘空間

clipboard.png

.container .item:first-child{
  order:2;
  flex-grow:1;
}
二、flex-grow 在0-1之間,那麼這個元素會多佔用空間爲剩餘空間乘以這個flex-grow的值。

clipboard.png

.container .item:first-child{
  order:2;
  flex-grow:0.5;
}

clipboard.png

.container{
  display:flex;
  justify-content:space-around;//若是子元素的flex-grow<1,此屬性依然有效
}

.container .item:first-child{
  order:2;
  flex-grow:0.5;
}
  • 容器中有多個元素設置了flex-grow
    一、全部元素的flex-grow的值之和>1
    則佔用所有的剩餘空間,多佔用的剩餘空間比例即爲各個元素所設置flex-grow的比例。
    二、全部元素的flex-grow的值之和<1
    所佔用的剩餘空間的比例即爲各個元素的felx-grow的值的比例。

flex-shrink

flex-shrink的屬性與flex-grow相反,指的是當空間不足的時候,元素的收縮比例,默認值爲1;其核心思路與grow一致,這裏再也不贅述,讀者能夠自行檢驗。

flex-basis

flex-basis定義了在分配剩餘空間以前,每一個元素的默認寬度,默認爲auto即元素的寬度;當flex-basis的值不爲auto時,其顯示的優先級是高於元素的width的。

flex

flex屬性爲以上三個屬性的統稱,語法爲:
flex: none | auto | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
flex翻譯爲中文就是彈性的,因此這個屬性就是說明當有空間過大or空間不足時,每一個元素如何分佈。

align-self

align-self顧名思義,就是肯定單個元素垂直分佈狀態;其在父容器對應的屬性是algin-items;
其屬性值有align-items一致,只不過多了一個auto默認屬性,表示與父元素的auto-items值一致。
來看例子:

clipboard.png
對應css代碼:

.container{
  display:flex;
  align-items:center;
}

.container .item:nth-child(2n+1){
  order:2;
  flex-grow:2;
  align-self:flex-start;
}

我在父元素上添加align-items屬性,使flex元素居中對齊,在子元素上添加align-self屬性,使奇數子元素向上對齊。

clipboard.png
當有多行的狀況下,可是align-content未設置,咱們能夠看到,每個設置了align-self屬性的子元素會在當前的行按照align-self屬性顯示,可是當align-content屬性設置後,其align-self屬性失效(見下圖)。

clipboard.png
對應代碼:

.container{
  display:flex;
  align-content:center;
  flex-wrap:wrap;
}

.container .item:nth-child(2n+1){
  order:2;
  flex-grow:2;
  align-self:flex-start;
}

總結

flex佈局就總結到這裏,裏面有些相似屬性沒有舉例子,還須要讀者本身去驗證。相對於其餘解決方案,flex佈局更加簡潔,也更加具備語義性;最顯而易見的,能夠很方便的解決咱們平時面試過程當中遇到的多欄佈局,垂直居中問題。
其實細細品讀flex,相比於Grid而言,他仍是更加線性化,就是把全部的元素都當作一條線,肯定這條線的方向、居中垂直方式,當這條線超過父元素的範圍,咱們怎樣處理。因此,雖然flex看似有許多屬性,可是合理的理解後,仍是很是簡單的。

這篇是glex與Grid的上篇,主要介紹了flex,而Grid的相關屬性與應用,咱們下篇見。

參考文獻

張鑫旭:寫給本身看的display: flex佈局教程
阮一峯:Flex 佈局教程

相關文章
相關標籤/搜索