flex布局---8.flex布局原理


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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM