问题描述
先来看一个需求场景:
上图中需要实现在水平方向上子元素之间、子元素和父容器边框之间的间距要相等。
实现的方法有很多,我们这里要讨论的是:如何简洁地使用 Flex 布局来实现?
我这里采用的方法是:使用自动的外边距在主轴上对齐。
自动的外边距在主轴上对齐
我们先来看一下 MDN 关于这个的解释:
… 自动的外边距会占据全部的多余的空间——在一个块上设置自动的左右外边距可以使它居中。两边尽可能占据多的空间,块就被置于中间位置了。
这很好理解:自动外边距将平分全部的剩余空间。下面就来尝试下这个方案吧,代码如下:
<div class="container">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
.container {
display: flex;
align-items: center;
box-sizing: border-box;
border: 2px dashed #7cb305;
width: 600px;
height: 200px;
margin: auto;
}
.item {
display: flex;
justify-content: center;
align-items: center;
margin: 0 auto;
width: 100px;
height: 100px;
background: #722ed1;
border-radius: 50%;
color: #fff;
font-size: 22pt;
}
然后看一下效果:
貌似有点不对。仔细看看子元素之间的间距比到边框的大,大概是子元素到边框的两倍,跟我们预期的效果有差异。
按照 MDN 的解释来看,自动的外边距会等分剩余空间,但为什么会出现上图的情况呢?下面来谈一下我的理解。
主轴剩余空间“分配权重”与子元素自动外边距的关系
这个分配权重关系没有在 MDN 上找到相关解释,纯粹是个人见解,我们可以这样来理解:
- 如果一个子元素在主轴的一个区域(或方向)上声明了
margin-*: auto
,那么这个空间的分配权重 + 1 - 如果另外一个子元素也在同样的区域(或方向)上有自动外边距的声明,那么分配权重再 + 1
- 在这些声明了自动外边距的区域上,剩余空间根据分配权重来划分间距大小
首先,这个理解显然是可以满足 MDN 上的解释。然后我们再来看看上图的情况怎么解释:
- 我们把
子元素 1
的左边区域命名为间距区域 1
,子元素 1
的右边区域命名为间距区域 2
-
子元素 1
的左边和右边都有自动外边距,那么间距区域 1 的权重 = 1
,间距区域 2 的权重 = 1
-
子元素 2
的左边和右边都有自动外边距,那么间距区域 2 的权重 = 1 + 1 = 2
- 最后
间距区域 1 的权重
和间距区域 1 的权重
就是 1:2 的关系 - 其他区域依次类推,最后根据权重划分间距区域大小
然后依据这种理解我们来调整下代码,只需要在每个相隔的区域上声明一次自动外边距就好了:
- 首先我们把
.item
这个样式上的margin
去掉 - 然后只在 html 的
子元素 1
和子元素 3
上设置style="margin: 0 auto"
调整后如下:
<div class="container">
<div class="item" style="margin: 0 auto">1</div>
<div class="item">2</div>
<div class="item" style="margin: 0 auto">3</div>
</div>
.container {
display: flex;
align-items: center;
box-sizing: border-box;
border: 2px dashed #7cb305;
width: 600px;
height: 200px;
margin: auto;
}
.item {
display: flex;
justify-content: center;
align-items: center;
width: 100px;
height: 100px;
background: #722ed1;
border-radius: 50%;
color: #fff;
font-size: 22pt;
}
OK,问题解决了
根据这个理解还有一种设置也可以达到同样效果:
<div class="container">
<div class="item" style="margin-left: auto">1</div>
<div class="item" style="margin: 0 auto">2</div>
<div class="item" style="margin-right: auto">3</div>
</div>
以上代码已放到 codepen 上:https://codepen.io/deepfunc/pen/BembyQ
各位童鞋如果觉得还可以请点赞和收藏下哈