在使用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>
可以發現我們在分配盒子的時候明明除了.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>
結果圖為
這種方法的優點是簡單直觀,缺點是不夠靈活,而且每個盒子的設定都要計算其所佔百分比。
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>
效果圖為
可以發現和方法一顯示結果一樣。這個方法更加便捷,可重用性更高,而且這種寫法可以廣泛應用於分割線,邊框等。