contain: layout paint 必须组合使用,容器需有显式尺寸且设 position: relative,否则无效;单独使用 layout 或 paint、无显式尺寸、绝对定位子元素未约束均会导致失效。

contain: layout paint 必须一起用,单写任一个都白搭
只加 contain: paint,动画改 background-color 或 opacity 看似能缩重绘范围,但一旦内容尺寸变化(比如文字换行、图标加载完成、JS 插入 loading 圈),容器高度就会撑开,外部布局立刻重排;只加 contain: layout,则完全不限制重绘扩散——hover 时整个父区域还是跟着闪。
真正起效的组合是 contain: layout paint。它让浏览器把该容器当作一个独立渲染上下文:layout 锁死边界,paint 封住绘制污染。Chrome 120+ 已移除 contain: content,contain: strict 在 iOS Safari 上有 sticky 失效等已知问题,不推荐。
- ✅ 正确:
contain: layout paint - ❌ 废弃:
contain: content、contain: strict - ⚠️ 危险:
contain: layout或contain: paint单独使用
容器必须有显式尺寸,否则浏览器直接忽略
Chrome 和 Safari 对 contain: layout paint 的启用是有条件的:容器必须能被浏览器“预测尺寸”。写 height: auto、min-height: min-content、width: fit-content 或依赖 flex/gird 父容器“代为撑开”,都会导致声明静默失效——DevTools 里能看到 contain 值还在,但 Paint Flashing 依旧满屏闪。
- ✅ 推荐写法:
min-height: 48px; width: 120px、aspect-ratio: 16/9、height: 200px - ⚠️ 响应式慎用:
min-height: clamp(48px, 5vh, 120px)在部分浏览器缩放时可能被判定为不可预测 - ❌ 无效写法:
height: auto、flex: 1、display: flex父容器下直接设子项 contain
绝对定位元素会逃逸 containment 边界
很多动画区域含 position: absolute 子元素(如 tooltip、loading spinner、下拉菜单)。contain: paint 不会自动把定位上下文拉进容器——如果容器没设 position: relative,这些元素就以 为基准定位,直接突破边界,重绘污染全屏。
- ✅ 必须同步加:
position: relative到容器上 - ✅ 配合
overflow: clip可进一步裁剪意外溢出(比hidden更轻量) - ❌ 常见错误:容器无
position,但子元素写top: 50%; left: 50%,结果 spinner 漂到页面右上角
移动端和编辑器场景要特别小心兼容性与位置
iOS Safari 16.4+ 才稳定支持 paint,旧版本会静默忽略;Android Chrome 需开启 chrome://flags/#enable-experimental-web-platform-features。更隐蔽的问题是:在 contenteditable 根节点或富文本容器上硬加 contain: layout paint,会导致光标跳失、选区错乱、IME 输入框锚点偏移。
- ✅ 安全落地位置:工具栏、评论列表项、右下角浮窗、预览卡片等结构固定、非编辑区域
- ✅ 动态场景建议运行时检测:
if ('contain' in CSS.supports && CSS.supports('contain', 'layout paint')) - ❌ 禁止加在:
<div contenteditable> 本身,或未包裹 wrapper 的编辑器主内容区 实际生效的关键不在“写了没”,而在“尺寸稳不稳定”“定位上下文对不对”“浏览器认不认”。这三个点漏掉任何一个,<code>contain就只是 CSS 文件里一行安静的注释。











