如何在不擠壓內容的情況下透過變換對高度進行動畫處理
P粉208469050
P粉208469050 2024-01-01 11:51:20
0
1
430

在我的專案中,當使用者點擊按鈕時,我一直在使用 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>
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板