簡介
- 傳統(tǒng)布局基于盒子模型乌叶,通過 display float position 屬性進行布局,但是有些效果在盒模型下不好實現(xiàn)芹敌,比如垂直方向居中蠢沿。
- 2009年 W3C 提出Flex布局,主流瀏覽器均可支持,其中IE瀏覽器在IE10之后開始支持
基礎語法
概念
Flex容器
- 采用Flex布局的元素陆盘,稱為Flex容器(flex container)普筹。它的所有子元素自動成為容器成員,稱為Flex項目(flex item)
- 給元素添加 display: flex 屬性使元素成為Flex容器隘马,即開啟了彈性布局太防,行內(nèi)元素也可用 display: inline-flex; 成為Flex容器
- 開啟彈性布局后Flex容器的子元素的 float clear vertical-align 屬性將失效
主軸和副軸
- 在Flex容器內(nèi)使用主軸和副軸概念;默認x軸為主軸酸员,y軸為副軸蜒车;可由Flex容器的 flex-direction 屬性修改
- 主軸副軸中有起始位置的概念,默認的起始位置為x軸的左側y軸的上側
- 在使用彈性布局時幔嗦,需要通過主軸和副軸確定編輯的方向酿愧,F(xiàn)lex容器內(nèi)的元素默認會處于類似 float 的狀態(tài),例html結構如下:
<div class="container">
<div class="pink"></div>
<div class="green"></div>
<div class="blue"></div>
</div>
當主軸為x軸時:
當主軸為y軸時:
即主軸方向決定了容器內(nèi)元素的排列方向
容器屬性
flex-direction
flex-wrap
flex-flow
justify-content
align-items
align-content
1. flex-direction
設置主軸方向
.box {
flex-direction: row | row-reverse | column | column-reverse;
}
row(默認值):主軸為x軸崭添,起始位置為左
row-reverse:主軸為x軸寓娩,起始位置為右
column:主軸為y軸,起始位置為上
column-reverse:主軸為y軸呼渣,起始位置為下
2. flex-wrap
設置可換行屬性棘伴,默認下容器內(nèi)子元素會按照主軸方向排一行,不會換行屁置,當總長度超過容器時子元素會被壓縮焊夸,通過 flex-wrap 屬性可設置換行模式
.box{
flex-wrap: nowrap | wrap | wrap-reverse;
}
nowrap(默認值):不換行,width設置為22%的6個子元素被壓縮在一行
wrap:換行蓝角,第一行從最上側開始
wrap-reverse:換行阱穗,第一行從最底部開始
3. flex-flow
flex-direction 和 flex-wrap 的聯(lián)寫模式
.box {
flex-flow: <flex-direction> || <flex-wrap>;
}
4. justify-content
設置主軸方向的對其方式
.box {
justify-content: flex-start | flex-end | center | space-between | space-around;
}
flex-start(默認值):左對齊
flex-end:右對齊
center: 居中
space-between:兩端對齊,項目之間的間隔都相等使鹅。
space-around:每個項目兩側的間隔相等揪阶。所以,項目之間的間隔比項目與邊框的間隔大一倍患朱。
5. align-items
設置副軸方向對其方式
.box {
align-items: flex-start | flex-end | center | baseline | stretch;
}
```
> flex-start:副軸的起點對齊
> flex-end:副軸的終點對齊
> center:副軸的中點對齊
> baseline: 項目的第一行文字的基線對齊
> stretch(默認值):如果項目未設置高度或設為auto鲁僚,將占滿整個容器的高度
![align-items效果圖](https://kabumie.github.io/images/md_img/align-items.png)
*這里只演示baseline效果,其它類似于justify-content的效果*
#### 6. align-content
在開啟換行模式后有換行時設置多行在副軸方向的對齊方式裁厅,如果主軸只有一行則該屬性無效
```css
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}
flex-start:與交叉軸的起點對齊
flex-end:與交叉軸的終點對齊
center:與交叉軸的中點對齊
space-between:與交叉軸兩端對齊冰沙,軸線之間的間隔平均分布
space-around:每根軸線兩側的間隔都相等。所以执虹,軸線之間的間隔比軸線與邊框的間隔大一倍
stretch(默認值):軸線占滿整個交叉軸
子元素屬性
order
flex-grow
flex-shrink
flex-basis
flex
align-self
1. order (常用)
定義子元素排列順序拓挥,值為無單位整數(shù),默認值為0袋励,值越小越靠近起始位置
2. flex-grow
- 定義子元素放大比例侥啤,只有在容器主軸方向大小大于子元素總大小時才有效果当叭,即容器有空余,值為無單位非負數(shù)字愿棋,可設置浮點數(shù)科展,默認為0
- 當值為0時代表子元素不放大,如果容器有剩余空間則空出
-
如果有子元素 flex-grow 值不為0糠雨,則子元素會按照 flex-grow 值的比例放大并填充容器的剩余空間
具體計算方式:假設 A, B, C, D, E 的寬度分別是 100, 120, 130, 100, 100才睹,父級的寬度是660,父級寬減去子級的全部寬度甘邀,這樣剩余空間就是110琅攘。例子中B, C定義了flex-grow,分別是1松邪,2坞琴,那剩余空間分成3份,B1份逗抑,C2份剧辐,比例就是1:2,分配計算出來的值就是B :36.666666666666664, C:73.33333333333333邮府。這個時候剩余空間就被計算出來了荧关,相加后的結果就是B:156.66666666666666,C:203.33333333333331褂傀。
B的計算公式:120 + (110 / 3) * 1
C的計算公式: 130 + (110 / 3) * 2
3. flex-shrink
- 定義子元素縮小比例忍啤,只有在容器主軸方向大小小于子元素總大小且不換行時才有效果,即容器空間不足仙辟,值為無單位非負數(shù)字同波,可設置浮點數(shù),默認為1
- 為0表示子元素不縮小叠国,如果容器大小小于子元素總大小未檩,而所有子元素均不縮小,則子元素會超出容器范圍
-
如果有子元素 flex-shrink 值不為0粟焊,則子元素會按照 flex-shrink 值的比例縮小在容器中
具體計算方式:假設 A, B, C 的寬度分別是155, 200, 50讹挎。父級寬度是300,計算超出的空間就是 -105吆玖,這樣超出的 105px 就要被 A, B, C 消化掉,比例是2:1:1马篮。
首先把每個項目的wdith值乘以 flex-shrink 值求積
A:(155 * 2) = 310
B:(200 * 1) = 200
C:(50 * 1) = 50沾乘。
然后再求和所有項目的乘積
(310 + 200 + 50) = 560
得到求占比之后還要乘以要騰出的空間
A:(310 / 560) * 105 = 58.125
B:(200 / 560) * 105 = 37.5
C:(50 / 560) * 105 = 9.375
得到每一項要騰出的空間
A:(155 - 58.125) = 96.875
B:(200 - 37.5) = 162.5
C:(50 - 9.375) = 40.625
這就是 A, B, C 按比例縮小后的大小
4. flex-basis
- 本人對于 flex-basis 的意義并沒有完全理解,個人感覺有點像是設置了一個 max-width (主軸x軸時)浑测,很多人推薦在彈性布局中多使用 flex-basis 而不是直接設置 width height 屬性翅阵,這個屬性在下面的圣杯布局實例中有一次使用
- 它的默認值為 auto歪玲,表示項目的本來大小
5. flex (常用)
- flex-grow flex-shrink flex-basis 的聯(lián)寫,默認值為0 1 auto掷匠。后兩個屬性可選
- 該屬性有兩個快捷值:auto (1 1 auto) 和 none (0 0 auto)
- 通常直接用 flex 設置子元素比例大小滥崩,例如使用 flex: 1 直接設置大小比例,而不再單獨寫 flex-grow: 1
6. align-self (常用)
- align-self 屬性允許單個項目有與其他項目不一樣的對齊方式讹语,可覆蓋 align-items 屬性钙皮。默認值為 auto,表示繼承父元素的 align-items 屬性顽决,如果沒有父元素短条,則等同于 stretch(默認值)
-
除多出默認值 auto 外,屬性值同 align-items
應用實例
圣杯布局
- 圣杯布局是指在頁面主體部分分為 left content right 3部分才菠,left和right固定大小茸时,content部分會自適應屏幕大小,后來國內(nèi)的淘寶團隊對其進行了改良赋访,改良后效果基本相同可都,一般叫做雙飛翼布局,使用搜索引擎搜索有很多相關介紹
- 本身圣杯布局是使用 float margin padding 和定位等盒模型方法實現(xiàn)的蚓耽,關鍵點是使用負值的 margin 使left和right可以與設置為100%寬度的content浮動在同一行中渠牲,這里使用彈性布局則可以非常方便清晰的實現(xiàn)有自適應效果的圣杯布局
html結構:
<body>
<div class="container">
<div class="header"></div>
<div class="content">
<div class="left"></div>
<div class="middle"></div>
<div class="right"></div>
</div>
<div class="footer"></div>
</div>
</body>
css樣式:
* {
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
}
.container {
height: 100%;
display: flex;
flex-direction: column;
}
.header {
flex: 1;
background-color: gray;
}
.content {
flex: 3;
display: flex;
}
.content .left {
background-color: red;
flex: 0 0 200px;
}
.content .right {
background-color: blue;
flex: 0 0 200px;
}
.content .middle {
background-color: whitesmoke;
flex: 1;
}
.footer {
flex: 1;
background-color: gray;
}
@media (max-width: 768px) {
.content {
flex-direction: column;
}
.content .left,
.content .right,
.content .middle {
flex: 1;
}
}
效果圖:
這里做了屏幕大小判斷來適應移動端,在設置left和right寬度時使用的是 flex-basis田晚,而不是 width嘱兼,主要是因為在判斷屏幕寬度小于768px時需要層疊掉left和right原本的固定寬度,讓left和right可以自動填充整個屏寬贤徒,使用 flex-basis 可以在移動端樣式中直接設置 flex: 1 使 flex-basis 變?yōu)?auto芹壕,如果使用 width,在需要去掉固定寬度時則比較麻煩
使用彈性布局不僅在寬度上達到自適應接奈,在高度上也可以不受內(nèi)容限制踢涌,直接填充滿整個屏高
懸窗圖片展示板
- 利用彈性布局可以用很少的代碼制作一個圖片懸窗的圖片展示板,彈性布局在處理寬高位置等方面非常方便序宦,實用的demo有很多睁壁,這里就只展示一個懸窗案例
html:
<div class="container">
![](../img/mm.png)
<div class="content">
<h3>Title</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laborum impedit ut officiis, nobis consequuntur fuga ipsam deleniti dolorem consequatur voluptatum saepe nam magni, aperiam voluptatibus officia. Sed facilis totam quis laborum laudantium cupiditate cumque, fuga illum asperiores alias libero quia, placeat debitis explicabo sint, rerum, at reiciendis inventore dolore officia!</p>
</div>
</div>
css:
* {
margin: 0;
padding: 0;
}
.container {
width: 400px;
padding: 15px;
margin: 50px auto;
background-color: whitesmoke;
border-radius: 10px;
display: flex;
}
.container img {
margin-right: 15px;
width: 80px;
height: 80px;
}
.content {
flex: 1;
}
.container p {
font: 400 12px "微軟雅黑";
}
效果圖:
結尾
作者很無恥的直接使用了阮一峰博客中的一些說明圖片(因為自己做的一部分圖片搞丟了,實在不想再做了T.T)互捌;這里先謝阮大神潘明,但是個人感覺阮一峰這篇博客對于一些屬性的說明不太詳細。
在 flex-grow 和 flex-shrink 的具體計算上直接使用了xiecg的文章中的例子秕噪,因為這個例子寫的實在是太棒了钳降。
會同步在 kabumie 的 github 空間上