前言我也不知道怎麼寫,那廢話就很少說了,反正flex佈局不考慮兼容性的話用處仍是挺多的,我的感受也是挺神奇挺好用的。在平時的工做中,flex發揮了很是大的做用,今天就來總結一下吧。css
這裏只介紹我經常使用的flex屬性,有不足的地方歡迎指正(如下狀況默認都是在瀏覽器的默認屬性基礎上進行介紹)html
display: flex;
複製代碼
這個想必你們都很是熟悉了,我也就很少說了。瀏覽器
flex-direction: row; // 瀏覽器默認佈局方式,在同一行內進行排列(flex-wrap: nowrap的狀況下)
flex-direction: column; // 在同一列內進行排列,相似於常規的一行一行的排列
複製代碼
至於row-reverse
和 column-reverse
就不說了,感受應用場景很少。bash
這裏就須要認識一下主軸(main axis)和交叉軸(cross axis)。app
簡單地說主軸就是排列方向,交叉軸和排列方向相垂直。佈局
具體地說:flex-direction: row;
時,主軸是指水平方向,交叉軸是垂直方向。flex-direction: column;
時,主軸是指垂直方向,交叉軸是水平方向。flex
用圖來表示的話就是:網站
justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly;
複製代碼
align-items: flex-start | flex-end | center | baseline | stretch;
複製代碼
flex-wrap: nowrap;(未設置時默認就是nowrap)
,將佔滿整個容器的高度(row)/寬度(column)交叉軸和主軸不同,可沒有什麼兩端對齊,因此可千萬別混淆了。spa
單行時使用 align-items, 多行時使用align-content, 這兩種都是使用於display: flex
的元素,而align-self能夠單獨設置子元素的交叉軸對齊方式。3d
flex-wrap: nowrap | wrap | wrap-reverse;
複製代碼
當使用nowrap時,當子元素的寬度之和超過父元素的寬度時並不會換行,而是儘可能壓縮自身以保障不超過父元素的寬度,因此有時候你會發現flex內的子元素寬度跟你想象的不同就是這個緣由形成的。
至於寬度究竟是怎麼計算的嘛,說來仍是有點複雜的。理論上, 當子元素的寬度之和超過父元素的寬度時,子元素的寬度 = 子元素所設置的寬度 / 子元素之和 父元素的寬度。
假設父元素是100px,子元素A是100px,B是400px,C元素是500px,那麼理論上子元素之和爲1000px,A = 100 / 1000 * 100 = 10px,B = 400 / 1000 * 100 = 40px, C = 500 / 1000 * 100 = 50px。
固然了,這只是理論上的理想狀況。實際上,能不能按照理論分配,還得看子元素內的實際寬度,什麼是實際寬度呢?就是它裏面的內容所佔的寬度,假設A裏面的文字有3個,佔用了25px,那麼它的最終寬度就是25px,而不是所分配的10px,B和C也會相應的減小。
使用wrap的話就不會存在這個問題了,在必定程度上能夠替代以前的inline-block和float的佈局方式。
flex: 1;
/* 其實就至關於 flex-grow: 1; flex-shrink: 1; flex-basis: 0%; */
複製代碼
這個屬性的做用就是將剩餘寬度按照比例分配給該子元素。經常使用於兩欄佈局,一側定寬,另外一側設置flex: 1;
便可得到剩餘寬度。
order: 1; /* 任意正整數 */
複製代碼
這個東西但是很神奇的了,不須要改變html的結構,直接改變顯示的順序,好比常見的列表介紹,第一行左圖右文字,第二行左文字右圖。
還有一種應用場景就是聊天界面了,這個稍後會講到。
總算是講完基礎部分,接下來終於能夠進入今天的正題了。
這個應該是最常遇到的佈局方式了吧,主要分爲單行居中,多行居中。
其實這裏還分爲只有一行的元素水平居中和多行中的某一行水平居中兩種狀況,暫時只介紹第一種狀況,下一段再介紹後一種狀況。
<div class="flex-center" style="background: red;color: #fff;padding: 20px 0;">
單行水平居中
</div>
複製代碼
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
複製代碼
排列方向爲row的狀況設置主軸對齊方式爲center便可,沒什麼好說的。
flex-wrap: wrap
後,
align-content: center
是將全部的子元素組合成一個總體後垂直居中,而
align-content: center
則是將剩餘部分的空白平均分配給子元素的上下兩側。
因此這種換行後的多行垂直居中推薦你們使用align-content。
<div class="attr-title">align-content: center</div>
<div class="flex box" style="align-content: center;">
<div class="red">red</div>
<div class="green">grren</div>
<div class="blue">blue</div>
</div>
<div class="attr-title">align-items: center</div>
<div class="flex box" style="align-items: center;">
<div class="red">red</div>
<div class="green">grren</div>
<div class="blue">blue</div>
</div>
複製代碼
.flex {
display: flex;
flex-direction: row;
}
.red {
background: red;
width: 50%;
height: 30px;
}
.green {
background: green;
height: 40px;
width: 100%;
}
.blue {
background: blue;
width: 100%;
}
.attr-title {
margin-top: 24px;
margin-bottom: 12px;
}
.box {
border: 5px solid #ccc;
flex-wrap: wrap;
height: 200px;
}
複製代碼
代碼以下:
<div class="attr-title">flex-direction: column 垂直居中</div>
<div class="flex-center column border">
<div class="red">red</div>
<div class="green">grren</div>
<div class="blue">blue</div>
</div>
複製代碼
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
.column {
flex-direction: column;
}
.border {
border: 5px solid #ccc;
height: 200px;
}
複製代碼
多行垂直居中的話,相比較上面換行的那種,仍是推薦你們使用column這種方式。畢竟代碼簡潔,更好理解。還有很重要的一點就是能夠更靈活的控制子元素在水平方向的對齊方式,在文章的排版中應該會比較常見。
可能有的人會說這種排版使用text-align
也能辦到。確實也能夠,可是text-align
只能做用於塊級元素,而flex佈局則沒有這個侷限性。
<div class="flex column">
<h2 class="title self-center">黑洞的發現</h2>
<div class="flex between">
<div class="author">某網站</div>
<time class="time self-end">發佈時間:2019-04-12</time>
</div>
<article class="article">
<p>正文中打撒打撒打撒多撒正文中打撒打撒打撒多撒正文中打撒打撒打撒多撒</p>
</article>
</div>
複製代碼
.flex {
display: flex;
flex-direction: row;
}
.column {
flex-direction: column;
}
.between {
justify-content: space-between;
}
.self-center {
align-self: center;
}
.self-end {
align-self: flex-end;
}
.author {
font-size: 14px;
color: #666;
}
.time {
color: #999;
font-size: 12px;
}
.article p {
text-indent: 2em;
line-height: 1.6;
}
複製代碼
這個應用場景也挺多的,好比左側是標題,右側是更多>>。原理也很簡單,就是
.flex {
display: flex;
flex-direction: row;
}
.between {
justify-content: space-between;
}
複製代碼
在須要兩端對齊的時候,只須要在父元素加上這兩個類名就能夠了。效果圖就不上了,上方文章排版的那個就用到了。
這裏只舉例最簡單的兩欄佈局,其餘的相似,本身推導便可。
在應用flex之後,左側定寬,右側flex: 1;
便可得到剩餘寬度。
<div class="flex">
<div class="red">red</div>
<div class="green">grren</div>
</div>
複製代碼
.flex {
display: flex;
flex-direction: row;
}
.red {
width: 100px;
background: red;
height: 36px;
}
.green {
flex: 1;
background: green;
}
複製代碼
不知道你們有沒有發現,上圖中我只設置了red的高度,可是green的高度竟然和red的一致!平時的佈局中不是隻有文字的高度嗎?
其實這就是上文所說的自動填充高度了,align-items: stretch
會將未主動設置高度的子元素拉伸至與高度最高的子元素相同。align-items的默認值就是stretch,因此若是不須要自動填充高度,你須要設置align-items爲flex-start,flex-end,center等其餘的值。
有了order之後,就能夠在不改變html結構的狀況下,經過改變order的數值來改變子元素的顯示順序。
分析一下這個佈局,其實也就是兩欄佈局,而後文字部分垂直居中,前面都介紹過了,因此實現起來是很簡單的。
代碼以下:
<ul class="list">
<li class="flex item even">
<img src="https://taidaxin.oss-cn-qingdao.aliyuncs.com/1.jpg" alt="" class="img">
<div class="content flex-center column">
<div class="p">介紹</div>
<div class="p">flex佈局</div>
</div>
</li>
<li class="flex item odd">
<img src="https://taidaxin.oss-cn-qingdao.aliyuncs.com/1.jpg" alt="" class="img">
<div class="content flex-center column">
<div class="p">介紹</div>
<div class="p">flex佈局</div>
</div>
</li>
</ul>
複製代碼
.flex {
display: flex;
flex-direction: row;
}
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
.column {
flex-direction: column;
}
.list {
padding: 20px;
background: #F5F5F5;
}
.img {
width: 94px;
height: 94px;
}
.item+.item {
margin-top: 20px;
}
.content {
padding-left: 20px;
background: #fff;
font-size: 12px;
flex: 1;
}
.even .img,
.odd .content {
order: 1;
}
.even .content,
.odd .img {
order: 2;
}
複製代碼
flex: 1;
,上下兩端對齊,靠右對齊,那麼能夠採用使用column的佈局方式,主軸兩端對齊,交叉軸對齊於結尾處,表現爲justify-content: space-between;align-items: flex-end;
代碼以下:
<div class="container">
<div class="card">
<img src="https://shadow.elemecdn.com/app/element/hamburger.9cf7b091-55e9-11e9-a976-7f4d0b07eef6.png" alt="" class="card-img">
<div class="card-body flex">
<div class="card-body--left">
<div class="title">標題</div>
<div class="text">發佈者:誰知道</div>
<time class="time">欄目:天知道</time>
</div>
<div class="card-body--right flex column between">
<div class="share flex align-center">
<img src="http://uppic.fd.zol-img.com.cn/t_s501x2000/g5/M00/0D/0D/ChMkJ1ibsVeIeZ0QAACr6Uwo-6EAAZzpgMdtPAAAKwB105.jpg" alt="" class="share-icon">
<div class="share-text">分享</div>
</div>
<time class="time">發佈時間: 2019-01-02</time>
</div>
</div>
</div>
</div>
複製代碼
.flex {
display: flex;
flex-direction: row;
}
.between {
justify-content: space-between;
}
.flex-center {
display: flex;
flex-direction: row;
justify-content: center;
}
.column {
flex-direction: column;
}
.container {
background: #F5F5F5;
padding: 32px;
}
.card {
width: 320px;
margin: 20px auto;
}
.card-img {
width: 100%;
}
.card-body {
padding: 20px;
background: #fff;
}
.title {
font-size: 16px;
color: #333;
}
.text {
font-size: 14px;
color: #666;
padding: 8px 0;
}
.card-body--right {
flex: 1;
align-items: flex-end;
}
.time {
font-size: 12px;
color: #999;
}
.share {
align-items: center;
}
.share-icon {
width: 40px;
height: 40px;
}
複製代碼
簡單的分析一下佈局,一個別人發的,一個本身發的,也就靠左和靠右對齊的區別而已。
從正常的佈局來看,先是頭像,而後是一個三角形的箭頭(用border便可),再而後就是對話內容了。 反方向的話,就是控制一下這三個部分的order而已,還有就是外邊距的方向也得反一下。
跟以前的東西相比沒有什麼新鮮的,我就不貼代碼了,要否則就太多了,固然了有須要的話能夠留言,我能夠放在評論區。
平時佈局的話,你們仍是要注意多總結,先思考怎麼佈局更簡單,而後再着手寫代碼,這樣能夠省下不少時間的。flex在一維佈局確實是很強大的,基本上能夠解決平時遇到的各類問題。grid在二維佈局方面相對而言更好用,都怪這**的兼容性問題,要否則咱們就有更多更好的方式能夠選擇了。
那麼今天就先說到這裏吧(雖然大部分都是代碼),若是你們還有什麼疑問或者指導性建議的話,歡迎評論。