跳到主要内容

Flex 布局(弹性盒):核心概念、常用属性、常见题怎么答?

面试速答(30 秒版 TL;DR)

  • Flex 的本质:把父容器变成 display: flex 后,子项(flex items)沿 主轴(main axis) 排列,并可按“伸缩规则”分配剩余空间。
  • 三个最核心点:
    • 主轴方向:flex-direction 决定横排还是竖排,以及起点方向。
    • 对齐:主轴用 justify-content,交叉轴用 align-items(单行)/align-content(多行)。
    • 伸缩:子项用 flex: grow shrink basis 控制“怎么分配宽高”。

一、心智模型:容器管“轴与对齐”,子项管“伸缩”

  1. 先确定主轴与交叉轴:
    • flex-direction: row:主轴横向(默认)
    • flex-direction: column:主轴纵向
  2. 再看是否换行:
    • flex-wrap: nowrap(默认):不换行,空间不够就缩
    • flex-wrap: wrap:可换行,形成多行(或多列)
  3. 最后才是伸缩与对齐:
    • 子项的 flex-* 决定“怎么长怎么缩”
    • 容器的 justify/align-* 决定“空白怎么分配、怎么对齐”

二、容器属性(Container)高频点

1)display: flex | inline-flex

  • flex:块级 flex 容器(常用)
  • inline-flex:行内级 flex 容器(容器本身像 inline-block 一样排版)

2)flex-direction

.row {
display: flex;
flex-direction: row; /* 默认:从左到右 */
}
.col {
display: flex;
flex-direction: column; /* 从上到下 */
}

3)justify-content(主轴对齐)

常用值:flex-startcenterspace-betweenspace-aroundspace-evenly

4)align-items(交叉轴对齐,单行)

常用值:stretch(默认)、flex-startcenterflex-endbaseline

5)gap(推荐)

Flex 里做间距优先用 gap,比写一堆 margin 更稳定、更好维护:

.list {
display: flex;
gap: 12px;
}

三、子项属性(Item)高频点

1)flex 到底怎么理解

flex 是简写:flex: <flex-grow> <flex-shrink> <flex-basis>

常见写法:

/* 最常见:占满剩余空间 */
.item {
flex: 1; /* 等价于:flex-grow: 1; flex-shrink: 1; flex-basis: 0%; */
}

/* 内容多大就多大,但也允许增长 */
.item-auto {
flex: auto; /* 1 1 auto */
}

/* 不长不缩,固定尺寸(常见于固定侧栏) */
.item-fixed {
flex: 0 0 240px;
}

面试提示:flex: 1 的关键是 flex-basis: 0%,这会让“按比例分配剩余空间”更直观。

2)order

改变视觉顺序,不改变 DOM 顺序。注意无障碍与 Tab 顺序(面试可顺带提“不要滥用”)。

3)align-self

覆盖容器的 align-items,只对某个子项生效。


四、典型题(高频布局题)与标准答法

1)左右布局:左固定,右自适应

<div class="wrap">
<aside class="left">left</aside>
<main class="right">right</main>
</div>
.wrap {
display: flex;
}
.left {
flex: 0 0 240px;
}
.right {
flex: 1;
min-width: 0; /* 重要:避免内容撑破导致无法收缩/溢出异常 */
}

2)水平垂直居中

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

3)等分布局(N 列等宽)

.cols {
display: flex;
}
.cols > li {
flex: 1;
min-width: 0;
}

常见追问(面试会顺带问)

Q1:为什么 flex 子项文字很长会把容器撑爆?

:因为 flex item 默认 min-width: auto,会以内容最小宽度作为下限,导致不能缩。解决通常是给可伸缩的 item 加 min-width: 0(竖排用 min-height: 0)。

Q2:justify-contentalign-items 经常混淆,怎么记?

:永远围绕“主轴/交叉轴”。主轴由 flex-direction 决定。


易错点/坑

  • 忘了 min-width: 0,导致 flex: 1 的区域无法收缩,出现横向溢出。
  • 把多行的交叉轴对齐写成 align-items:多行要用 align-content(前提是 flex-wrap: wrap)。
  • 过度依赖 order 改顺序:视觉顺序与可访问性交互顺序可能不一致。

速记要点(可背诵)

  • Flex 三件事:轴(direction)+ 对齐(justify/align)+ 伸缩(flex)。
  • flex: 1 常用:按比例吃掉剩余空间;可伸缩区域加 min-width: 0 防溢出。