CSS 小結筆記之解決flex佈局邊框對不齊

Assist發表於2018-10-15

在使用flex 進行伸縮佈局的時候,經常會給子盒子設定邊框,這時經常會出現上下邊框對不齊的情況。本篇文章來探討並解決這個問題。

具體出現的問題如下圖所示

具體程式碼如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            font-size: 16px;
        }
        
        .fa {
            height: 18.75em;
            width: 31.25em;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
        }
        
        .l1,
        .l2 {
            flex: 1;
            background-color: aqua;
            display: flex;
            border: 0.25em solid black;
            border-right: none;
        }
        
        .l2 {
            border-top: none;
            background-color: deeppink;
        }
        
        .son1,
        .son2,
        .son3,
        .son4,
        .son5 {
            box-sizing: border-box;
            border-right: 0.25em solid black;
            flex: 1;
        }
        
        .son5 {
            flex: 2;
        }
    </style>
</head>

<body>
    <div class="fa">
        <div class="l1">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son5"></div>
        </div>
        <div class="l2">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son3"></div>
            <div class="son4"></div>
        </div>

    </div>

</body>

</html>
View Code

可以發現我們在分配盒子的時候明明除了.son5 設定為flex:2外, 都是設定了 flex:1 ;按照我們預想的結果應該是對齊的,但是事實上在新增邊框之後,邊框並不能對齊。

產生這個問題的主要原因如下:

首先我們知道flex :n 是flex:n n 0 的簡寫,主要的作用是將剩餘的空間進行按比例劃分。

而我們在指定了邊框大小後,邊框將會佔用固定的大小,那麼可分配的剩餘大小就會改變。

如上例(計算原理不清楚的同學可以參考CSS 小結筆記之伸縮佈局 (flex)):

藍色區域

共有四個豎邊框,大小共為4*0.25*16=16px;

那麼剩下可分配區域的大小為:31.25*16-16=484px

所以藍色區域的三塊大小分別是:1*484/4=121px、1*484/4=121px、2*484/2=242px

紅色區域

共有五個豎邊框,大小共為5*0.25*16=20px;

那麼剩下可分配區域的大小為:31.25*16-20=480px

所以紅色區域的四塊大小都是:1*480/4=120px

因此紅色區域和藍色區域的子盒子大小實際上是不對等的,因此邊框出現了偏移。

下面將給出這個問題的解決方法:

1、最基本的方法

  使用伸縮基準值(flex-basis)即flex 值中的百分比+border-box 來實現

  首先把右邊框都設定為子盒子的邊框,接著給子盒子新增屬性 box-sizing: border-box,最後將flex:1 改為 flex:0 0 25%,將flex:2改為 flex:0 0 50%。

  這麼做的原理是,將子盒子的盒子計算大小模式改為 border-box ,即分配或計算式,邊框和內邊距也被視為盒子大小的一部分。

  之後再設定每個盒子的起始長度,這樣就可以解決這個問題。

  具體程式碼如下

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            font-size: 16px;
        }
        
        .fa {
            height: 18.75em;
            width: 31.25em;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
        }
        
        .l1,
        .l2 {
            flex: 1;
            background-color: aqua;
            display: flex;
            border: 0.25em solid black;
            border-right: none;
        }
        
        .l2 {
            border-top: none;
            background-color: deeppink;
        }
        
        .son1,
        .son2,
        .son3,
        .son4,
        .son5 {
            box-sizing: border-box;
            border-right: 0.25em solid black;
            flex: 0 0 25%;
        }
        
        .son5 {
            flex: 0 0 50%;
        }
    </style>
</head>

<body>
    <div class="fa">
        <div class="l1">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son5"></div>
        </div>
        <div class="l2">
            <div class="son1"></div>
            <div class="son2"></div>
            <div class="son3"></div>
            <div class="son4"></div>
        </div>

    </div>

</body>

</html>
View Code

 

  結果圖為

  

  這種方法的優點是簡單直觀,缺點是不夠靈活,而且每個盒子的設定都要計算其所佔百分比。

2、將邊框畫出

  我們知道在不給出邊框的時候,是不會出現問題的,而且即使不給出邊框,盒子與盒子之間也是有分界線的,因此我們可以自己在盒子的邊線上通過定位畫出一個邊框。

  通過::after偽元素選擇器,設定其高度100%,寬度為0.25em,定位靠右。這樣只要給需要邊框效果的盒子增加這個類,則相當於給盒子增加了右邊框。 

 
        .bd-r {
            position: relative;
        }
        
        .bd-r::after {
            content: "";
            width: 0.25em;
            height: 100%;
            position: absolute;
            background-color: black;
            top: 0;
            right: 0;
        }

  完整程式碼如下:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            font-size: 16px;
        }
        
        .fa {
            height: 18.75em;
            width: 31.25em;
            margin: 0 auto;
            display: flex;
            flex-direction: column;
        }
        
        .l1,
        .l2 {
            flex: 1;
            background-color: aqua;
            display: flex;
            border: 0.25em solid black;
            border-right: none;
        }
        
        .l2 {
            border-top: none;
            background-color: deeppink;
        }
        
        .son1,
        .son2,
        .son3,
        .son4,
        .son5 {
            flex: 0 0 25%;
        }
        
        .son5 {
            flex: 0 0 50%;
        }
        
        .bd-r {
            position: relative;
        }
        
        .bd-r::after {
            content: "";
            width: 0.25em;
            height: 100%;
            position: absolute;
            background-color: black;
            top: 0;
            right: 0;
        }
    </style>
</head>

<body>
    <div class="fa">
        <div class="l1">
            <div class="son1 bd-r"></div>
            <div class="son2 bd-r"></div>
            <div class="son5 bd-r"></div>
        </div>
        <div class="l2">
            <div class="son1 bd-r"></div>
            <div class="son2 bd-r"></div>
            <div class="son3 bd-r"></div>
            <div class="son4 bd-r"></div>
        </div>

    </div>

</body>

</html>
View Code

  效果圖為

  

  可以發現和方法一顯示結果一樣。這個方法更加便捷,可重用性更高,而且這種寫法可以廣泛應用於分割線,邊框等。

 

  

 

相關文章