纯CSS实现卡片展开动画:details与现代CSS技巧详解

用 details、::details-content、interpolate-size 等现代 CSS 特性,无需 JS 实现平滑分层卡片展开动画。
本文拆解了一套纯 CSS 实现的卡片展开动画方案。核心结构依赖 HTML 原生 `<details>`/`<summary>` 元素,利用浏览器内置的展开/收起交互,无需任何 JavaScript。高度动画通过 `::details-content` 伪元素配合 `block-size` 过渡实现,并借助 `transition-behavior: allow-discrete` 解决收起方向因 `content-visibility: hidden` 导致动画失效的问题。`interpolate-size: allow-keywords` 让 `auto` 高度可以参与 CSS 过渡,适合作为渐进增强使用。内部统计项的交错入场通过 `transition-delay` 与 CSS 自定义属性索引配合实现,`@starting-style` 则解决了元素首次进入渲染树时缺少动画起点的问题。整套方案展示了现代 CSS 在无脚本场景下的表达能力。
很多开发者在为网站添加交互动画时会第一反应想到 JavaScript 库,比如 GSAP。但有些精巧的信息展开效果,其实完全可以用纯 CSS 实现。本文基于一位前端 UP 主的实战演示,拆解如何用 <details> 元素配合现代 CSS 特性,打造一个平滑、分层入场的卡片展开动画。
用 details/summary 搭建可交互卡片
整个方案的基础是 HTML 原生的 <details> 与 <summary> 元素。作者把卡片图片与基本信息放进 <summary>,而额外的驾驶统计数据放在 <details> 的其余部分。这样做的好处是——点击展开/收起是浏览器免费提供的原生交互,无需任何脚本。
一个容易踩坑的细节是:<summary> 内部只允许放置 phrasing content(短语内容),不能随意塞 <div>。作者最初用 div 看似正常,但为了符合规范,最终改用 <span> 来包裹内容。而在 <summary> 之外的 <details> 区域,则可以自由使用 div 等流式内容(flow content)。
另一个实用技巧是给多个 <details> 设置相同的 name 属性,这样它们会形成互斥组——同一时间只能展开一个,类似手风琴效果。去掉 name 则可同时展开多个,具体取舍交给开发者按需求决定。

布局方面,作者在 <details> 上使用 display: flex 加 flex-direction: column,让 <summary> 通过 flex: 1 撑满空间;统计数据区域则用 display: grid 让各项横向排列。这些都是基础样式,重点在于为后续动画打好结构基础。
用 details-content 实现高度过渡
要让展开过程产生平滑的高度动画,需要选中 <summary> 以外的内容。这里有个坑:直接选 div 并不理想,因为 <details> 内部存在类似 Shadow DOM 的 web component 结构。现代 CSS 提供了 ::details-content 伪元素,可以精准选中非 summary 的全部内容。
具体做法是先把 ::details-content 的 block-size(即逻辑方向上的 height)设为 0,并加上 overflow: hidden,让内容被收起隐藏。当 <details> 处于 open 状态时,再把 block-size 设为 auto,就能恢复展开状态。
关键在于让这两种状态之间产生过渡。作者发现只写 transition: block-size 1s 时,动画只在一个方向生效——展开有动画,收起却瞬间消失。原因是 ::details-content 伪元素上带有 content-visibility: hidden 的内联样式,收起时内容会像 display: none 一样直接从渲染中移除,因此无法过渡。

解决办法是加上 transition-behavior: allow-discrete,它允许本来是离散(discrete)的属性参与过渡。配合把 content-visibility 一并写进 transition,收起动画就能延迟到过渡结束后再切换,两个方向都变得顺滑。
content-visibility 是一个 CSS 属性,用于控制元素的渲染可见性,其 hidden 值类似于 visibility: hidden 与 display: none 的混合体——元素从可访问性树中移除,浏览器跳过其渲染,从而节省性能。在 <details> 内部,浏览器会通过内联样式自动给 ::details-content 添加 content-visibility: hidden,收起时直接切断渲染管线,这属于"离散"(discrete)属性变化,即状态只能在两个离散值之间瞬间跳转,不存在中间插值状态。transition-behavior: allow-discrete 正是专为这类离散属性设计的——它告诉浏览器在过渡期间暂时维持可见状态,等 block-size 的过渡动画播放结束后,再切换 content-visibility 的离散状态,从而让收起动画得以完整呈现。
interpolate-size 让 auto 高度可动画
默认情况下,CSS 无法在数值高度与 auto 之间做过渡。为了让 block-size: auto 也能参与动画,作者在根元素上声明了 interpolate-size: allow-keywords。这个属性是 opt-in(需主动开启)的,一旦在 :root 或 html 上声明,就会继承到整个页面。
需要注意的是浏览器兼容性:本文涉及的大多数特性在各大浏览器引擎中都已支持,但 interpolate-size 目前仅限 Chromium。作者认为这完全可以作为渐进增强(progressive enhancement)来使用——支持的浏览器享受动画,不支持的也能正常展开收起。如果不想依赖它,也可以改用 CSS 的 @ 相关方案或其他库来兼容。

CSS 长期以来有一个根本性限制:height: auto 是一个关键字而非具体数值,浏览器无法在 0 与 auto 之间进行插值计算,因此直接过渡会瞬间跳变。历史上的解决方案包括用 max-height 设定一个足够大的估算值作为动画终点,或通过 JavaScript 先测量 scrollHeight 再赋给固定高度,这两种方式都有精度或性能上的取舍。interpolate-size: allow-keywords 是 CSS Values Level 5 规范引入的新机制,授权浏览器对 auto、min-content、max-content 等关键字尺寸进行动画插值。将其声明在 :root 上后全局生效,但因为可能影响页面上所有尺寸关键字的过渡行为,规范设计为需要开发者主动 opt-in,而非默认开启。
为统计项添加交错入场动画
整段内容一起滑入虽然够用,但作者更追求细节——让内部的统计项逐个错落入场,这种小润色能让网站从「还行」变成「有质感」。
实现思路是给每个统计项(value 与 label)初始设置 opacity: 0 和一个向下位移 translate: 0 40%,并为 translate 和 opacity 加上过渡。作者建议先把动画逻辑写好,最后再加 opacity,因为透明度是最容易验证的属性。
当卡片展开时,把 translate 设回 0 0、opacity 设为 1。为了产生交错效果,关键是 transition-delay,用 calc(var(--i) * 时间) 根据每个元素的索引递增延迟。索引可以通过内联 --i 变量传入(作者用 Astro 循环生成),未来也能用新的 sibling-index() / sibling-count() 自动获取,无需手动标注。

一个有趣的细节:位移用百分比而非固定像素时,由于不同元素尺寸不同,实际位移距离也不同,看起来像是有略微不同的速度,反而让交错更自然。
最后还有一个首次展开不触发动画的问题。因为这些元素在卡片收起时并不真正存在于 DOM 中,首次生成时没有「起始状态」可供过渡。解决方案是用 @starting-style 规则定义元素进入页面时的初始样式,这样第一次点击展开就能正确播放动画。
@starting-style 是 CSS 动画中较新引入的 at-rule,用于定义元素首次被插入渲染树或从 display: none 变为可见时的初始样式。在此之前,浏览器对新插入元素的过渡无法感知「从哪里开始」,因为元素在上一帧并不存在。@starting-style 填补了这一空缺:在规则块中声明的属性值作为过渡的起点,浏览器据此计算从初始状态到最终状态的补间动画。本文场景中,<details> 关闭时内部统计项并不真正保留在渲染树里,首次展开相当于元素第一次「出现」,没有 @starting-style 就缺少起始帧,动画自然无法触发。该特性目前在 Chromium 和 Firefox 的较新版本中均已获得支持,Safari 也已跟进。
小结
这套方案展示了现代 CSS 的强大:无需任何 JavaScript,仅靠 <details>、::details-content、transition-behavior: allow-discrete、interpolate-size 和 @starting-style 的组合,就能做出平滑且带交错入场的卡片展开效果。在 AI 辅助编码日益普及的今天,理解这些底层 CSS 机制依然重要——因为自动生成的代码一旦出问题,只有真正懂原理的人才能高效调试和优化。
相关推荐

离子推进器:赢得太空竞赛的慢速火箭
离子推进器以极低推力、极高效率成为太空深空探测与货运物流的关键技术。本文解析离子引擎的工作原理、氙气推进剂的选择、太阳能与核电推进的权衡,以及它为何可能成为建造星际文明的"慢速火箭"。

人类造过最快的东西:帕克太阳探测器的43万英里时速
人类建造过最快的物体不是旅行者号或火箭,而是NASA帕克太阳探测器,时速约43万英里。本文解析它如何借助金星引力辅助与太阳引力井加速,以及为何以光速衡量人类仍刚刚起步。

美光CEO警告:内存供应将在未来两年持续趋紧
美光CEO表示存储芯片供应将在未来两年比当前更为紧张,AI需求激增与产能扩张滞后是主因。本文分析内存供应趋紧的原因及其对市场和消费者的影响。