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

如何通过纯CSS实现移除下方div后上方div的平滑滑动过渡动画?

纯CSS实现上方div平滑下落的解决方案

首先得说,直接移除DOM元素是没法触发过渡动画的——浏览器会瞬间重新布局,上方div自然就“跳”下去了。咱们得换个思路:不删除下方div,而是用CSS让它平滑隐藏,同时给上方div加过渡,让它跟着布局变化慢慢移动。

下面给你两种场景的实现方案,都是纯CSS(最多加几行JS触发类切换,不用插件):

场景1:正常文档流布局(上下排列)

这种情况最常见,上方和下方div在正常流里垂直排列。咱们让下方div平滑收缩消失,上方div会因为布局变化自然平滑下落。

HTML结构

<div class="container">
  <div class="top-card">我是上方的卡片</div>
  <div class="bottom-card">我是带滑动动画的下方卡片</div>
  <button class="toggle-btn">切换下方卡片</button>
</div>

CSS代码

.container {
  width: 320px;
  margin: 30px auto;
}

.top-card {
  padding: 24px;
  background: #4CAF50;
  color: white;
  border-radius: 8px;
  /* 关键:给上方卡片的所有可过渡属性加动画 */
  transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
  margin-bottom: 16px;
}

.bottom-card {
  padding: 24px;
  background: #2196F3;
  color: white;
  border-radius: 8px;
  /* 下方卡片的平滑隐藏动画 */
  max-height: 120px; /* 设一个比实际内容高的最大值 */
  overflow: hidden;
  transition: max-height 0.5s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.5s ease, padding 0.5s ease;
  opacity: 1;
}

/* 隐藏下方卡片的类 */
.bottom-card.hidden {
  max-height: 0;
  opacity: 0;
  padding: 0 24px; /* 保留左右padding,避免宽度跳动 */
  margin-top: 0;
  margin-bottom: 0;
}

.toggle-btn {
  margin-top: 16px;
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background: #f44336;
  color: white;
  cursor: pointer;
}

触发逻辑(几行JS)

const toggleBtn = document.querySelector('.toggle-btn');
const bottomCard = document.querySelector('.bottom-card');

toggleBtn.addEventListener('click', () => {
  bottomCard.classList.toggle('hidden');
});

场景2:定位布局(上方div覆盖在下方div上)

如果你的布局是上方div在下方div的上方(比如绝对定位),可以用:has()选择器纯CSS触发上方div的滑动动画(现代浏览器都支持has())。

HTML结构

<div class="positioned-container">
  <div class="top-positioned">我是上方的定位元素</div>
  <div class="bottom-positioned">我是下方的定位元素</div>
  <button class="pos-toggle-btn">切换下方元素</button>
</div>

CSS代码

.positioned-container {
  position: relative;
  width: 320px;
  height: 200px;
  margin: 30px auto;
  border: 1px solid #eee;
  border-radius: 8px;
}

.top-positioned {
  position: absolute;
  top: 16px;
  left: 16px;
  right: 16px;
  padding: 20px;
  background: #ff9800;
  color: white;
  border-radius: 8px;
  /* 给定位属性加过渡 */
  transition: top 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}

.bottom-positioned {
  position: absolute;
  top: 100px;
  left: 16px;
  right: 16px;
  padding: 20px;
  background: #9c27b0;
  color: white;
  border-radius: 8px;
  max-height: 80px;
  overflow: hidden;
  transition: max-height 0.5s ease, opacity 0.5s ease;
}

.bottom-positioned.hidden {
  max-height: 0;
  opacity: 0;
  padding: 0 20px;
}

/* 纯CSS触发上方元素滑动:当下方元素有hidden类时,移动上方元素 */
.positioned-container:has(.bottom-positioned.hidden) .top-positioned {
  top: 100px;
}

.pos-toggle-btn {
  position: absolute;
  bottom: 16px;
  left: 50%;
  transform: translateX(-50%);
  padding: 8px 16px;
  border: none;
  border-radius: 4px;
  background: #f44336;
  color: white;
  cursor: pointer;
}

触发逻辑

const posToggleBtn = document.querySelector('.pos-toggle-btn');
const bottomPositioned = document.querySelector('.bottom-positioned');

posToggleBtn.addEventListener('click', () => {
  bottomPositioned.classList.toggle('hidden');
});

核心要点总结

  1. 不要直接删除DOM:删除元素会导致浏览器瞬间重排,过渡动画无法触发,必须用CSS类来平滑隐藏元素。
  2. 给上方元素加transition:针对会变化的属性(比如margin、定位的top/left、transform等)添加过渡,让布局变化时产生动画。
  3. 用max-height代替height:因为height: auto无法过渡,用max-height可以模拟内容的平滑收缩/展开。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:58:00