1 傳統布局與flex布局
傳統布局(以之前所學的PC端布局為例)
- 兼容性好
- 布局繁瑣
- 局限性,不可以在移動端很好的布局
flex彈性布局 - 操作方便簡單,移動端應用廣泛
- PC端瀏覽器支持情況較差
- IE11或更低版本,不支持或僅部分支持
建議 - 如果是PC端頁面布局,采用傳統布局
- 如果是移動端或者不考慮兼容性問題的PC端布局,采用flex彈性布局
2 布局原理
flex用來為盒狀模型提供最大的靈活性,任何一個容器都可以指定為flex布局。
- 當為父盒子設置為flex布局之后,子元素的float、clear、vertical-align屬性將失效。(不需要浮動、清除浮動、盒子垂直居中,因為flex都可以代替這些功能)
- 伸縮布局=彈性布局=伸縮盒布局=彈性盒布局=flex布局
采用flex布局的元素稱為flex容器,簡稱容器。它所有子元素自動成為容器成員,稱為flex項目,簡稱項目。
- 體驗中div就是flex父容器
- 體驗中span就是子容器flex項目
- 子容器可以橫向排列也可以縱向排列
總結flex布局原理:
就是通過給父盒子添加flex屬性,來控制子盒子的位置和排列方式。
3 父項常見屬性
3.1 flex-direction設置主軸的方向
flex-direction屬性決定主軸的方向(即項目的排列方向)
注意:主軸和側軸是會變化的,就看flex-direction設置誰為主軸,剩下的就是側軸,我們的子元素是根據主軸來排列的。
flex-direction的屬性值:
- row(默認值從左到右)
- row-reverse(從右到左)
- column(從上到下)
- column-reverse(從下到上)
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
/* 給父親添加flex屬性 */
display: flex;
/* 添加flex之后,行內元素也有寬高;*/
width: 500px;
height: 200px;
background-color: pink;
/* 默認沿着x軸排列 */
/* flex-direction: row; 默認值 */
flex-direction: row-reverse;
/* flex-direction: column; */
/* flex-direction: column-reverse; */
}
div span {
width: 100px;
height: 50px;
background-color: skyblue;
margin: 2px 10px;
}
</style>
-
flex-direction: row;
-
flex-direction: row-reverse;
-
flex-direction: column;
-
flex-direction: column-reverse;
3.2 justify-content設置主軸的子元素排列方式
justify-content屬性定義了項目在主軸上的對齊方式;注意:使用這個屬性之前要確定好主軸是哪一個。
- flex-start:從頭開始,如果主軸是x則從左到右(默認值)
- flex-end:從尾部開始排列
- center:在主軸居中對齊,如果主軸是x軸則水平居中
- space-around:平分剩余空間
- space-between:先兩邊貼邊再平分剩余空間(重要)
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
</div>
</body>
<style>
div {
/* 給父親添加flex屬性 */
display: flex;
/* 添加flex之后,行內元素也有寬高;*/
width: 800px;
height: 200px;
background-color: pink;
/* 主軸默認是x軸 */
/* 1. 左對齊 */
/* justify-content: flex-start; */
/* 2. 右對齊 (子盒子順序不變)*/
/* justify-content: flex-end; */
/* 3. 居中對齊 */
/* justify-content: center; */
/* 4. 平分剩余空間 此時對span設置的左右外邊距會失效*/
/* justify-content: space-around; */
/* 5. 先兩邊貼邊再平分所有空間 span如果設置了左右外邊距,則兩端盒子的外邊距會保留*/
justify-content: space-between;
}
div span {
width: 100px;
height: 50px;
background-color: skyblue;
margin: 2px 10px;
}
</style>
-
justify-content: flex-start;左對齊
-
justify-content: flex-end; 右對齊 (子盒子順序不變)
-
justify-content: center;居中對齊
-
justify-content: space-around;平分剩余空間 此時對span設置的左右外邊距會失效
-
justify-content: space-between;先兩邊貼邊再平分所有空間 span如果設置了左右外邊距,則兩端盒子的外邊距會保留
3.3 flex-wrap設置主軸的子元素是否換行
默認情況下,項目都排在一條線(軸線)上。flex-wrap屬性定義,flex布局默認是不換行的。
- nowrap:默認值,不換行
- wrap:換行
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
</div>
</body>
<style>
div {
/* 給父親添加flex屬性 */
display: flex;
/* 添加flex之后,行內元素也有寬高;*/
width: 500px;
height: 200px;
background-color: pink;
/* flex布局中,默認的子元素是不換行的,如果裝不開,會縮小子元素寬度,放到父元素里面 */
/* 1.默認值 默認不換行 */
flex-wrap: nowrap;
/* 2. 換行 */
/* flex-wrap: wrap; */
}
div span {
width: 150px;
height: 100px;
background-color: skyblue;
margin: 2px 10px;
}
</style>
-
flex-wrap: nowrap;默認值 默認不換行
-
flex-wrap: wrap;放不下就換行
3.4 align-items設置側軸上的子元素排列方式(單行)
該屬性是控制子項在側軸(默認是y軸)上的排列方式,在子項為單項的時候使用。
- flex-start:默認值 從上到下
- fllex-end:從下到上
- center:擠在一起(垂直居中)
- stretch:拉伸
center:擠在一起(垂直居中)舉例如下
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
/* 給父親添加flex屬性 */
display: flex;
/* 添加flex之后,行內元素也有寬高;*/
width: 800px;
height: 200px;
background-color: pink;
/* 沿着主軸(x軸) 水平居中對齊 */
justify-content: center;
/* 沿着側軸(y軸) 垂直居中 */
align-items: center;
}
div span {
width: 150px;
height: 100px;
background-color: skyblue;
color: #fff;
margin: 10px;
}
</style>
對於stretch:拉伸,舉例如下
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
/* 給父親添加flex屬性 */
display: flex;
/* 添加flex之后,行內元素也有寬高;*/
width: 800px;
height: 200px;
background-color: pink;
/* 沿着主軸(x軸) 水平居中對齊 */
justify-content: center;
/* 沿着側軸(y軸) 拉伸 */
align-items: stretch;
}
div span {
width: 150px;
/* height: 100px; 使用stretch的時候要將子項的height取消,否則無法拉伸 */
background-color: skyblue;
color: #fff;
margin: 10px;
}
</style>
3.5 align-content設置側軸上的子元素排列方式(多行)
align-items只適用於單行,就像讓文字垂直居中line-height=height也是只適用於單行,所以出現了align-content用於設置多行。
align-content設置子項在側軸上的排列方式,且只可以用於子項出現換行的情況(多行),在單行下是沒有效果的。
- flex-start:默認值,從側軸的頭部開始排列
- flex-end:從側軸的尾部開始排列
- center:在側軸中間顯示
- space-around:子項在側軸平分剩余空間
- space-between:子項在側軸先分布在兩頭,再平分剩余空間
- stretch:設置子項元素高度平分父元素高度(設置該屬性的時候子項不可以給高度)
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
<span>4</span>
<span>5</span>
<span>6</span>
</div>
</body>
<style>
div {
/* 給父親添加flex屬性 */
display: flex;
/* 添加flex之后,行內元素也有寬高;*/
width: 800px;
height: 250px;
background-color: pink;
/* 換行 */
flex-wrap: wrap;
/* 因為有了換行,此時我們側軸上控制子元素的對齊方式適用的是align-content */
/* 1.錯誤 兩行直接空出較大距離 */
/* align-items: flex-start; */
/* 2. 正確 行與行之間隔着的僅僅是自己設定的margin */
/* align-content: flex-start; */
/* 3. 錯誤 */
/* align-items: center; */
/* 4. 正確 兩行的盒子整體都居中了 */
/* align-content: center; */
/* 5. space-between */
/* align-content: space-between; */
/* 6. space-around */
/* align-content: space-around; */
/* 7.子項平分父盒子的高度 設置該屬性的時候,子項的高度應該注釋掉 */
align-content: stretch;
}
div span {
width: 150px;
/* height: 50px; */
background-color: skyblue;
color: #fff;
margin: 10px;
}
</style>
-
1 align-items: flex-start;錯誤 兩行直接空出較大距離
-
2 align-content: flex-start;正確 行與行之間隔着的僅僅是自己設定的margin
-
3 align-items: center;錯誤
-
4 align-content: center;正確 兩行的盒子整體都居中了
-
5 space-between
-
6 space-around
-
7 align-content: stretch;子項平分父盒子的高度 設置該屬性的時候,子項的高度應該注釋掉
align-items和align-content區別
- align-items適用於單行情況下,只有上對齊、下對齊、居中和拉伸
- align-content適應於換行(多行)的情況(單行情況下無效)可以設置上對其、下對齊、居中、拉伸、平均分配剩余空間等屬性。
- 總結就是單行找align-items多行找align-content
- 關鍵看“行數”而不是flex-wrap: wrap;
3.6 flex-flow是flex-direction和flex-wrap屬性的父盒屬性
/* 設置主軸方向 */
/* flex-direction: column; */
/* 是否換行 */
/* flex-wrap: wrap; */
/* 設置主軸方向和是否換行可以簡寫如下 */
flex-flow: column wrap;
4. flex布局子項常見屬性
- flex子項占的份數
- align-self控制子項在自己側軸的排列方式
- order屬性定義子項的排列順序(前后順序)
4.1 flex屬性
flex屬性定義子項分配“剩余”空間,用flex來表示占有多少份數,flex默認值是1
- 利用flex來實現兩側盒子固定,中間盒子自適應
<body>
<section>
<div></div>
<div></div>
<div></div>
</section>
</body>
<style>
section {
display: flex;
width: 60%;
height: 150px;
background-color: pink;
margin: 0 auto;
}
section div:nth-child(1) {
width: 100px;
height: 150px;
background-color: red;
}
section div:nth-child(2) {
flex: 1;
background-color: green;
}
section div:nth-child(3) {
width: 100px;
height: 150px;
background-color: blue;
}
</style>
說明:1和3號盒子有寬帶,它們一共占據了200px寬,那么剩余空間就是section的寬減去這200px的寬,即2號盒子將剩余空間全占了。
- 用flex實現不同盒子的固定比例占據
<body>
<section>
<div></div>
<div></div>
<div></div>
</section>
</body>
<style>
section {
display: flex;
width: 60%;
height: 150px;
background-color: pink;
margin: 0 auto;
}
section div:nth-child(1) {
width: 100px;
height: 150px;
background-color: red;
}
section div:nth-child(2) {
flex: 1;
background-color: green;
}
section div:nth-child(3) {
width: 100px;
height: 150px;
background-color: blue;
}
</style>
三個盒子所占寬帶的比例就是1:2:1
4.2 控制子項自己在側軸上的排列方式
- 讓3個子盒子沿着側軸底側對齊
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
display: flex;
width: 80%;
height: 200px;
background-color: pink;
/* 1. 讓3個子盒子沿着側軸底側對齊 */
align-items: flex-end;
}
div span {
width: 150px;
height: 60px;
background-color: skyblue;
margin-right: 5px;
}
/* div span:nth-child(3) {
align-self: flex-end;
} */
</style>
- 只讓第三個盒子沿着底側對齊
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
display: flex;
width: 80%;
height: 200px;
background-color: pink;
/* 2. 只讓第三個盒子沿着底側對齊 */
}
div span {
width: 150px;
height: 60px;
background-color: skyblue;
margin-right: 5px;
}
/* 2. 只讓第三個盒子沿着底側對齊 */
div span:nth-child(3) {
align-self: flex-end;
}
</style>
4.3 order屬性定義項目的排列順序
數值越小,排列越靠前,默認值為0
注意:和z-index不一樣
<body>
<div>
<span>1</span>
<span>2</span>
<span>3</span>
</div>
</body>
<style>
div {
display: flex;
width: 80%;
height: 200px;
background-color: pink;
}
div span {
width: 150px;
height: 60px;
background-color: skyblue;
margin-right: 5px;
}
div span:nth-child(2) {
/* order默認值是0,-1比0小,所以在前面 */
order: -1;
}
</style>