You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在@keyframes动画特定百分比阶段显示/添加内容元素?

下拉菜单子元素随父容器动画分步显示方案

先解决容器高度不全的问题

height:100%无法包裹所有子元素的核心原因是它依赖父元素的高度继承,而非自身内容高度。可以这么处理:

  • 改用height: fit-content让容器自动适配子元素总高度,适合不需要固定高度的场景;
  • 如果必须用从0展开的动画,先通过JS获取容器的真实内容高度(scrollHeight属性),再把动画的目标高度设为这个具体数值,而非百分比,避免高度不足。

子元素分步显示的模块化实现

方案1:纯CSS + CSS变量(无JS依赖,推荐)

通过CSS变量动态计算子元素的动画延迟,后续新增子元素无需手动调整:

  1. 给父容器定义核心变量:
.content {
  --item-count: 3; /* 子元素数量,后续由JS自动更新 */
  --animation-duration: 1s; /* 父容器展开总时长 */
  height: 0;
  overflow: hidden;
  animation: expand var(--animation-duration) forwards;
}

@keyframes expand {
  to {
    height: fit-content; /* 或用JS获取的具体高度值 */
  }
}
  1. 子元素的显示动画规则:
.content > * {
  opacity: 0;
  transform: translateY(10px);
  animation: fadeIn 0.3s forwards;
  /* 按子元素索引均分总动画时长,计算延迟 */
  animation-delay: calc(var(--animation-duration) / var(--item-count) * (var(--index) - 1));
}

@keyframes fadeIn {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
  1. 用JS自动更新变量(新增子元素后自动生效):
const content = document.querySelector('.content');
const items = content.children;
// 设置子元素数量变量
content.style.setProperty('--item-count', items.length);
// 给每个子元素设置索引变量
Array.from(items).forEach((item, idx) => {
  item.style.setProperty('--index', idx + 1);
});

方案2:JS监听动画进度(更灵活)

通过requestAnimationFrame跟踪父容器的动画进度,精准控制子元素显示时机:

const content = document.querySelector('.content');
const items = content.children;
const totalDuration = 1000; // 对应父容器动画的总时长(毫秒)
let startTime;

// 跟踪动画进度
function trackAnimationProgress(timestamp) {
  if (!startTime) startTime = timestamp;
  const progress = Math.min((timestamp - startTime) / totalDuration, 1);
  const step = 1 / items.length;

  // 根据进度显示对应子元素
  Array.from(items).forEach((item, idx) => {
    if (progress >= step * idx) {
      item.style.opacity = 1;
      item.style.transform = 'translateY(0)';
    }
  });

  if (progress < 1) {
    requestAnimationFrame(trackAnimationProgress);
  }
}

// 父动画开始时初始化
content.addEventListener('animationstart', () => {
  startTime = null;
  // 先隐藏所有子元素
  Array.from(items).forEach(item => {
    item.style.opacity = 0;
    item.style.transform = 'translateY(10px)';
  });
  requestAnimationFrame(trackAnimationProgress);
});

额外优化提示

  • 如果浏览器不支持height: fit-content的动画,用JS获取content.scrollHeight并赋值给CSS变量--target-height,再把@keyframes expand的目标高度设为var(--target-height);
  • 子元素的显示动画可以调整transform的参数(如位移距离),让过渡效果更贴合需求。

内容的提问来源于stack exchange,提问作者ThisQRequiresASpecialist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 21:04:55