原文:flex:1不等分的问题
一、现象
我们常常使用flex布局,来实现等分。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style type="text/css">
.box{
width: 100vw;
height: 100vh;
background: green;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.item{
flex: 1;
background: yellow;
height: 200px;
border: 2px solid #000000;
}
.test{
padding: 40px;
background-color: red;
}
</style>
<body>
<div class="box">
<span class="item test"></span>
<span class="item"></span>
<span class="item"></span>
<span class="item"></span>
</div>
</body>
<script type="text/javascript">
</script>
</html>
但是上述代码实现的效果:
都是flex:1,为啥第一个item会更宽一些呢?看起来就是那个padding导致的效果。可是按照我们平时的使用来看,flex:1应该均等分配空间才对。难道是因为box-sizing的原因,那么就给item加上box-sizing:border-box:
可以看到,高度上确实起作用了,但是宽度上似乎并没有起到作用。第一个的宽度上还是被padding撑开了。
二、原因分析
1、父容器flex布局,子元素不处理
先来看看基本的,没有flex等属性的时候,子元素默认的属性值是:
flex-grow: 0;//0的意思就是子元素不放大,这个属性规定了 flex-grow 项在 flex 容器中主轴方向上分配剩余空间的相对比例。
flex-shrink: 1;//flex 元素仅在默认宽度之和大于容器的时候才会发生收缩,其收缩的大小是依据 flex-shrink 的值。0时不缩小,值越大越缩小。
flex-basis: auto;//指定了 flex 元素在主轴方向上的初始大小。如果不使用 box-sizing 改变盒模型的话,那么这个属性就决定了 flex 元素的内容盒(content-box)的尺寸。并且当一个元素同时被设置了 flex-basis (除值为 auto 外) 和 width (或者在 flex-direction: column 情况下设置了height) , flex-basis 具有更高的优先级.
注:因为flex:1其实是这三个属性的简写,具体的网上到处都有。这里按下不表。
这里分析下,为啥子元素不设flex的时候会是这个样子。
1,四个子元素的内容都为空,且conten-box并没有设置宽度值,所以内容盒子conten-box的宽度是0.flex-basis: auto;就基于这个内容设置了四个子元素宽度为0,因为它的优先级高于width。
2,这时候四个子元素默认宽度之和小于容器宽度,flex-shrink: 1;没有生效。
3,又因为flex-grow: 0;不进行放大处理。所以宽度就是0。
三、实际原因
因为 依照 flex 的自动调整计算规范是不包含 padding 的。w3 规范这里的部分提到 flexItem 的可用空间要减去 margin、border、padding。所以想要均分的话,需要套个margin、border、padding一样的div。