flexbox更加優雅的Web布局
flexbox layout是W3C為了更好的在網頁中排版和布局而設計出來的一個模塊。它用來可以處理更加復雜的布局。它本質是盒模型的延伸,它可以進一步去規范容器中子元素盒模型之間的相對關系。
基礎知識點
flexbox盒子按照寬和高分出了main axis(主軸)和cross axis(和主軸交叉的軸),盒子的上邊稱為cross start,下邊稱為cross end,左邊稱為main start,右邊稱為main end。
flexbox可以解決什么問題
完全置中
在前端中實現置中是一件很頭疼的事情,尤其是實現垂直置中,之前在一個老外的博客上看到一篇實現置中的七種方法,其中提到一種最簡單的方法就是使用transform,需要5行代碼可以實現完全置中。
下面看一下flexbox實現置中:
.flex-container{ display:flex; justify-content: center; align-items: center; }
flexbox只要3行代碼就可以實現置中。
等高的卡片式布局
在沒有用flexbox之前很多卡片設計的網站都有這樣一個問題,由于卡片里面的內容多少不同,而產生的不等高問題。
flexbox簡單的實現等高列:
.flex-container{ display:flex; align-items: stretch; }
flexbox能用在哪里
兼容性
可以看出flexbox從提出到現在也已經有了8個草案。flexbox更新了三種寫法。
caniuse上各個瀏覽器支持的情況
稍微整理一下(這里借用gitcafe的JaychSu的圖用一下)
從這里可以看出現代瀏覽器都支持最新的那個版本,只有IE10支持中間那個版本。
使用css預處理器定義的@mixin解決flexbox版本兼容
在github上有大神把flexbox三個版本搞成一個sass的@mixin,這樣可以在需要的地方直接@include進來就可以輕松解決三個版本的兼容問題。
sass關于flexbox的mixin的github項目地址
flexbox實現的原理邏輯
1. display(定義容器里面為flex文檔流)
- dislpay:flex使父容器表現為塊盒子
- display:inline-flex使容器表現為行盒子
2. flex
flex是flex-grow,flex-shrink,flex-basis的縮寫形式。默認值是0 1 auto。
3. flex-basis
flex-basis:flex-basis可以理解為我們給子元素設置的寬度。默認值是auto,寬度設置為auto時,盒子的寬度取決你們元素的寬度。
4. flex-grow和flex-shrink
grow和shrink是一對雙胞胎,grow表示伸張因子,shrink表示是收縮因子。
grow在flex容器下的子元素的寬度和比容器和小的時候起作用。 grow定義了子元素的寬度增長因子,容器中除去子元素之和剩下的寬度會按照各個子元素的gorw值進行平分加大各個子元素上。
公式:
-
計算容器還剩空間
available_space(容器還剩的空間)=container_size(容器寬度)-flex_item_total(子元素寬度之和)
-
計算增長單位
grow_unit(增長單位)=available_space/flex_grow_total(子元素增長因子之和)
-
得到子元素的寬度
flex-item-width(子元素計算得到的寬度)=flex-basis+grow-unit*flex-grow
上面例子的計算
container-size=480px; flex-item-total=100*3=300px;flex-grow-total=3+2+1=6 available_space=480-300=180px; grow_unit=180/6=30px;
子元素1的寬度為:
flex_item_width1=100+3*30=190px;
子元素2的寬度為:
flex_item_width1=100+2*30=160px;
子元素3的寬度為:
flex_item_width1=100+30=130px;
Codepen實例 shrink則是在寬度和比容器寬度大時候,才有用。按照shrink的值減去相應大小得到子元素的值。
公式:
overflow_space(溢出的寬度)
-
計算溢出的寬度
overflow-space=flex-item-total(子元素basis寬度之和)-container_width(容器寬度)
-
得到計算的子元素的寬度
item-basis:子元素設置的flex-basis;item-shrink:子元素的flex-shrink;item-shrink-sum:所有子元素flex_shrink的和。 flex_item_width(計算的子元素的寬度)=item-basis --(overflow-space*(item-shrink/item-shrink-sum))
container-width=480px; item-shrink分別為3,2,1.item-basis=200px; overflow-space=120px;
則:
flex_item1_width=200-(120*(3/6))=140px; flex_item2_width=200-(120*(2/6))=160px; flex_item3_width=200-(120*(1/6))=180px;
5. align-content
對單行和單列不起作用,多行時才有效,需設置flex-direction:row;flex-wrap:wrap;或者flex-flow:row-wrap,對flex container中的行進行布局排版。
- flex-start:行填充到容器的開始。
- flex-bottom:行填充到容器的結束。
- center:行居中分布
- space-between:行平均分布,第一行在容器開始,最后一行在容器結束。
- space-around:行平均分布,但行與行之間有空隙。
實例截圖
6. align-items
用于當前行中的子元素進行對齊布局。
- flex-start: 子元素的上邊緣對齊到行的上邊緣。
- flex-end: 子元素的上邊緣對齊到行的下邊緣。
- center: 以中軸線居中。
- baseline: 子元素的基線對齊。
- stretch:子元素拉伸至充滿容器。
實例截圖
7. align-self
應用在子元素上,可以覆蓋align-item來獲得特殊的元素對齊。
- flex-start: 子元素的上邊緣對齊到行的上邊緣。
- flex-end: 子元素的上邊緣對齊到行的下邊緣。
- center: 以中軸線居中。
- baseline: 子元素的基線對齊。
- stretch:子元素拉伸至充滿容器。
實例截圖
一個利用align-self來改變默認align-items排版的例子
8. justify-content
水平方向上布局排版
- flex-start:子元素靠容器的左邊線對齊
- flex-end:子元素靠容器的右邊線對齊
- center: 子元素居中
- space-between: 子元素被平均分布,第一子元素在容器最左邊,最后一個子元素在最右邊。
- space-around: 子元素平均分布,但子元素與子元素之間有空隙。
實例截圖
9. order
用來改變子元素之間的排列循序,默認值是0,值越小,越往前排。
10. flex-wrap
定義flexitem是限制在一行中單行顯示還是超出父容器時換行。
- nowrap(默認)不換行
- wrap 超出父容器寬度換行
- wrap-inverse 換行但是子元素的倒序排列
11. flex-flow
flex-flow是flex-direction和flex-wrap的縮寫形式。第一個值是flex-direction屬性的值,第二個值是flex-wrap屬性的值
flexbox解決的一些問題。
- 優雅的實現響應式布局。
- 最簡潔的實現媒體對象效果。(不需要浮動和創建BFC哦!)
關于flexbox的一些文章
原文:http://luxiaojian.me/2015/03/22/flexboxgeng-jia-you-ya-de-webbu-ju/