CSS 中 box-sizing 属性为何无法通过 DETAILS 元素继承?

css 中 box-sizing 属性为何无法通过 details 元素继承?details 元素内部使用 shadow dom 插槽渲染内容,导致子元素继承的是插槽节点的样式(`display: block; content-visibility: hidden`),而非 details 自身的 css 样式;因此 `* { box-sizing: inherit }` 无法作用于其内部子元素,默认回退为 `content-box`。

DETAILS 元素在现代浏览器中(Chrome、Firefox 等)采用 Shadow DOM 实现其折叠/展开行为。根据 HTML 规范,

渲染时会生成一个内部 shadow tree,其中包含两个 slot:一个用于 ,另一个用于其余子内容(即
的“主体”部分)。关键在于——这个主体 slot 节点被规范强制赋予内联样式:

/* 浏览器内部等效样式(不可直接覆盖) */
slot[role="presentation"] {
  display: block;
  content-visibility: hidden; /* closed 状态下隐藏 */
  /* 注意:此处未设置 box-sizing,因此取初始值 content-box */
}

由于该 slot 是 shadow host(

)与 light DOM 子元素之间的样式继承中介,而你的全局重置规则:

*, *::after, *::before { box-sizing: inherit; }
html { box-sizing: border-box; }

无法匹配 shadow slot 节点(它既不是 light DOM 中的 *,也不是 ::before/::after 伪元素),因此 slot 节点的 box-sizing 值保持为 CSS 初始值 content-box。所有嵌套在其内的子元素(如

Box sizing inside Details?)将从该 slot 继承 box-sizing: content-box,而非从
或 html 继承 border-box。

✅ 正确修复方案:显式为 DETAILS 内部子元素设置 box-sizing

/* 方案 1:针对 details 内部所有块级子元素(推荐) */
details > * {
  box-sizing: border-box;
}

/* 方案 2:更精确地匹配主体内容(含 summary 后的任意子节点) */
details > :not(summary) {
  box-sizing: border-box;
}

/* 方案 3:若需全局兼容,可扩展选择器范围(谨慎使用) */
details *, details *::before, details *::after {
  box-sizing: inherit;
}

⚠️ 注意事项:

  • 不要依赖 * { box-sizing: inherit } 跨 Shadow DOM 边界生效——这是设计使然,非 bug;
  • content-visibility: hidden 是实现折叠的关键,但不影响盒模型计算,仅控制渲染可见性;
  • 若使用自定义
    封装组件(如 Web Component),可通过 :host 或 ::slotted() 显式控制 slot 内样式;
  • 在 CSS 重置库(如 modern-normalize)中,该问题已普遍被识别,主流方案均采用 details > * 显式声明。

总结:这不是浏览器兼容性问题,而是 Shadow DOM 继承机制的必然结果。理解 slot 作为样式继承链中的“中间节点”,是解决此类问题的核心。始终对 details 的直系子元素做显式 box-sizing 声明,即可确保布局行为一致可靠。