讲解

上一章的 API 组合起来能解决 80% 的日常布局,这一章把高频套路一次讲透。第一个是「绝对居中」:容器 justify-content: center + align-items: center,两行代码让子元素水平垂直居中——这个曾经需要各种 hack 的世纪难题,在 Flexbox 里已经不值一提。第二个是「两端分布」:justify-content: space-between 让首尾项贴边、中间均分;当只有两项(logo 和菜单)时,给后项 margin-left: auto 效果相同且更灵活。

第三个是「等高列」:弹性项默认 align-items: stretch,同一行里的卡片自动拉成一样高——过去要靠表格或 JS 的等高难题现在零成本。配合 flex-direction: column + margin-top: auto,还能把卡片里的按钮统一推到底部对齐,无论标题长短。第四个是「媒体对象」(左图右文):容器 flex + gap,图片 flex: none 固定尺寸,文字区 flex: 1 + min-width: 0。第五个是「底部固定 footer」(上一章示例已出现):页面 column 布局 + main flex: 1,内容不足一屏时 footer 也沉在底部。

换行布局有个细节:flex-wrap: wrap 配合 space-between 时,最后一行如果只有两个项目会被拉到天各一方。对策是给项目固定 basis(如 flex: 0 1 calc(33.33% - 11px)),或者最后一行的对齐需求复杂时干脆上 Grid。此外 order 属性可以改变弹性项的视觉顺序(默认 0,越小越靠前),做响应式「移动端图片在上、桌面端图片在右」时有用,但注意视觉顺序和 DOM 顺序不一致会影响键盘和读屏,慎用。

示例

/* 1. 垂直水平居中(弹窗、空状态插画) */
.center-box {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

/* 2. 等高卡片 + 按钮底部对齐 */
.card-row {
  display: flex;
  gap: 16px;
}
.card-row .card {
  flex: 1;
  display: flex;
  flex-direction: column; /* 卡片内部再套一层纵向 flex */
}
.card-row .actions {
  margin-top: auto; /* 按钮区推到卡片底部,与兄弟卡片对齐 */
}

/* 3. 媒体对象:左图右文 */
.media {
  display: flex;
  gap: 12px;
}
.media img {
  flex: none;
  width: 64px;
  height: 64px;
  border-radius: 8px;
}
.media .body {
  flex: 1;
  min-width: 0; /* 长文可收缩,配合省略号 */
}

/* 4. 响应式顺序调整 */
.feature {
  display: flex;
  gap: 24px;
}
@media (max-width: 640px) {
  .feature .illustration {
    order: -1; /* 小屏把插图提到文字上方 */
  }
}

常见坑

  • space-between 最后一行散落:换行布局中末行不满时被均分拉开。改用固定 basis,或换 Grid 的 repeat(3, 1fr)。
  • 等高卡里按钮对不齐:只给卡片行设了 stretch 还不够,卡片内部要 flex-direction: column 并给按钮区 margin-top: auto,两层配合。
  • order 打乱可访问性顺序:视觉顺序与 DOM 顺序脱节,Tab 键跳动混乱。只在纯装饰性调整时用 order。
  • 套路堆砌过度嵌套:为实现一个对齐套了四五层 div。先想想 Grid 或更简单的 margin: auto 能否一步解决,容器越少越好维护。
  • 居中用定死宽高:居中容器配合 min-height 而不是 height,内容溢出时才不会被裁掉(配合 margin: auto 于弹性项可兼得居中与不裁剪)。

小结

居中、两端分布、等高列、媒体对象、沉底 footer 五个套路覆盖日常大多数场景;换行布局的末行问题考虑 Grid。下一章正式进入二维布局:Grid。