flex布局出现之前,想让一行元素两端贴边、中间元素均匀分布,需要给每个元素写margin、算宽度,元素一多就乱成一团。有了justify-content: space-between之后,一行声明就能搞定这件事。不过这个属性看起来简单,实际用起来还是有不少细节值得说清楚,比如它的分配规则到底是什么、和space-around有什么区别、子元素数量不确定时怎么保证布局不塌。

space-between的工作原理到底是什么
先明确一点:justify-content作用在flex容器的主轴方向上。容器设置为display: flex后,主轴默认是水平方向,justify-content控制的就是子元素在水平方向上如何排布。而space-between的含义是:第一个子元素贴住主轴起点,最后一个子元素贴住主轴终点,剩下的空间平均分配到每两个相邻子元素之间。
注意这里的关键词是“之间”。也就是说,第一个元素前面没有间距,最后一个元素后面也没有间距,所有空隙都出现在元素与元素的夹缝里。这一点和space-around完全不同,后者是每个元素两侧各分一份相等间距,导致首尾元素与容器边缘的间距只有中间间距的一半;而space-evenly则是所有空隙(包括首尾)完全相等。三个属性放在一起对比,用一张表就能看明白:
| 属性值 | 首元素与起点间距 | 元素之间间距 | 末元素与终点间距 |
|---|---|---|---|
| space-between | 0 | 平均分配 | 0 |
| space-around | 间距的一半 | 平均分配 | 间距的一半 |
| space-evenly | 与中间相等 | 平均分配 | 与中间相等 |
最基础的用法只需要两行CSS:
.container {
display: flex;
justify-content: space-between;
}
.container span {
/* 不需要写任何margin,间距由容器统一分配 */
}
还有一点容易被忽略:分配的是“剩余空间”。如果子元素的宽度加起来已经撑满了容器,那space-between没有任何空间可分,表现上就和不设置一样。此外,如果容器设置了flex-wrap: wrap且子元素换行,每一行都会独立应用一次space-between的逻辑,每行的首尾元素都会贴边,这就是后面要讲的“最后一行对不齐”问题的根源。
几个最典型的应用场景及完整代码
场景一:顶部导航栏
导航栏是space-between出现频率最高的地方。左侧放logo,中间放菜单,右侧放登录按钮,三块内容天然适合两端分布:
<nav class="navbar">
<div class="logo">LOGO</div>
<ul class="menu">
<li><a href="/home">首页</a></li>
<li><a href="/product">产品</a></li>
<li><a href="/about">关于</a></li>
</ul>
<button class="login">登录</button>
</nav>
<style>
.navbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
height: 60px;
background: #fff;
border-bottom: 1px solid #eee;
}
.menu {
display: flex;
gap: 24px; /* 菜单内部用gap控制间距,不参与两端分布 */
list-style: none;
}
</style>
这里有个技巧:把中间的菜单看成一个整体,让.menu自己也是一个flex容器,菜单内部的间距用gap控制。这样外层只负责三块内容的分布,内外互不干扰。
场景二:多列卡片均匀铺开
一行放四个卡片并让它们均匀分布,很多人会习惯性写margin-right,最后一个再单独清除,写起来很啰嗦。用space-between一行就够:
.card-list {
display: flex;
justify-content: space-between;
}
.card {
width: 23%; /* 四张卡片,剩余空间自动分到中间三道缝里 */
background: #f7f8fa;
border-radius: 8px;
padding: 16px;
}
这种写法的好处是间距是自动计算的,容器宽度变化时不需要重新算margin。但要注意卡片宽度最好用百分比或者弹性单位,如果固定像素宽度,容器太窄时元素会溢出。
场景三:移动端底部操作栏
详情页底部的“加入购物车”和“立即购买”两个按钮,一个贴左一个贴右,正是两个元素时space-between的经典用法:
.footer-bar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 16px;
background: #fff;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.06);
}
当容器里只有两个子元素时,space-between的行为最直观:一个去起点,一个去终点,中间的全部空间变成空隙,没有任何多余的计算。
常见坑点与解决办法
子元素数量不固定导致布局失衡
后端返回的数据条数不确定时,如果某次只返回了三个卡片而布局按四个设计,space-between会把这三个卡片强行拉开,前两个贴边、中间留大缝,视觉上非常难看。常见的处理思路有两种:一种是给容器加上flex-wrap: wrap并给每个卡片一个固定的基准宽度,配合下文的对齐补位方案;另一种是不用space-between,改用gap加固定间距,让不足一行的元素从左往右自然排列,视觉上更整齐。
换行后最后一行被拉扯
设置了flex-wrap: wrap之后,如果总共有九个卡片分三行显示,前两行每行四个元素可以正常分布,但最后一行只有一个元素时,这个元素会被space-between推到行尾,和上面的行完全对不上。解决思路是补占位元素:根据每行的最大数量,在末尾补上若干个不可见的占位块:
<div class="grid">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<!-- 补的占位块,高度设为0避免占用视觉空间 -->
<div class="item placeholder"></div>
</div>
<style>
.grid {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.item {
width: 23%;
height: 100px;
}
.placeholder {
height: 0;
border: none;
visibility: hidden; /* 仍参与布局分配,但视觉上不可见 */
}
</style>
如果不想手动补占位,也可以直接换用CSS Grid:grid-template-columns: repeat(4, 1fr)配合gap,天然不存在最后一行被拉开的问题,需要严格对齐的列表布局优先考虑Grid。
与其他属性的冲突
当子元素设置了flex-grow时,剩余空间会被增长因子吃掉,space-between就没有空间可分,两个属性会互相抵消效果。同样的道理,如果子元素用了margin: 0 auto之类的居中写法,也会干扰分布结果。使用space-between时,子元素的间距应该完全交给容器管理,不要再用margin去手动干预水平方向的位置。
兼容性方面完全不用担心,space-between从IE10时代就支持了,现代浏览器全覆盖。唯一需要注意的是IE10需要写display: -ms-flexbox,不过现在这类老旧环境基本可以忽略。掌握了“剩余空间只分给元素之间”这一个核心规则,剩下的各种布局变体都能快速推导出来。
justify-contentspace-betweenflex布局修改时间:2026-09-07 18:18:49