子项的三个自由度:grow(分剩余)、shrink(扛挤压)、basis(起点)

flex-grow:剩余空间按份数分

grow:1
grow:2(拿两份剩余)
不设(保持内容宽)

grow 分配的是剩余空间,不是总宽度。所以两个 grow:1 的项如果内容宽度不同,最终宽度也不相等。

flex-basis:从哪个尺寸出发

basis:auto(用 width/内容)
basis:120px
basis:40%
/* basis 优先级高于 width(主轴方向上)。flex-basis: auto + width: 200px ≡ flex-basis: 200px */
/* 想「固定 200px 但可伸缩」:.item { flex: 0 1 200px } 或写 width:200px; flex-shrink:1 */

flex-shrink:容器不够宽时谁让步

shrink:0 图标/按钮:绝不压缩
shrink:1 默认值,宽度会被压到内容以下直到 min-content

收缩量按 shrink × basis 加权,不是按 shrink 数字直接分。给不想被压的项写 flex-shrink: 0(图标、关闭按钮、固定侧栏)。

flex 简写:三种常见意图

写法展开意图
flex: 11 1 0%均分整行,忽略内容宽度 → 等宽列
flex: 1 1 auto(= flex: auto)1 1 auto按内容比例分配剩余,能长能缩
flex: none0 0 auto完全固定,不看不给
flex: initial0 1 auto默认值:不生长,但会被压缩
flex: 0 0 240px—固定 240px 侧栏(等价 flex-basis:240px; flex-shrink:0)

写 flex: 1 时浏览器给的 basis 是 0%,不是 auto —— 这就是它能「严格等宽」的原因。

flex-wrap + flex-basis:响应式标签云

HTMLCSSFlexboxGrid自定义属性容器查询层叠BEM媒体查询渐变
.tags { display: flex; flex-wrap: wrap; gap: 8px; }
/* 不加 nowrap 之外的宽度限制,窄屏会自动堆成多行;换行的行间距同样由 gap 管 */

order:只改视觉顺序

DOM 第 1
order:99 → 排到最后
order:-1 → 排到最前

用途:移动端把主内容提到前面(DOM 顺序按语义写,视觉顺序用 order 调)。风险与 row-reverse 相同:视觉顺序与 Tab 焦点顺序不一致会让键盘用户迷路 —— 能用 DOM 顺序解决就别用 order。

最经典的坑:文字把容器撑爆(min-width 不是 0)

Flex 子项的自动最小尺寸是 min-content,所以下面第一条会溢出,加上 min-width: 0 后省略号才生效。

固定侧栏
这一行文字非常长足够溢出容器但省略号不会生效因为flex子项的min-width默认是min-content
固定侧栏
这一行文字非常长足够溢出容器但省略号不会生效因为flex子项的min-width默认是min-content
.child { min-width: 0; }   /* 允许收缩到内容以下:嵌套 flex、text-overflow、overflow 容器都要配它 */
/* 纵向 flex(column)里对应的问题是 min-height: 0,否则子项撑破滚动容器 */

实战配方一:等宽 + 间距 + 窄屏换行

.cols { display: flex; flex-wrap: wrap; gap: 16px; }
.cols > * { flex: 1 1 240px; }   /* 期望 240px:宽屏均分,不足则整体换行 */

实战配方二:等高卡片 + 底部对齐的按钮

短卡片
内容较少,正文区用 flex:1 吃掉中间空白。
底部永远贴齐 ↓
长内容卡片
Flex 的子项默认 align-items: stretch,所以两张卡片高度自动相等 —— 这是 Flex 做「等高卡片」比 float 简单得多的地方。再配合内部 margin-top:auto 或 flex:1 把页脚推到底。
底部对齐

实战配方三:吸底页脚(sticky footer)

body { min-height: 100svh; display: flex; flex-direction: column; }
main { flex: 1; }   /* 内容不足一屏时,footer 仍被顶到视口底部 */