核心思路是利用 max-height 结合 opacity 和 transform 实现流畅折叠展开动画,避免直接动画 height 引发重排。通过设置足够大的 max-height 值、配合 overflow: hidden 与关键帧动画,在无需精确计算高度的前提下实现性能友好的视觉效果。使用 opacity 实现淡入淡出,transform 应用 scaleY 或 translateY 增强动态感,由 GPU 加速提升流畅度。为优化动态内容场景,可结合 will-change 提示、合理缓动函数与动画时长,并在必要时通过 JavaScript 获取 scrollHeight 实现精准 height 过渡,或仅对列表项单独执行 opacity 和 transform 动画以规避容器尺寸变化带来的性能问题。

CSS
animation
max-height
opacity
transform
@keyframes
transition
height
要用 CSS
animation
height
max-height
opacity
transform
具体来说,当列表需要折叠时,我们将
max-height
0
opacity
1
0
0
1
transform: scaleY()
translateY()
transform
以下是一个基础的 CSS
animation
立即学习“前端免费学习笔记(深入)”;
/* 列表容器 */
.list-container {
overflow: hidden;
max-height: 1000px; /* 足够大的值,确保能容纳所有内容 */
opacity: 1;
transform-origin: top; /* 确保缩放从顶部开始 */
animation-fill-mode: forwards; /* 动画结束后保持最终状态 */
will-change: max-height, opacity, transform; /* 性能优化提示 */
}
/* 展开动画 */
.list-container.is-expanded {
animation: expandList 0.4s ease-out forwards;
}
@keyframes expandList {
0% {
max-height: 0;
opacity: 0;
transform: scaleY(0.8) translateY(-10px);
}
100% {
max-height: 1000px; /* 或根据实际内容估算一个更大的值 */
opacity: 1;
transform: scaleY(1) translateY(0);
}
}
/* 折叠动画 */
.list-container.is-collapsed {
animation: collapseList 0.4s ease-in forwards;
}
@keyframes collapseList {
0% {
max-height: 1000px;
opacity: 1;
transform: scaleY(1) translateY(0);
}
100% {
max-height: 0;
opacity: 0;
transform: scaleY(0.8) translateY(-10px);
}
}
/* 确保初始状态 */
.list-container.hidden-by-default {
max-height: 0;
opacity: 0;
transform: scaleY(0.8) translateY(-10px);
}通过 JavaScript 切换
.is-expanded
.is-collapsed
max-height
height
在实现列表折叠展开动画时,
max-height
height
max-height
height
height
0
scrollHeight
height
scrollHeight
height
相比之下,
max-height
max-height
1000px
9999px
0
0
overflow: hidden
max-height
height
max-height
然而,
max-height
max-height
50px
max-height
0
1000px
0.4s
为了避免动画卡顿,无论选择
height
max-height
overflow: hidden
max-height
opacity
transform
scaleY
translateY
max-height
opacity
transform
will-change
will-change: max-height, opacity, transform;
200ms
400ms
ease-in
ease-out
ease-in-out
总的来说,对于大多数动态列表折叠场景,
max-height
overflow: hidden
opacity
transform
height
opacity
transform
仅仅动画
max-height
opacity
transform
我个人在做这类动画时,几乎都会同时考虑这三个属性的组合。
1. opacity
opacity
max-height
max-height
opacity
expandList
opacity
0
1
max-height
collapseList
opacity
1
0
max-height
2. transform
transform
scaleY
translateY
transform
transform: scaleY()
scaleY
0.8
0
1
transform-origin: top;
bottom
scaleY(0.8)
scaleY(1)
scaleY
1
0.8
0
scaleY
scaleY
transform: translateY()
translateY
10px
-10px
0
translateY(-10px)
translateY(0)
translateY
0
10px
-10px
组合示例:
在解决方案部分给出的
keyframes
@keyframes expandList {
0% {
max-height: 0;
opacity: 0;
transform: scaleY(0.8) translateY(-10px); /* 略微压缩并向上偏移 */
}
100% {
max-height: 1000px;
opacity: 1;
transform: scaleY(1) translateY(0); /* 完全展开并回到原位 */
}
}
@keyframes collapseList {
0% {
max-height: 1000px;
opacity: 1;
transform: scaleY(1) translateY(0);
}
100% {
max-height: 0;
opacity: 0;
transform: scaleY(0.8) translateY(-10px); /* 略微压缩并向上偏移 */
}
}这里,
max-height
opacity
transform: scaleY(0.8) translateY(-10px)
实际项目中,动态内容和不确定数量的列表项是常态,这确实给 CSS 动画带来了一些挑战。纯 CSS
max-height
1. max-height
前面提到,
max-height
max-height
N
X
max-height
N * X + padding
max-height
opacity
transform
2. JavaScript 辅助获取精确高度(“混合式”方案):
这是解决动态内容高度不确定性最有效的方法,虽然牺牲了一部分纯 CSS 的优雅,但能带来最精确的动画效果。
基本思路:
height: 0; overflow: hidden;
height
auto
scrollHeight
height
0
offsetHeight
height: 0
height
scrollHeight
transition
height
auto
scrollHeight
height
transition
height: 0
代码示例(简化版):
function toggleList(element) {
if (element.style.height && element.style.height !== '0px') {
// 正在展开或已展开,准备折叠
element.style.height = element.scrollHeight + 'px'; // 确保从当前高度开始折叠
requestAnimationFrame(() => {
element.style.height = '0';
});
} else {
// 正在折叠或已折叠,准备展开
element.style.height = 'auto'; // 临时设置为auto获取实际高度
const scrollHeight = element.scrollHeight;
element.style.height = '0'; // 立即设回0
requestAnimationFrame(() => { // 确保浏览器已经渲染了height:0
element.style.height = scrollHeight + 'px';
});
}
// 动画结束后移除height属性,让其自适应
element.addEventListener('transitionend', () => {
if (element.style.height !== '0px') {
element.style.height = 'auto';
}
}, { once: true });
}
// CSS
// .list-container {
// overflow: hidden;
// transition: height 0.4s ease-in-out;
// }
// .list-container[style="height: 0px;"] {
// height: 0;
// }这种方案虽然需要 JavaScript 介入,但它能提供最精确、最流畅的动画,尤其适合内容高度差异大且不可预测的场景。
3. 仅动画列表项,而非容器高度:
对于列表项数量不确定,但每个列表项高度相对固定的情况,可以考虑不动画列表容器的
height
max-height
opacity
transform
以上就是如何用css animation优化列表折叠展开动画的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号