搜尋

首頁  >  問答  >  主體

如何在不擠壓內容的情況下透過變換對高度進行動畫處理

在我的專案中,當使用者點擊按鈕時,我一直在使用 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%); 來使其更接近。

看來我已經非常接近實現目標,但從未完全成功。有什麼現成的技巧可以做到這一點嗎?

要求:

P粉208469050P粉208469050371 天前469

全部回覆(1)我來回復

  • P粉005134685

    P粉0051346852024-01-02 09:03:14

    經過幾個晚上的睡眠,我找到了一個完全符合我需要的解決方案。我必須使用三層 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>

    回覆
    0
  • 取消回覆