← 🧲 Flexbox · 简写语义与对齐边界 / 尺寸取值:width / height / min / max 的各种值 待审核 6 / 14
sizing · 尺寸取值

尺寸取值:width / height / min / max 的各种值

flex-basis 一页讲了 item 主轴尺寸如何确定、为何 flex-basis 覆盖 width。这页退一步,系统看 width / height / min-* / max-* 本身能接哪些取值:固定 <length>、相对 <percentage>、内容驱动的 min-content / max-content / fit-content()、以及较新的 stretch;再讲清百分比相对谁解析min/max 如何夹取最终尺寸。示例在 flex 容器里跑(item 设 flex: none,其主轴尺寸即 width),但取值规则对普通块同样适用。

1 · width 取值之旅(实测)

容器定宽 360px,里面一个 flex: none 的 item,文字含一个长单词。切换 width 取值,再叠加 min-width / max-width 看夹取效果。item 宽度为真实 getBoundingClientRect 实测

2 · 取值类型一览

取值 含义 备注
auto 由布局算法决定(初始值) 普通块的 width: auto 撑满可用宽;flex item 的主轴 autoflex-basis 流程。
<length> 固定长度,如 120px / 8rem box-sizing 影响(默认 content-box)。
<percentage> 相对包含块对应维度 width% ← 包含块宽;height% ← 包含块高(高度不确定时退化为 auto,见下)。
min-content 内容能压到的最小尺寸 横向 ≈ 最长不可断单词的宽度。
max-content 内容不换行时的理想尺寸 横向 ≈ 全部文字排一行的宽度。
fit-content 在可用空间内自适应,但不超 max-content = min(max-content, max(min-content, stretch))
fit-content(<LP>) 用给定值替代「可用空间」做夹取 = min(max-content, max(min-content, <LP>))
stretch 让 margin box 撑满包含块 较新关键字(旧前缀 -webkit-fill-available),支持有限,不支持时按 auto 表现。

百分比相对谁? width / min-width / max-width 的百分比相对包含块宽度;height 系列相对包含块高度。一个高频陷阱:margin / padding 的百分比无论横竖都相对包含块 inline 尺寸(通常是宽度)——所以 padding-top: 50% 是按宽度算的(常用于固定宽高比占位)。

3 · 百分比高度:为什么常常「不生效」

两个父盒都给子元素设 height: 50%。左父盒显式 height: 200px,右父盒高度 auto(由内容撑开)。子元素高度为实测值:左 = 父高一半,右 = 退化为 auto(按内容)。

规则: 当包含块的高度未显式确定(高度为 auto、取决于内容)时,子元素的百分比 height 计算为 auto——即不生效、回到按内容定高。宽度没有这个问题,因为块的宽度通常是确定的。绝对定位元素与 flex/grid 在部分情形下有各自的确定尺寸规则,不在此列。

4 · min / max 如何夹取

属性 默认值 作用
min-width / min-height auto 下界。普通块里 auto ≈ 0;flex item 的 min-width: auto 是「自动最小尺寸」≈ min-content——这正是 flex item 默认不会缩到内容以下的原因。
max-width / max-height none 上界(none = 不限)。

夹取顺序: 先取 width(或布局算出的尺寸),用 max 压上界、再用 min 顶下界——所以 min 的优先级高于 max:当 min-width > max-width 时,最终用 min-width。在 flex 里想让 item 真正缩到内容以下,需显式 min-width: 0(列向 min-height: 0),见 flex-basis 页。

5 · 物理尺寸 vs 逻辑尺寸:inline-size / block-size

上面的 width / height / min-* / max-* 都是物理属性(绑定屏幕的横、竖)。CSS Logical Properties 另给一组逻辑等价物,跟随 writing-mode / direction 翻转:inline-size 沿文字流方向block-size 沿块堆叠方向。取值空间与 width / height 完全一致。

下面的盒子固定 inline-size: 160px / block-size: 80px。切 writing-mode 看它如何在横排=宽、竖排=高之间翻转(实测 width / height)。

逻辑属性 横排 horizontal-tb 竖排 vertical-rl / lr
inline-size width height
block-size height width
min-inline-size / max-inline-size min-width / max-width min-height / max-height
min-block-size / max-block-size min-height / max-height min-width / max-width

与 flex 的关系: flex 的主轴 / 交叉轴本就是逻辑概念——flex-direction: row 的主轴即 inline 轴(随 writing-mode / direction 改向)、column 的主轴即 block 轴。因此 flex-basis 度量的正是主轴方向的 inline-size 或 block-size。用逻辑属性写 flex item 的尺寸,可天然跟随书写方向而无需改属性名,这也是 flex 布局对国际化(RTL / 竖排)友好的原因之一。

6 · 长度单位:与 layout 相关的几类

上面的 <length> 不止 px。布局里真正常用、且各有「相对谁」的单位分四类:字体相对视口相对容器相对,以及把它们组合起来的数学函数。选错参照系是响应式布局最常见的错误(例如该跟容器走却写了 vw)。

类别 单位 相对谁 layout 用途 / 备注
绝对 px CSS 像素 固定尺寸基线;不随字号 / 视口缩放。
字体相对 rem 根元素 font-size 全局可缩放的间距 / 尺寸基准,不受局部字号影响。
字体相对 em 本元素 font-size(用在 font-size 上则取父级) 随字号缩放;嵌套时会复合放大(见下)。
字体相对 ch 字形「0」的 advance 宽 近似字符宽,做可读行宽 max-width: 60ch
字体相对 lh 本元素 line-height 按行高对齐的间距(rlh = 根行高)。
视口相对 vw / vh 视口宽 / 高(vh = 大视口 lvh 全屏区块。vh 在手机上偏大,见下。
视口相对 vmin / vmax vwvh 的小 / 大者 随视口的方形元素 / 自适应留白。
视口相对 vi / vb 视口 inline / block 向 逻辑版视口单位,随 writing-mode
视口相对 svh / lvh / dvh 小 / 大 / 动态视口高 手机地址栏问题的解药(见下)。
容器相对 cqw / cqh 查询容器 宽 / 高的 1% 组件相对尺寸;需祖先设 container-type
容器相对 cqi / cqb 查询容器 inline / block 的 1% 逻辑版容器单位(常用 cqi)。
容器相对 cqmin / cqmax 容器 inline、block 的小 / 大者 无合格容器时回退到 small viewport(sv*)。
函数组合 clamp() / min() / max() 组合上述单位 流式尺寸:clamp(1rem, 2vw + 1rem, 3rem) 在上下界间随视口平滑变化。
(grid) fr grid 轨道剩余空间的份额 只能用于 grid-template-*,不能用于 width / flex-basis

7 · 容器单位 cqw:跟随容器,而非视口

外层设 container-type: inline-size 成为查询容器,内部 child 用 width: 50cqw / font-size: 7cqw。拖动改外层宽度——child 尺寸跟着这个容器缩放(实测约为容器 inline 尺寸的一半),与视口无关。这正是组件级响应式的基础:同一个组件放进窄侧栏或宽主区,靠 cqw / cqi 自适应,而不必依赖 vw 或断点。

手机上的 100vh 问题。 vh 等于大视口lvh,地址栏收起时的高度),所以地址栏显示时 height: 100vh比可见区域更高、底部被切走。解药:svh(小视口,始终可见的最小高度)、dvh(动态,随地址栏伸缩实时变化)。全屏区块常用 min-height: 100svh100dvh 替代 100vhdvh 会在滚动时重算,注意性能)。

两个易错点。 其一,em 复合:父子都用 em 时逐层相乘——父 font-size: 1.5em、子再 1.5em,子的实际是祖父的 2.25 倍;要稳定基准用 rem。其二,fr 是 grid 轨道单位,不是 <length>,不能写进 widthflex-basis;flex 里「按比例分配」用 flex-grow(见 flex 简写)。