如何为HTML details标签添加关闭时的动画效果
问题根因
<details> 标签的原生交互逻辑为:当用户触发关闭操作时,浏览器会立即移除 open 属性并直接隐藏内部内容,没有为动画预留执行时间,因此直接编写的关闭动画会因为内容提前被隐藏而无法正常触发。
实现方案
方案1:少量JS配合CSS(兼容性最好,可兼容所有主流浏览器)
首先更新CSS代码,新增关闭动画定义:
/* 原有开启动画 */ @keyframes open { 0% { opacity: 0; transform: translateY(-1vw); } 100% { opacity: 1; transform: translateY(0); } } /* 新增关闭动画 */ @keyframes close { 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-1vw); } } details[open] summary ~ * { animation: open .5s cubic-bezier(0.785, 0.135, 0.15, 0.86) forwards; } /* 关闭过程中添加的动画类 */ details.closing summary ~ * { animation: close .5s cubic-bezier(0.785, 0.135, 0.15, 0.86) forwards; }
添加JS逻辑,拦截点击事件控制动画执行时机:
document.querySelectorAll('details').forEach(detail => { const summary = detail.querySelector('summary'); summary.addEventListener('click', e => { // 仅处理开启状态下的关闭操作 if (detail.hasAttribute('open')) { e.preventDefault(); detail.classList.add('closing'); // 动画执行完成后再移除open属性 setTimeout(() => { detail.removeAttribute('open'); detail.classList.remove('closing'); }, 500); // 时长和CSS动画保持一致即可 } }) })
原有HTML代码无需做任何修改。
方案2:纯CSS实现(仅支持现代浏览器)
如果不需要兼容旧版本浏览器,可以直接用@starting-style配合transition实现,要求Chrome 117+、Firefox 127+版本支持:
details summary ~ * { transition: all .5s cubic-bezier(0.785, 0.135, 0.15, 0.86); opacity: 0; transform: translateY(-1vw); } details[open] summary ~ * { opacity: 1; transform: translateY(0); } /* 定义开启时的初始状态,避免开启动画失效 */ @starting-style { details[open] summary ~ * { opacity: 0; transform: translateY(-1vw); } }
内容的提问来源于stack exchange,提问作者JustADeveloper
相关产品推荐
相关产品推荐

