如何在不挤压内容的情况下通过变换对高度进行动画处理
P粉208469050
P粉208469050 2024-01-01 11:51:20
0
1
439

在我的项目中,当用户单击按钮时,我一直在使用 jQuery slideUp() 向上滑动 200 项列表中的元素。但是,众所周知,CSS 高度动画需要回流,从而导致动画不稳定。该动画是应用程序的一个组成部分,我愿意做大量的工作以使其工作并顺利工作。

我决定 CSS transform 是让它顺利工作的方法,因为它是在 GPU 上处理的,在一些现代浏览器上,它甚至脱离了主线程,繁重的 JS 工作不会影响变换。 (我确实有繁重的 JS 工作)。

我正在寻找一个使用CSS transition的巧妙解决方案:transform来复制jQuery slideUp,它只是为height属性设置动画。以下是我的尝试,但似乎 scaletranslate 未按预期同步。

$("button").on("click", function() {
  $(".collapsible").addClass("collapsed")
  setTimeout(function() {
    $(".collapsible").removeClass("collapsed")
  }, 5000);
});
.list-item {
  width: 400px;
  height: 100px;
  background-color: blue;
  margin-top: 10px;
  overflow-y: hidden;
}

.collapsible.collapsed .content {
  transition: transform 3s linear;
  transform: scale(1, 1) translate(0, -100%);
}

.collapsible.collapsed {
  transition: transform 3s linear;
  transform: translate(0, -50%) scale(1, 0);
}

.collapsible.collapsed ~ .list-item {
  transition: transform 3s linear;
  transform: translate(0, -100%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<button>Collapse</button>
<div class="list-item collapsible">
  <div class="content">
    Just an example <br>
    Just an example <br>
    Just an example <br>
    Just an example <br>
    Just an example <br>
  </div>
</div>
<div class="list-item">
  
</div>
<div class="list-item">
  
</div>

我对这些值进行了一些修改,并通过将 content 转换更改为 transform:scale(1, 3) translate(0, -50%); 来使其更接近。

看来我已经非常接近实现目标,但从未完全成功。有什么现成的技巧可以做到这一点吗?

要求:

  • 最好没有 JS
  • 脱离主线程

P粉208469050
P粉208469050

全部回复(1)
P粉005134685

经过几个晚上的睡眠,我找到了一个完全符合我需要的解决方案。我必须使用三层 div 并确保内部两层设置为 height: 100%;。然后,我取消了 scale() 并使用 transform() 将中间层向上滑动。

这符合我的要求:

  • 使用 Transform(),其在 GPU 上的运行速度应高达 60fps
  • 不会使用 Scale() 压缩内容
  • 内容像 jQuery 一样从下到上消失 SlideUp()
  • 无论目标元素的高度如何,下面的其他元素都会向上滑动以填充间隙
  • 一旦触发动画,就不再涉及 JS

$("button").on("click", function() {
  const height = $(".collapsible").css("height");
  $(":root").css("--height", height);
  $(".collapsible").addClass("collapsed");
  setTimeout(function() {
    $(".collapsible").removeClass("collapsed");
  }, 4000);
});
:root {
  --height: unset;
}

.outer-container {
  width: 400px;
  height: fit-content;
  background-color: transparent;
  margin-top: 10px;
  overflow-y: hidden;
}

.inner-container {
  height: 100%;
  background-color: blue;
  overflow: hidden;
}

.content {
  height: 100%;
}

.collapsible.collapsed .inner-container {
  transition: transform 3s linear;
  transform: translate(0, -100%);
}

.collapsible.collapsed .content {
  transition: transform 3s linear;
  transform: translate(0, 100%);
}

.collapsible.collapsed ~ .outer-container {
  transition: transform 3s linear;
  transform: translate(0, calc((var(--height) * -1) - 10px));
}

.collapsible .inner-container {
  transition: transform .5s ease-in-out;
  transform: translate(0, 0);
}

.collapsible .content {
  transition: transform .5s ease-in-out;
  transform: translate(0, 0);
}

.collapsible ~ .outer-container {
  transition: transform .5s ease-in-out;
  transform: translate(0, 0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
<button>Collapse</button>
<div class="outer-container">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
<div class="outer-container collapsible">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
<div class="outer-container">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
<div class="outer-container">
  <div class="inner-container">
    <div class="content">
      Just an example <br>
      Just an example <br>
      Just an example <br>
      Just an example <br>
    </div>
  </div>
</div>
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板