關于flex具體是什么在此不贅述,官方文檔在此:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox
我自己通過實例總結如下:
flex 布局主要有兩大塊:1. 父元素;2. 子元素
把這兩大塊搞明白就算吃透flex布局了(接下來的實例中,我會將完整代碼貼出來,大家可復制代碼在瀏覽器運行感受一下)。
父元素
1. justify-content
元素水平方向上的布局 常用的也就5個屬性而已,代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>justify-content</title>
<style>
.boxp{
background: lightgreen;
height: 100px;
display: flex;
margin-bottom: 50px;
}
.boxp div{
width: 100px;
height: 100px;
background: purple;
}
.center{
justify-content: center;
}
.space-between{
justify-content: space-between;
}
.space-around{
justify-content: space-around;
}
.flex-start{
justify-content: flex-start;
}
.flex-end{
justify-content: flex-end;
}
</style>
</head>
<body>
<!-- justify-content: center -->
<div class="boxp center">
<div></div><div></div><div></div><div></div>
</div>
<!-- justify-content: space-between -->
<div class="boxp space-between">
<div></div><div></div><div></div><div></div>
</div>
<!-- justify-content: space-around -->
<div class="boxp space-around">
<div></div><div></div><div></div><div></div>
</div>
<!-- justify-content: flex-start -->
<div class="boxp flex-start">
<div></div><div></div><div></div><div></div>
</div>
<!-- justify-content: flex-end -->
<div class="boxp flex-end">
<div></div><div></div><div></div><div></div>
</div>
</body>
</html>
效果如下:
注意
- space-between: 先是兩端對齊,剩余的子元素之間間隔相同
- space-around: 每個元素左右距離相同(為了方便理解,可想象成每個元素都是margin: 0 20px; 這種效果,所以兩側的剩余寬度是項目間隔寬度的二分之一)。
2. align-items
元素垂直方向上的布局,常用的就5個屬性,代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>align-items</title>
<style>
.boxp{
height: 120px;
background: lightgreen;
display: flex;
margin-bottom: 30px;
}
.boxp div{
width: 80px;
background: yellow;
margin: 0 10px;
}
.one{
height: 50px;
font-size: 12px;
}
.two{
height: 80px;
font-size: 25px;
}
.three{
height: 60px;
font-size: 45px;
}
.noheight{
height: auto;
}
.center{
align-items: center;
}
.flex-start{
align-items: flex-start;
}
.flex-end{
align-items: flex-end;
}
.baseline{
align-items: baseline;
}
.stretch{
align-items: stretch;
}
</style>
</head>
<body>
<!-- align-items: center; -->
<div class="boxp center">
<div class="one">1</div><div class="two">2</div><div class="three">3</div>
</div>
<!-- align-items: flex-start; -->
<div class="boxp flex-start">
<div class="one">1</div><div class="two">2</div><div class="three">3</div>
</div>
<!-- align-items: flex-end; -->
<div class="boxp flex-end">
<div class="one">1</div><div class="two">2</div><div class="three">3</div>
</div>
<!-- align-items: baseline; -->
<div class="boxp baseline">
<div class="one">1</div><div class="two">2</div><div class="three">3</div>
</div>
<!-- align-items: stretch; -->
<div class="boxp stretch">
<div class="noheight">1</div><div class="noheight">2</div>
</div>
</body>
</html>
效果:
注意
- baseline: 使整行文字的基準線平齊,在此基礎上布局子元素
- stretch: 元素沒有設置具體高度值,或者高度屬性值為auto時,才會生效
3. align-content
要解釋這個屬性,先帶大家理解一下flex
布局容器中“軸”
的概念:
flex
布局的容器中默認有兩根軸:1. 水平方向的主軸;2:垂直方向的軸。
容器內的元素默認按照主軸的方向進行布局,當元素不止一行的時候,水平方向就會存在多根軸;
或者當元素按照垂直方向布局,當元素不止一列時,垂直方向就會存在多根軸。
align-content
就是對這多根軸進行布局。具體看代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>align-content</title>
<style>
.boxp{
background: lightgreen;
display: flex;
margin-bottom: 20px;
height: 500px;
flex-wrap: wrap;
}
.boxp div{
width: 300px;
height: 50px;
background: yellow;
margin: 10px;
}
.center{
align-content: center;
}
.space-between{
align-content: space-between;
}
.space-around{
align-content: space-around;
}
.flex-start{
align-content: flex-start;
}
.flex-end{
align-content: flex-end;
}
</style>
</head>
<body>
<!-- align-content: center -->
<div class="boxp center">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
<!-- align-content: space-between -->
<div class="boxp space-between">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
<!-- align-content: space-between -->
<div class="boxp space-around">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
<!-- align-content: flex-start -->
<div class="boxp flex-start">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
<!-- align-content: flex-end -->
<div class="boxp flex-end">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
</body>
</html>
效果:
4. flex-wrap
子元素是否可以換行展示,常用的只有三個屬性,代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-wrap</title>
<style>
.boxp{
background: lightgreen;
height: 200px;
display: flex;
margin-bottom: 30px;
}
.boxp div{
width: 100px;
height: 50px;
margin: 10px;
background: yellow;
}
.wrap{
flex-wrap: wrap;
}
.nowrap{
flex-wrap: nowrap;
}
.wrap-reverse{
flex-wrap: wrap-reverse;
}
</style>
</head>
<body>
<!-- flex-wrap: wrap; -->
<div class="boxp wrap">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
<!-- flex-wrap: nowrap; -->
<div class="boxp nowrap">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
<!-- flex-wrap: wrap-reverse; -->
<div class="boxp wrap-reverse">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div><div>6</div><div>7</div><div>8</div><div>9</div><div>10</div>
</div>
</body>
</html>
效果:
注意
當沒有設置flex-wrap屬性時,默認是不換行的,所有子元素會擠在一排。
屬性值為wrap-reverse
時,是把行倒序排列,但每一行里面的元素還是原來的順序,這樣想就容易理解了。
5. flex-direction
元素排列方向,常用的四個屬性,代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-direction</title>
<style>
.boxp{
background: lightgreen;
display: flex;
margin-bottom: 20px;
}
.boxp div{
width: 50px;
height: 50px;
background: yellow;
margin: 10px;
}
.row{
height: 80px;
flex-direction: row;
}
.row-reverse{
height: 80px;
flex-direction: row-reverse;
}
.column{
height: 350px;
flex-direction: column;
}
.column-reverse{
height: 350px;
flex-direction: column-reverse;
}
</style>
</head>
<body>
<!-- flex-direction: row; -->
<div class="boxp row">
<div>1</div><div>2</div><div>3</div><div>4</div>
</div>
<!-- flex-direction: row-reverse; -->
<div class="boxp row-reverse">
<div>1</div><div>2</div><div>3</div><div>4</div>
</div>
<!-- flex-direction: column; -->
<div class="boxp column">
<div>1</div><div>2</div><div>3</div><div>4</div>
</div>
<!-- flex-direction: column-reverse; -->
<div class="boxp column-reverse">
<div>1</div><div>2</div><div>3</div><div>4</div>
</div>
</body>
</html>
效果:
注意
不僅要注意元素排列順序,還要注意相對父元素的排列方向!!!
6. flex-flow
flex-direction 和 flex-wrap 的簡寫,應該很好理解吧,在此不贅述,請查看官網文檔。
子元素
1. order
設置當前子元素的排序位置,數字越小越往前,默認為0,可以是負數。
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-wrap</title>
<style>
.boxp{
background: lightgreen;
height: 100px;
display: flex;
margin-bottom: 30px;
}
.boxp div{
width: 100px;
height: 50px;
margin: 10px;
background: yellow;
}
.NO1{
-webkit-order: 5;
-moz-order: 5;
-ms-order: 5;
-o-order: 5;
order: 5;
}
.NO-3{
-webkit-order: -3;
-moz-order: -3;
-ms-order: -3;
-o-order: -3;
order: -3;
}
.NO-2{
-webkit-order: -2;
-moz-order: -2;
-ms-order: -2;
-o-order: -2;
order: -2;
}
</style>
</head>
<body>
<!-- 無order -->
<div class="boxp">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div>
</div>
<!-- 有order -->
<div class="boxp">
<div class="NO1">1</div>
<div>2</div>
<div>3</div>
<div class="NO-2">4</div>
<div class="NO-3">5</div>
</div>
</body>
</html>
效果:
2. flex-grow
設置項目占剩余空間的份額(如果有剩余空間的話),如果為0,則不拉伸,負數無效。
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-grow</title>
<style>
.boxp{
background: lightgreen;
height: 100px;
display: flex;
margin-bottom: 30px;
}
.boxp div{
width: 100px;
height: 50px;
margin: 10px;
background: yellow;
}
.grow0{
flex-grow: 0;
}
.grow-1{
flex-grow: -1;
}
.grow2{
flex-grow: 2;
}
.grow3{
flex-grow: 3;
}
</style>
</head>
<body>
<!-- 無flex-grow -->
<div class="boxp">
<div>1</div><div>2</div><div>3</div><div>4</div><div>5</div>
</div>
<!-- 有flex-grow -->
<div class="boxp">
<div class="grow0">flex-grow: 0</div>
<div class="grow-1">flex-grow: -1</div>
<div>3</div>
<div class="grow2">flex-grow: 2</div>
<div class="grow3">flex-grow: 3</div>
</div>
</body>
</html>
效果:
3. flex-shrink
當空間不夠時,設置子元素的縮小比例。若屬性值為0
,則不縮小。
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-shrink</title>
<style>
.boxp{
background: lightgreen;
height: 100px;
display: flex;
margin-bottom: 30px;
}
.boxp div{
width: 500px;
height: 50px;
outline: 1px solid green;
background: yellow;
}
.shrink0{
flex-shrink: 0;
}
.shrink1{
flex-shrink: 1;
}
.shrink2{
flex-shrink: 2;
}
.shrink3{
flex-shrink: 3;
}
.shrink4{
flex-shrink: 4;
}
</style>
</head>
<body>
<!-- 無flex-shrink -->
<div class="boxp">
<div>未設置flex-shrink</div><div>未設置flex-shrink</div><div>未設置flex-shrink</div><div>未設置flex-shrink</div><div>未設置flex-shrink</div>
</div>
<!-- 有flex-shrink -->
<div class="boxp">
<div class="shrink0">flex-shrink: 0</div>
<div class="shrink1">flex-shrink: 1</div>
<div class="shrink2">flex-shrink: 2</div>
<div class="shrink3">flex-shrink: 3</div>
<div class="shrink4">flex-shrink: 4</div>
</div>
</body>
</html>
效果:
關于flex-shrink計算規則:
- 在上例中,五個子元素,每個寬度是500px,所以總寬度是500*5=2500px
- 父元素寬度1660px,所以需要子元素們縮小2500-1660=840px
- 五個子元素
flex-shrink
屬性值分別為0
、1
、2
、3
、4
,所以總共縮小的份數是0+1+2+3+4=10,每一份的寬度是 840 ÷ 10 = 84px;- 第一個子元素
flex-shrink: 0
,所占份額是0,所以不進行縮小,最終寬度是500px- 第二個子元素
flex-shrink: 1
,所占份額是1,所以縮小1份,最終寬度是500-84*1=416px- 第三個子元素
flex-shrink: 2
,所占份額是2,所以縮小2份,最終寬度是500-84*2=332px- 第四個子元素
flex-shrink: 3
,所占份額是3,所以縮小3份,最終寬度是500-84*3=248px- 第五個子元素
flex-shrink: 4
,所占份額是4,所以縮小4份,最終寬度是500-84*4=164px
注意: 如果元素設置
margin
、padding
、border
,需要把這些也算進寬度里
4. flex-basis
定義子元素在主軸方向上的初始大小。
當一個元素同時被設置了 flex-basis (除值為 auto 外) 和 width (或者在 flex-direction: column 情況下設置了height) , flex-basis 具有更高的優先級.
翻譯成人話就是說:flex-basis
比 width
或height
優先級高!
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-basis</title>
<style>
.boxp{
background: lightgreen;
height: 100px;
display: flex;
margin-bottom: 30px;
}
.boxp div{
width: 500px;
height: 50px;
margin: 10px;
background: yellow;
}
.basis{
flex-basis: 300px;
}
</style>
</head>
<body>
<div class="boxp">
<div>width:500px;</div>
<div class="basis">width:500px; flex-basis: 300px;</div>
</div>
</body>
</html>
效果:
5. flex
flex屬性是flex-grow, flex-shrink 和 flex-basis的簡寫,默認值為0 1 auto。后兩個屬性可選。
6. align-self
設置當前子元素相對父元素的對齊方式,可覆蓋父元素的align-items
屬性。屬性值和align-items
的屬性值一樣。
代碼:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>flex-basis</title>
<style>
.boxp{
background: lightgreen;
height: 200px;
display: flex;
margin-bottom: 30px;
align-items: center;
}
.boxp div{
width: 170px;
height: 50px;
margin: 10px;
background: yellow;
}
.align-self{
align-self: flex-end;
}
</style>
</head>
<body>
<div class="boxp">
<div></div>
<div></div>
<div></div>
<div class="align-self">align-self: flex-end;</div>
<div></div>
</div>
</body>
</html>
效果: