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-between 的 fallback 并不退回 start。 规范规定 space-* 系列在只有一个 item 或会溢出时,fallback 到 safe center 而非 start——于是
justify-content: space-between 在内容溢出时,反而可能把首项推到左侧而被切掉。CSSWG 也认为这是一处设计缺陷(csswg-drafts #11937)。稳妥做法:横向可滚动的条不要依赖 space-between 的 fallback,显式写
safe 或改用 flex-start。
3 · 兼容性
safe / unsafe 关键字在三大引擎都已落地多年(Chrome 84+ / Firefox 63+ / Safari 11+,caniuse 上 flex 上下文的支持已是绿区)。页面顶部横幅是本浏览器的实测(CSS.supports('justify-content', 'safe center'))。真要照顾远古浏览器,safe center 不被识别时整条声明被丢弃、回退到默认 flex-start——恰好就是安全的那一侧,所以即便不支持也不会更糟。