一、背景
前段時間幫公司運維小姑娘調整她自己寫的頁面樣式時發現她用了display: flex,我這個后端老古董還不太懂flex,自愧不如啊,所以寫篇博客記錄學習下。
現在寫的前端頁面還停留在依賴?display
?屬性 +?position
屬性 +?float
屬性的布局方式,這種布局對一些特殊布局非常不方便,比如,垂直居中等等。
2009年,W3C 提出了一種新的方案----Flex 布局,可以簡便、完整、響應式地實現各種頁面布局。目前,它已經得到了所有瀏覽器的支持,這意味著,現在就能很安全地使用這項功能。
二、概念
Flex 是 Flexible Box 的縮寫,意為"彈性布局",用來為盒狀模型提供最大的靈活性。任何一個容器都可以指定為 Flex 布局(包括塊狀和行內元素)。在設置Flex布局后,子元素的float
、clear
和vertical-align
屬性將失效。
采用 Flex 布局的元素,稱為 Flex 容器(flex container),簡稱"容器"。它的所有子元素自動成為容器成員,稱為 Flex 項目(flex item),簡稱"項目"。
容器默認存在兩根軸:水平的主軸(main axis)和垂直的交叉軸(cross axis)。主軸的開始位置(與邊框的交叉點)叫做main start
,結束位置叫做main end
;交叉軸的開始位置叫做cross start
,結束位置叫做cross end
。
項目默認沿主軸排列。單個項目占據的主軸空間叫做main size
,占據的交叉軸空間叫做cross size
。
三、基本屬性
以下容器的6個屬性設置:
3.1、flex-direction 容器內項目的排序方式,屬性值如下:
row//默認值,沿水平主軸由左向右排列
row-reverse//沿水平主軸由右向左排列
column//沿垂直的交叉軸由上向下排列
column-reverse //沿垂直的交叉軸由下向上排列
3.2、flex-wrap 容器內項目的換行方式,值如下:
nowrap //(默認):不換行。
wrap://換行,第一行在上方。
wrap-reverse://換行,第一行在下方。
?
3.3、flex-flow 以上兩種屬性的簡寫 寫法:
div{flex-flow: <flex-direction> || <flex-wrap>;
}
3.4、justify-content 項目在主軸上的對齊方式
flex-start//(默認值):左對齊
flex-end//右對齊
center//居中
space-between//兩端對齊,項目之間的間隔都相等。
space-around//每個項目兩側的間隔相等。所以,項目之間的間隔比項目與邊框的間隔大一倍。
3.5、align-item 項目在垂直交叉軸上的對齊方式
flex-start//交叉軸的起點對齊。
flex-end//交叉軸的終點對齊。
center//交叉軸的中點對齊。
baseline//項目的第一行文字的基線對齊。
stretch//(默認值):如果項目未設置高度或設為auto,將占滿整個容器的高度。
3.6、align-content 在多根軸線的情況下的對齊方式,一根軸線下不起作用
flex-start//與交叉軸的起點對齊。
flex-end//與交叉軸的終點對齊。
center//與交叉軸的中點對齊。
space-between//與交叉軸兩端對齊,軸線之間的間隔平均分布。
space-around//每根軸線兩側的間隔都相等。所以,軸線之間的間隔比軸線與邊框的間隔大一倍。
stretch(默認值)//軸線占滿整個交叉軸。
四、項目的屬性
4.1、order?屬性定義項目的排列順序。數值越小,排列越靠前,默認為0
?
4.2、flex-grow
屬性定義項目的放大比例,默認為0
,即如果存在剩余空間,也不放大。
如果所有項目的flex-grow
屬性都為1,則它們將等分剩余空間(如果有的話)。如果一個項目的flex-grow
屬性為2,其他項目都為1,則前者占據的剩余空間將比其他項多一倍。
4.3、flex-shrink
屬性定義了項目的縮小比例,默認為1,即如果空間不足,該項目將縮小
如果所有項目的flex-shrink
屬性都為1,當空間不足時,都將等比例縮小。如果一個項目的flex-shrink
屬性為0,其他項目都為1,則空間不足時,前者不縮小。
?
4.4、flex-basis
屬性定義了在分配多余空間之前,項目占據的主軸空間(main size)。
瀏覽器根據這個屬性,計算主軸是否有多余空間。它的默認值為auto
,即項目的本來大小。它可以設為跟width
或height
屬性一樣的值(比如350px),則項目將占據固定空間。
4.5、flex
屬性是flex-grow
,?flex-shrink
?和?flex-basis
的簡寫,默認值為0 1 auto
。后兩個屬性可選。
該屬性有兩個快捷值:auto
?(1 1 auto
) 和 none (0 0 auto
)。
建議優先使用這個屬性,而不是單獨寫三個分離的屬性,因為瀏覽器會推算相關值
4.6、align-self
屬性允許單個項目有與其他項目不一樣的對齊方式。
可覆蓋align-items
屬性。默認值為auto
,表示繼承父元素的align-items
屬性,如果沒有父元素,則等同于stretch
。
該屬性可能取6個值,除了auto,其他都與align-items屬性完全一致。
?
五、常用布局
5.1網格布局
5.11 基本網格布局
最簡單的網格布局,就是平均分布。在容器里面平均分配空間,需要設置項目的自動縮放。
HTML代碼如下:
<div class="Grid"><div class="Grid-cell">...</div><div class="Grid-cell">...</div><div class="Grid-cell">...</div>
</div>
CSS代碼如下:
.Grid {display: flex;
}.Grid-cell {flex: 1;
}
5.12 百分比布局
某個網格的寬度為固定的百分比,其余網格平均分配剩余的空間。
HTML代碼如下。
<div class="Grid"><div class="Grid-cell u-1of4">...</div><div class="Grid-cell">...</div><div class="Grid-cell u-1of3">...</div>
</div>
.Grid {display: flex;
}.Grid-cell {flex: 1;
}.Grid-cell.u-full {flex: 0 0 100%;
}.Grid-cell.u-1of2 {flex: 0 0 50%;
}.Grid-cell.u-1of3 {flex: 0 0 33.3333%;
}.Grid-cell.u-1of4 {flex: 0 0 25%;
}
5.2、圣杯布局
圣杯布局(Holy Grail Layout)指的是一種最常見的網站布局。頁面從上到下,分成三個部分:頭部(header),軀干(body),尾部(footer)。其中軀干又水平分成三欄,從左到右為:導航、主欄、副欄。
HTML代碼如下:
<body class="HolyGrail"><header>...</header><div class="HolyGrail-body"><main class="HolyGrail-content">...</main><nav class="HolyGrail-nav">...</nav><aside class="HolyGrail-ads">...</aside></div><footer>...</footer>
</body>
CSS代碼如下:
.HolyGrail {display: flex;min-height: 100vh;flex-direction: column;
}header,
footer {flex: 1;
}.HolyGrail-body {display: flex;flex: 1;
}.HolyGrail-content {flex: 1;
}.HolyGrail-nav, .HolyGrail-ads {/* 兩個邊欄的寬度設為12em */flex: 0 0 12em;
}.HolyGrail-nav {/* 導航放到最左邊 */order: -1;
}
如果是小屏幕,軀干的三欄自動變為垂直疊加。
@media (max-width: 768px) {.HolyGrail-body {flex-direction: column;flex: 1;}.HolyGrail-nav,.HolyGrail-ads,.HolyGrail-content {flex: auto;}
}
5.3、輸入框的布局
我們常常需要在輸入框的前方添加提示,后方添加按鈕。
HTML代碼如下。
<div class="InputAddOn"><span class="InputAddOn-item">...</span><input class="InputAddOn-field"><button class="InputAddOn-item">...</button>
</div>
CSS代碼如下。
.InputAddOn {display: flex;
}.InputAddOn-field {flex: 1;
}
5.4、懸掛式布局
有時,主欄的左側或右側,需要添加一個圖片欄。
HTML代碼如下。
<div class="Media"><img class="Media-figure" src="" alt=""><p class="Media-body">...</p>
</div>
CSS代碼如下。
.Media {display: flex;align-items: flex-start;
}.Media-figure {margin-right: 1em;
}.Media-body {flex: 1;
}
5.5、固定的底欄
有時,頁面內容太少,無法占滿一屏的高度,底欄就會抬高到頁面的中間。這時可以采用Flex布局,讓底欄總是出現在頁面的底部。
HTML代碼如下。
<body class="Site"><header>...</header><main class="Site-content">...</main><footer>...</footer>
</body>
CSS代碼如下。
.Site {display: flex;min-height: 100vh;flex-direction: column;
}.Site-content {flex: 1;
}
5.6、流式布局
每行的項目數固定,會自動分行。
CSS的寫法。
.parent {width: 200px;height: 150px;background-color: black;display: flex;flex-flow: row wrap;align-content: flex-start;
}.child {box-sizing: border-box;background-color: white;flex: 0 0 25%;height: 50px;border: 1px solid red;
}
以上文章主要摘自阮一峰的《Flex 布局教程》,鏈接:http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool