safe / unsafe:给对齐加一句「别切到内容」
居中即截断一页的问题,本质是浏览器为了「居中」而牺牲了可访问性(把内容推到滚不到的位置)。CSS Box Alignment 模块早已为对齐关键字预留了一个修饰位 <overflow-position>——safe 与
unsafe,正是用来回答「当对齐会导致内容溢出丢失时该如何处理」。iCSS #249 的简洁解即在于此。
三种写法,三种处理方式:
· justify-content: center——不加修饰。溢出时仍然居中,左侧被切、滚不到(内容丢失)。
· justify-content: unsafe center——显式声明「即使切到内容也保持居中」。效果与不加修饰一致,但意图明确。
· justify-content: safe center——「优先居中,但若会溢出丢失则退回 start」,兼顾对齐与可访问性。
1 · 同一条轨道,三种关键字实测
切换关键字,加 item 到溢出,点「滚到最左」。safe center 在溢出时会自动表现得像 flex-start(内容从左开始、完整可滚);不溢出时仍居中。unsafe center / 裸 center 则始终居中、左侧被切。底部读数是真实 getBoundingClientRect 实测,旁边还回显 getComputedStyle 拿到的实际值。
2 · 能用在哪些对齐上?
<overflow-position> 是 Box Alignment 的通用修饰,凡是会把内容推到产生溢出的对齐属性都能加:
| 属性 | 作用轴 | 典型 safe 写法 | 挡住什么溢出 |
|---|---|---|---|
justify-content |
主轴(整体) | safe center |
横向条左侧被切、滚不到(本系列主线) |
align-items / align-self |
交叉轴(单项) | safe center |
item 比行高时,垂直居中会切到上边、滚不到 |
align-content |
交叉轴(多行) | safe center |
多行总高超容器时,整体垂直居中切到顶部 |
justify-self(grid) |
主轴(单格) | safe center |
grid 单元格里子项过宽被切 |
一处反直觉的行为:space-* 三个值的 fallback 并不相同。 只有一个 alignment subject 或空间不足以按该模式分配时,space-between 退回 safe flex-start,而 space-around 与 space-evenly 退回
safe center——因此在横向可滚的条上,后两者比 space-between 更容易把首项推到不可滚的一侧。另有一处规范修订值得知道:csswg-drafts #11937 指出 fallback 里的 safe 在 row-reverse 且自身是
scrollport 的容器上反而不安全,CSSWG 已决议把 safe 从该 fallback 中去掉。稳妥做法:横向可滚动的条显式写 safe,或直接用 flex-start。
3 · 兼容性
flex 上下文里的 safe / unsafe 落地时间差异很大:Firefox 63、Chrome 115、Safari 17.6(BCD 8.0.11,核对于 2026-08)。Chrome 在 115 之前的处境最值得留意——那些版本能解析该值但不生效,于是 CSS.supports('justify-content', 'safe center') 返回
true,实际表现却等同裸 center,照样截断。页面顶部横幅用的正是这个探测,在那段版本区间会给出假阳性。若浏览器彻底不识别,整条声明被丢弃、回退到默认 flex-start,那一侧恰好是安全的。