details标签原生仅支持垂直展开,水平展开需用CSS模拟:通过details[open]控制内部.content的max-width过渡,并设overflow:hidden实现视觉伸缩,避免直接对details或summary设过渡。

details 默认不支持水平展开,必须用 CSS 模拟
details 标签原生只支持垂直方向的展开/收起(即内容在 summary 下方动态显示或隐藏),浏览器没有提供 flex-direction: row 或横向高度过渡的内置逻辑。所谓“水平展开”,本质是把内容容器设为 display: flex,再用 max-width + overflow: hidden 配合 transition 实现视觉上的横向伸缩。
用 max-width 过渡模拟水平展开的实操要点
核心思路:不依赖 details[open] 控制 height,而是控制内部包装容器的 max-width,并让其父级 overflow: hidden 裁剪溢出部分。
-
details本身设为display: flex; align-items: center;,避免默认块级流干扰布局 -
summary设为固定宽度或flex-shrink: 0,防止被压缩 - 用一个
<div class="content">包住要水平展开的内容,并设置:details[open] .content { max-width: 300px; transition: max-width 0.3s ease-in-out; }<br>.content { max-width: 0; overflow: hidden; white-space: nowrap; } - 注意:不能对
details或summary直接设max-width过渡——它们不是内容容器,状态变化不会触发重排
为什么 details[open] > *:not(summary) 不适用于水平展开
垂直展开常用 details[open] > *:not(summary) 配合 max-height 过渡,但该技巧在水平场景下失效,原因很实在:
-
max-height对行内元素或flex子项无效,尤其当内容是文字、图标、按钮等非块级流时,高度不随内容宽度变化 -
details的子元素默认是文档流顺序排列,> *选择器无法精准捕获“横向内容区”,容易误选summary后面的空白文本节点 - 某些 Safari 版本对
max-width过渡的支持不稳定,需加will-change: max-width提前提示渲染引擎
移动端和 WebView 中的横向展开要格外小心
微信、QQ、钉钉等 App 内嵌 WebView 对 details 的支持集中在垂直行为上,很多版本会忽略 [open] 状态下的自定义 max-width 动画,表现为“突然弹出”或“完全不动”。
立即学习“前端免费学习笔记(深入)”;
- 真机测试必须覆盖 iOS 微信(尤其是 8.0.5x 及以下)、安卓 QQ 浏览器(X5 内核 v4.3.x)
- 若发现动画卡顿或失效,可降级为
transform: translateX()方案:初始transform: translateX(-100%),展开时设为translateX(0),配合transition: transform - 别忘了给
summary加user-select: none,防止长按触发文字选择遮盖点击热区
横向展开不是 details 的设计目标,它只是借了语义和 toggle 事件;真正稳定可控的方案,往往得在 details[open] 触发后,用 JS 补一帧 class 切换,绕过浏览器对伪类过渡的限制。这个细节,上线前很容易漏测。



















