土薯工具 Toolshu.com 登录 用户注册

CSS flex 布局里,justify-content 和 align-items 为什么老是记混?

作者:bhnw 于 2026-05-22 16:52 发布 6次浏览 收藏 (0)

flex 布局用了这么多年,justify-contentalign-items 还是有人老是记混。不是因为笨,是因为这两个属性的行为会随 flex-direction 变化,记住"横向纵向"没用,下次换了方向又乱了。

这篇文章从主轴和交叉轴的概念出发,讲清楚为什么记混、怎么记对,以及几个常见场景的写法。


先搞清楚一件事:轴的方向不是固定的

很多人背的是"justify-content 控制水平方向,align-items 控制垂直方向"。这句话在默认情况下是对的,但只要 flex-direction 改了,这句话就错了。

准确的描述是:

  • justify-content:控制主轴方向的对齐
  • align-items:控制交叉轴方向的对齐

主轴是什么?就是 flex-direction 指定的方向:

flex-direction: row;         /* 主轴是水平方向(默认) */
flex-direction: row-reverse; /* 主轴是水平方向,但从右往左 */
flex-direction: column;      /* 主轴是垂直方向 */
flex-direction: column-reverse; /* 主轴是垂直方向,但从下往上 */

交叉轴永远和主轴垂直。主轴是水平的,交叉轴就是垂直的;主轴是垂直的,交叉轴就是水平的。

所以当你把 flex-direction 改成 column,两个属性的效果就完全反过来了:

/* flex-direction: row(默认) */
.container {
  display: flex;
  justify-content: center;  /* 水平居中 */
  align-items: center;      /* 垂直居中 */
}

/* flex-direction: column */
.container {
  display: flex;
  flex-direction: column;
  justify-content: center;  /* 垂直居中! */
  align-items: center;      /* 水平居中! */
}

记这个最简单的方式:justify 跟着主轴走,align 跟着交叉轴走,主轴在哪 justify 就控制哪个方向。


垂直居中,为什么有时候不生效?

这是最常见的问题。写了 align-items: center,元素就是不居中。

原因几乎只有一个:容器没有高度,或者高度不够。

align-items 控制的是元素在交叉轴上的位置,但如果容器本身没有指定高度,它的高度就等于子元素的高度,根本没有多余的空间,居中也就无从谈起。

/* 不生效:容器高度就是内容高度,没有空间居中 */
.container {
  display: flex;
  align-items: center;
}

/* 生效:给容器一个高度 */
.container {
  display: flex;
  align-items: center;
  height: 300px; /* 或者 min-height,或者 100vh */
}

做全屏垂直居中:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

space-between、space-around、space-evenly 有什么区别?

这三个值都是 justify-content 的选项,都是把剩余空间分配给间距,但分配方式不同。

假设容器里有三个元素,用示意图来看:

space-between:  |A    B    C|   首尾元素贴边,间距在中间平均分
space-around:   | A   B   C |   每个元素两侧各有等量空间(首尾是内部间距的一半)
space-evenly:   |  A   B   C  | 所有间距完全相等,包括首尾

实际写代码时:

/* 导航栏:logo 在左,链接在右 */
.nav {
  display: flex;
  justify-content: space-between;
}

/* 卡片列表:卡片之间和两侧都有间距 */
.cards {
  display: flex;
  justify-content: space-evenly;
}

不过现在更推荐直接用 gap 来控制间距,而不是依赖 justify-content 的 space 系列值,因为 gap 更直观,而且在换行时行为也更符合预期:

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px; /* 元素之间的间距,首尾不加 */
}

align-items 和 align-content 的区别

这也是常见的困惑点。

  • align-items:控制每一行内部,子元素在交叉轴上的对齐方式
  • align-content:控制多行在容器交叉轴上整体的分布方式,只有在 flex-wrap: wrap 且实际发生了换行时才有效果
/* 只有一行内容时,align-content 没有效果 */
.container {
  display: flex;
  align-items: center;    /* 这行有效:控制行内对齐 */
  align-content: center;  /* 这行无效:只有一行,没有多行分布可言 */
}

/* 多行时,两个属性同时发挥作用 */
.container {
  display: flex;
  flex-wrap: wrap;
  height: 400px;
  align-items: flex-start;   /* 每行内部:顶部对齐 */
  align-content: space-between; /* 多行之间:两端对齐 */
}

记忆方式:items 管的是行内的事,content 管的是行与行之间的事。


几个常见布局的写法

水平垂直居中(最常用)

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

导航栏:左边 logo,右边按钮

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

把最后一个元素推到最右边

.nav {
  display: flex;
  align-items: center;
}

.nav .last-item {
  margin-left: auto; /* auto margin 会吃掉所有剩余空间 */
}

等高卡片列表

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: stretch; /* 默认值,子元素自动拉伸到等高 */
}

竖向排列,水平居中

.container {
  display: flex;
  flex-direction: column;
  align-items: center; /* 注意:column 时,align-items 控制水平方向 */
}

想直接验证这些布局效果,把 HTML 和 CSS 粘到 HTML 在线编辑器 里实时预览,改一个属性马上看到变化,比在本地建文件测试快多了。

发现周边 发现周边
评论区

加载中...