Flex 是 CSS3 推出的一種佈局方式,至今有超過十年時間了 要實現 Flex 佈局很容易,只需要給一個元素的 屬性設置為 就行 咋看之下好像沒什麼變化,那是因為受到影響的其實是其內部的元素,給這個容器內添加幾個元素就可以看到效果 可以看到的是預設情況下應該獨占一行的 `` 元素現在全部擠在了一 ...
Flex 是 CSS3 推出的一種佈局方式,至今有超過十年時間了
要實現 Flex 佈局很容易,只需要給一個元素的 display
屬性設置為 flex
就行
.box {
display: flex;
}
咋看之下好像沒什麼變化,那是因為受到影響的其實是其內部的元素,給這個容器內添加幾個元素就可以看到效果
<div class="box">
<div class="item-1">1</div>
<div class="item-2">2</div>
<div class="item-3">3</div>
</div>
可以看到的是預設情況下應該獨占一行的 <div>
元素現在全部擠在了一行,這就是 flex 的效果,也就是說只要一行代碼就實現了 flex 佈局,不愧為大神級理解
flex-direction
簡單的說,佈局其實就是一個怎麼擺放的問題,內部那些元素既然可以擺成一行,當然也可以擺成一列,只需要向容器添加一個 flex-direction
屬性,就能改變內部元素的擺放方向
.box {
flex-direction: column;
}
當其值為 column
的時候即為按列,而之前的預設值是 row
,一旦確定了擺放方向後,則該方向成為 flex 的主軸,用箭頭來表示就像這樣
flex-direction: row
flex-direction: column
另外還有兩個擺放方向,就是這兩者相反的方向
flex-direction: column-reverse
flex-direction: column-reverse
justify-content
有了方向之後,就有了起點和終點,前面這些元素都是擠在主軸的起點位置,我們可以通過添加一個 justify-content
屬性改變這些元素在主軸上的位置
.box {
justify-content: flex-end;
}
這樣就全部跑到主軸的終點位置去了
justify-content: flex-end
也能擺在中間
justify-content: center
理所當然的預設值就應該是起點了 flex-start
,除了這種一鍋端式的對齊方式外,還能讓這些元素均勻地分佈於主軸上,有3種方式
1種是兩端不留空,兩端的元素和容器之間無間隔
justify-content: space-between
1種是兩端留空,兩端的元素和容器之間也有同等的間隔
justify-content: space-evenly
還有1種是每個元素兩邊留相等的間距,這種情況下兩端的元素和容器之間的距離是元素之間距離的一半
justify-content: space-around
align-items
另外和主軸垂直的一個方向稱為交叉軸,不同於主軸,元素也可以在交叉軸上挪動位置,只需要給容器添加一個 align-items
屬性
.box {
align-items: stretch;
}
這是預設值,也就是說預設情況下元素在交叉軸上是拉伸的
align-items: stretch
此外還有3種普通對齊方式,即起點(flex-start),終點(flex-end)和居中(center)
align-items: flex-start|center|flex-end
另外還有一個值是 baseline
,這是根據文字的基線對齊,改變每一項文字的大小可以看出效果
align-items: baseline
在主軸上對齊使用 justify-content
,在交叉軸上對齊使用 align-items
,這個一定要記清,因為它喵的還有個 align-content
屬性!
flex-wrap
前面在容器中一直都只有3個元素,假如我們給添加到30個會怎樣?
會傻傻地擠在一堆,哪怕容器已經放不下了,因為預設是不會自動換行的,需要給容器添加一個 flex-wrap
屬性
.box {
flex-wrap: wrap;
}
flex-wrap: wrap
除了這種理所當然的換行方式外,還有一種意想不到的反方向換行方式
flex-wrap: wrap-reverse
為什麼會有這麼一種奇葩的換行方式呢,因為前面 flex 的主軸由 flex-direction
屬性定義,總共有4個方向,而交叉軸是垂直於主軸的,但其方向是固定的,如果主軸橫向的話,無論向左還是向右,交叉軸都是自上而下;而如果主軸是縱向的話,那麼交叉軸就是從左至右。但是這個 flex-wrap: wrap-reverse
屬性設置之後就會改變交叉軸的方向,原本的起點和終點的位置就交換了
align-items: flex-start; flex-wrap: wrap-reverse
可以看到,交叉軸的起點跑到容器下沿去了,說明這時候交叉軸是自下而上的。不過如果經常使用的是居中對齊或者均勻分佈的話根本不用關心什麼起點終點的
align-content
說到均勻分佈,前面只提到可以在主軸上均勻分佈,但當參與佈局的元素多到已經一行或是一列裝不下的時候,在交叉軸上也是可以均勻分佈的,這就需要前面提到的 align-content
屬性,其值和 justify-content
一樣,這兩個屬性才是對應的,同樣有3種均勻分佈方式
align-content: space-between|space-evenly|space-around
以及起點,終點和居中對齊等等
align-content: flex-start|flex-end|center
其預設值是 stretch
order
一直以來容器里的元素都是按順序擺放的,那麼可不可以自由調整元素的擺放順序呢,比如將第2個元素擺到最前面呢,當然,只需要添加一個 order
屬性即可,需要註意的是前面添加的所有屬性都是針對容器內的所有元素的,因而那些屬性都是設置在容器上的,而這時只是想改變第2個元素的順序,因此 order
屬性需要添加到對應的元素上
.item-2 {
order: -1;
}
因為 order
的預設值是 0,只需要給個比 0 小的值就可以擺到前面,同理,給個比 0 大的值就可以擺到末尾去,給每個元素設置一個不一樣的 order
的值就會按照從小到大的順序依次擺放
align-self
既然可以單獨改變某個元素的順序,那麼是不是也可以單獨改變某個元素的對齊方式呢,讓這個元素不跟著大部隊一起走,特立獨行一點,這當然是可以的,需要用到 align-self
屬性,它的值和 align-items
基本一樣,同樣是 align-
首碼,那就意味著是在交叉軸上使用自己的對齊方式
.item-2 {
align-self: flex-end;
}
align-self: flex-end
那麼在主軸上能不能使用特立獨行的對齊方式呢,比如有沒有一個 justify-self
屬性,目前來看好像貌似不得行。
flex
雖然在交叉軸上元素會預設拉伸,但是在主軸上當元素比較少的時候會留有很多空間,這時候就要祭出可能是 Flex 的最後一個屬性了,那就是 flex
,給每個元素都添加一個值為 1 的 flex
屬性
.item {
flex: 1;
}
這樣所有元素就會平分容器的空間
而給每個元素設置不同的值,則會按比例分配空間
.item-1 {
flex: 2;
}
.item-2 {
flex: 1;
}
.item-3 {
flex: 3;
}
由於 2 + 1 + 3 = 6,根據比例第 1 項分得 1/3,第 2 項得到 1/6,第 3 項得到一半
這個數值越大,分得越多,預設值是 0,那就相當於是凈身出戶,一點都不要了,當只給一個元素設置值為 1 的時候,這個元素就會獨享主軸上的剩餘空間,當值小於 1 的時候會按這個小數的比例來分配
flex
屬性還有第 2 個值,第 2 個值和第 1 個值剛好相反,第 1 個值規定容器空間太多的時候每個元素怎麼分,第 2 個值則是規定當元素空間不足以容納這所有元素的時候,每個元素應該如何縮小來騰出足夠的空間,其預設值是 1,表示預設情況下所有元素都會自行縮小,這個數值越大,表示責任就越大,需要為騰出空間出更多力,為 0 則表示這是只鐵公雞一毛不拔,只能讓其它不為 0 的元素來縮小以騰出空間
.item {
flex: 0 1;
}
flex
屬性還有第三個值,規定某個元素在主軸上占據的空間,預設值是 auto
,表示元素占據的空間由其自身決定,其值可以是各種長度單位
.item {
flex: 0 1 60px;
}
由此 flex
的完整預設值就是 0 1 auto
,這是個簡寫屬性,由 flex-grow
,flex-shrink
和 flex-basis
這 3 個屬性組成,如果只想單獨設置其中某個值的時候可以用到
.item {
flex-grow: 0;
flex-shrink: 1;
flex-basis: 60px;
}