CSS max-height过渡在JavaScript切换类时动画异常问题咨询
问题原因
- 你设置的
.open类max-height值过大(100000px),过渡是在100000px和默认的30px之间做插值计算:收起时前99%的过渡时长里,max-height都高于你实际的内容高度,容器高度始终跟随内容高度展示,视觉上没有变化;只有当max-height降低到低于实际内容高度时才会发生可见变化,此时剩余过渡时长极短,看起来就是瞬间闭合。 - 额外问题:你默认给
.project设置的max-height:30px比子元素.project-head的height:50px小,默认状态下头部内容会被截断。
修复方案
方案1:固定合适的max-height(简单,适用于内容高度固定的场景)
把.open的max-height调整为仅略大于你的菜单最大实际高度即可,同时修复默认max-height的截断问题,优化选择器优先级避免用!important:
section.project { /* 改成和头部高度一致,避免默认截断 */ max-height: 50px; overflow: hidden; transition: all 0.5s ease-in-out; } .project-head { display: grid; height: 50px; width: 95vw; } /* 选择器优先级更高,不需要!important */ section.project.open { /* 假设你的菜单展开后最高不超过300px,就设300px,按需调整 */ max-height: 300px; }
方案2:动态计算高度(通用,适用于内容高度不固定的场景)
通过JS动态获取内容实际高度来设置过渡的起止值,不需要固定max-height的数值:
修改后的JS代码:
document.querySelectorAll('.project').forEach(project => { // 初始化默认高度 project.style.maxHeight = '50px'; project.querySelector('.project-head').addEventListener('click', function () { const parent = this.parentElement; if(parent.classList.contains('open')){ // 收起逻辑:先把max-height从auto改成当前实际高度,再下一帧改成收起高度 parent.style.maxHeight = parent.scrollHeight + 'px'; // 等待浏览器渲染完成 requestAnimationFrame(() => { parent.style.maxHeight = '50px'; parent.classList.remove('open'); }) }else{ // 展开逻辑:设为实际内容高度,过渡完成后改成auto避免后续内容变化被截断 parent.style.maxHeight = parent.scrollHeight + 'px'; parent.classList.add('open'); // 过渡结束后重置为auto,时长和CSS过渡时长保持一致 setTimeout(() => { if(parent.classList.contains('open')) parent.style.maxHeight = 'unset'; }, 500) } }); })
对应的CSS可以去掉.open的max-height配置:
section.project { max-height: 50px; overflow: hidden; transition: all 0.5s ease-in-out; } .project-head { display: grid; height: 50px; width: 95vw; }
内容的提问来源于stack exchange,提问作者Labradoodle
相关产品推荐
相关产品推荐

