grow 分配的是剩余空间,不是总宽度。所以两个 grow:1 的项如果内容宽度不同,最终宽度也不相等。
/* basis 优先级高于 width(主轴方向上)。flex-basis: auto + width: 200px ≡ flex-basis: 200px */
/* 想「固定 200px 但可伸缩」:.item { flex: 0 1 200px } 或写 width:200px; flex-shrink:1 */
收缩量按 shrink × basis 加权,不是按 shrink 数字直接分。给不想被压的项写 flex-shrink: 0(图标、关闭按钮、固定侧栏)。
| 写法 | 展开 | 意图 |
|---|---|---|
flex: 1 | 1 1 0% | 均分整行,忽略内容宽度 → 等宽列 |
flex: 1 1 auto(= flex: auto) | 1 1 auto | 按内容比例分配剩余,能长能缩 |
flex: none | 0 0 auto | 完全固定,不看不给 |
flex: initial | 0 1 auto | 默认值:不生长,但会被压缩 |
flex: 0 0 240px | — | 固定 240px 侧栏(等价 flex-basis:240px; flex-shrink:0) |
写 flex: 1 时浏览器给的 basis 是 0%,不是 auto —— 这就是它能「严格等宽」的原因。
.tags { display: flex; flex-wrap: wrap; gap: 8px; }
/* 不加 nowrap 之外的宽度限制,窄屏会自动堆成多行;换行的行间距同样由 gap 管 */
用途:移动端把主内容提到前面(DOM 顺序按语义写,视觉顺序用 order 调)。风险与 row-reverse 相同:视觉顺序与 Tab 焦点顺序不一致会让键盘用户迷路 —— 能用 DOM 顺序解决就别用 order。
Flex 子项的自动最小尺寸是 min-content,所以下面第一条会溢出,加上 min-width: 0 后省略号才生效。
.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 吃掉中间空白。align-items: stretch,所以两张卡片高度自动相等 —— 这是 Flex 做「等高卡片」比 float 简单得多的地方。再配合内部 margin-top:auto 或 flex:1 把页脚推到底。body { min-height: 100svh; display: flex; flex-direction: column; }
main { flex: 1; } /* 内容不足一屏时,footer 仍被顶到视口底部 */