原文首發於個人博客:不再混淆,一次搞懂!圖解flexbox十余個屬性
flexbox的發明簡直是csser的一大福音,終於可以不再需要為垂直居中一個元素而絞盡腦汁了。同時它還能夠實現彈性布局,可以說沒有它做不到,只有你想不到。但是由於歷史原因,flexbox的有多個版本在市面上流通,需要使用不同的廠商前綴或者使用完全不一樣的屬性名,起初的時候造成人們使用的困擾。
不過后來隨着css后處理器的出現,使得我們在用起flexbox來,幾乎不用擔心瀏覽器兼容的問題了。相關博文:還在手動給css加前綴?no!幾種自動處理css前綴的方法簡介
一、flexbox是什么?
從字面上來看,flexbox是可伸縮的盒子的意思。我們可以讓這個盒子里的子項,根據我們的需要拉伸、對齊、排序。設置父元素為flexbox,即可激活這個彈性機制。方法如下:
首先我們來設置html
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
接下來設置css
.parent {
display:flex; // 類似display:block的flexbox
}
或者
.parent {
display:inline-flex; // 類似display:inline-block的flexbox
}
二、屬性太多很難記?
和flexbox相關的屬性繁多,每個屬性又有不同的值,要一時半會全部記住是不太可能,但是我們可以分類記憶,在腦中有印象后在使用時勤查文檔,相信要熟練應用還是會很快的。記憶flexbox只需要記住兩點:
- 所有的屬性分為兩類:父容器的屬性和子項的屬性
- 所有的屬性值幾乎都和排列、對齊、占地面積3類特性相關
父容器屬性
屬性 | 作用 | 特性分類 |
---|---|---|
flex-direction | 定義子項在容器內的排列方向 | 排列 |
flex-wrap | 定義子項在容器內的換行效果 | 排列 |
flex-flow | flex-direction和flex-wrap的復合屬性 | 排列 |
justify-content | 定義子項在容器內水平對齊方式 | 對齊 |
align-items | 定義 子項在容器內垂直對齊方式 | 對齊 |
align-content | 定義多行子項在容器內整體垂直對齊方式 | 對齊 |
子項屬性
屬性 | 作用 | 特性分類 |
---|---|---|
order | 定義子項們的排列順序 | 排列 |
flex-grow | 定義子項寬度之和不足父元素寬度時,子項拉伸的比例 | 占地面積 |
flex-shrink | 定義子項寬度之和超過父元素寬度時,子項縮放的比例 | 占地面積 |
flex-basis | 定義子項的初始寬度,若子項寬度之和超過父元素寬度時,子項按照flex-basis的比例縮放 | 占地面積 |
align-self | 定義單個子項與其他項目不一樣的對齊方式 | 對齊 |
三、圖解父容器的屬性
我們逐一來看看效果,先來看看父元素的屬性(不要忘了我們已經在父元素上加上了display:flex哦,下面為了更直觀對比隱藏了這個設置)
3.1 flex-direction屬性
定義子項在容器內的排列方向
.parent {
flex-direction: row | row-reverse | column | column-reverse;
}
3.2 flex-wrap屬性
定義子項在容器內的換行效果
.parent {
flex-wrap: nowrap | wrap | wrap-reverse;
}
3.3 flex-flow屬性
flex-flow是flex-direction和flex-wrap兩個屬性的簡寫,參考以上兩個屬性的寫法即可,在此略過。
3.4 justify-content屬性
定義子項在容器內水平對齊方式
.parent {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
3.5 align-items屬性
定義 子項在容器內垂直對齊方式
.parent {
align-items: flex-start | flex-end | center | baseline | stretch;
}
3.6 align-content屬性
定義多行子項在容器內整體垂直對齊方式
.parent {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
四、圖解子項的屬性
4.1 order屬性
定義子項們的排列順序
.child{
order:[integer] /* 傳入整數,default 0 */
}
flex-grow屬性
定義子項寬度之和不足父元素寬度時,子項拉伸的比例
.child{
flex-grow:[number] // 傳入數字
}
4.2 flex-shrink屬性
定義子項寬度之和超過父元素寬度時,子項縮放的比例
.child{
flex-shrink:[number] /* 傳入數字, default 1*/
}
說明:
flex-shrink的默認值為1,瀏覽器將超出的空間,按照收縮因子相加之后計算比率來進行空間收縮。
圖例中4定義了flex-shrink:2,其余子項定義了flex-shrink:1,這樣可以看到總共將剩余空間分成了6份,4個1份,1個2份,即1:1:1:2:1。
我們給父容器width定義為800px,子項的width被定義為250px,5個子項相加之后即為1250px,超出父容器450px。那么這么超出的450px需要被這5個子項消化。
按照收縮因子,加權綜合可得250*1+250*1+250*1+250*2+250*1=1500px;
於是我們可以計算子項將被移除的溢出量是多少:
收縮因子為1的,被移除溢出量:(250*1/1500)*450,即等於75px
收縮因子為2的,被移除溢出量:(250*2/1500)*450,即約等於150px
最后實際寬度分別為:250-75=175px, 250-150=100px
4.3 flex-basis屬性
定義子項的初始寬度,若子項寬度之和超過父元素寬度時,子項按照flex-basis的比例縮放
.child{
flex-basis: [length] | [percentage] | auto; /* default auto*/
}
說明:
flex-basis的默認值為auto(
無特定寬度值,取決於其它屬性值),瀏覽器將超出的空間,按照各子項basis的值的比例進行空間收縮。
圖例中5定義了flex-basis:400px,其余子項定義了flex-basis:200px,我們給父容器width定義為800px,5個子項相加之后即為1200px,超出父容器400px。那么這么超出的400px需要被這5個子項消化。
這5個子項的比例為1:1:1:1:2,則多出來的400px要被分為6份,於是我們可以計算子項將被移除的溢出量是多少:
flex-basis為400px的,被移除溢出量:400/6*2,即約等於133.33px
flex-basis為200px的,被移除溢出量:400/6*1,即約等於66.67px
最后實際寬度分別為:400-133.33=266.67px, 200-66.67=133.33px
flex-basis:[percentage]與[length]的計算方式類似
4.4 flex屬性
flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫,默認值為0 1 auto。后兩個屬性可選。
4.5 align-self屬性
定義單個子項與其他項目不一樣的對齊方式
align-self屬性允許單個項目有與其他項目不一樣的對齊方式,可覆蓋父容器的align-items屬性。默認值為auto,表示繼承父容器的align-items屬性,如果沒有父容器,則等同於stretch。
圖例中父容器設置了align-items:flex-start,然后我們單獨給5設置了align-self:flex-end。
參考:
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html
https://developer.mozilla.org/zh-CN/docs/Web/CSS/flex
http://www.css88.com/book/css/properties/flex/index.htm