CSS 小结笔记之解决flex布局边框对不齐
在使用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>
效果图为
可以发现和方法一显示结果一样。这个方法更加便捷,可重用性更高,而且这种写法可以广泛应用于分割线,边框等。