动态

详情 返回 返回

每天進步一點點——學習高度過渡的四種方式 - 动态 详情

每天學點知識點,每天進步一點點,本文記錄了高度過渡變化的四種方式,大家一塊來查漏補缺,或者回顧知識吧😉😉😉

常見的四種方式的高度過渡

目前常見的高度過渡的方式有四種

  • transition + height
  • transition + max-height
  • transition + tranform:scale(0/1)
  • JS方式計算元素的高度
實際上,還有一個height: calc-size(auto)也能實現,只是兼容性目前還不行,估計還得等個三五年,才能放心用

1. 通過transition + height方式

transition只針對數值變化有效,所以 height:auto 不觸發過渡動畫,height:200px可觸發動畫 但該數值固定,無法滿足不固定長度的情況。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .elA {
            width: 150px;
            height: 50px;
            background-color: #eee;
        }

        .elB {
            width: 300px;
            background-color: #5b734a;
            color: #ddd;
            height: 0;
            overflow: hidden;
            transition: 1s;
            position: absolute;
        }

        /* transition只針對數值變化有效,所以 height:auto 不觸發過渡動畫,
            height:200px可觸發動畫 但該數值固定,無法滿足不固定長度的情況。*/
        .elA:hover+.elB {
            height: 200px;
        }
    </style>
</head>

<body>
    <div class="elA">元素A
    </div>
    <div class="elB">
        元素B
        <div class="inner">
            Lorem ipsum dolor sit amet consectetur adipisicing elit.<br>
            Architecto officiis repudiandae natus dolores quos porro
            eveniet eum temporibus aspernatur <br>commodi sapiente ab accusantium
            dolorem nisi id nemo, obcaecati velit non.
        </div>
    </div>
</body>

</html>

2. 通過transition + max-height方式

因無法確認顯示內容最大高度,會導致設置高度過大,回縮時有延遲

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .elA {
            width: 150px;
            height: 50px;
            background-color: #eee;
        }

        .elB {
            width: 300px;
            background-color: #5b734a;
            color: #ddd;
            max-height: 0;
            overflow: hidden;
            transition: 1s;
            position: absolute;
        }

        /* 因無法確認顯示內容最大高度,會導致設置高度過大,回縮時有延遲 */
        .elA:hover+.elB {
            max-height: 1000px;
        }
    </style>
</head>

<body>
    <div class="elA">元素A</div>
    <div class="elB">
        元素B
        <div class="inner">
            Lorem ipsum dolor sit amet consectetur adipisicing elit.<br>
            Architecto officiis repudiandae natus dolores quos porro
            eveniet eum temporibus aspernatur <br>commodi sapiente ab accusantium
            dolorem nisi id nemo, obcaecati velit non.
        </div>
    </div>
</body>

</html>

3. 通過transition + tranform:scale(0/1)

使用這種方式時,展示收回會出現一個壓縮的過程

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .elA {
            width: 150px;
            height: 50px;
            background-color: #eee;
        }

        .elB {
            width: 300px;
            background-color: #5b734a;
            color: #ddd;
            transform-origin: center top;
            transform: scaleY(0);
            overflow: hidden;
            transition: 1s;
            position: absolute;
        }

        /* scale回縮時,會有展示出一個壓縮的過程 */
        .elA:hover+.elB {
            transform: scaleY(1);
        }
    </style>
</head>

<body>
    <div class="elA">元素A</div>
    <div class="elB">
        元素B
        <div class="inner">
            Lorem ipsum dolor sit amet consectetur adipisicing elit.<br>
            Architecto officiis repudiandae natus dolores quos porro
            eveniet eum temporibus aspernatur <br>commodi sapiente ab accusantium
            dolorem nisi id nemo, obcaecati velit non.
        </div>
    </div>
</body>

</html>

4. 通過JS方式計算元素的高度,實現元素高度 絲滑展示

通過dom.getBoundingClientRect().height計算

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .elA {
            width: 150px;
            height: 50px;
            background-color: #eee;
        }

        .elB {
            width: 300px;
            background-color: #5b734a;
            color: #ddd;
            overflow: hidden;
            transition: 1s;
            position: absolute;
            height: 0;
        }
    </style>
</head>

<body>
    <div class="elA">元素A
    </div>
    <div class="elB">
        元素B
        <div class="inner">
            Lorem ipsum dolor sit amet consectetur adipisicing elit.<br>
            Architecto officiis repudiandae natus dolores quos porro
            eveniet eum temporibus aspernatur <br>commodi sapiente ab accusantium
            dolorem nisi id nemo, obcaecati velit non.
        </div>
    </div>

    <script>
        let elA = document.querySelector('.elA')
        let elB = document.querySelector('.elB')
        elA.onmouseenter = () => {
            // 先獲取元素的自適應原始高度
            elB.style.height = 'auto'
            let h = elB.getBoundingClientRect().height
            // 回到最初的高度
            elB.style.height = 0
            // 代碼到這裏,頁面會直接保持高度為0的狀態,不會有動畫。

            // 強制迴流
            // 方式一、計算,(當DOM元素的大小、位置或可見性發生變化時,瀏覽器需要重新計算頁面佈局,這個過程就是迴流。)
            // elB.getBoundingClientRect()
            // elB.style.height = h + 'px'

            // 方式二、在 requestAnimationFrame 的回調函數中進行DOM操作,如改變元素的樣式、尺寸或位置,這些操作會排隊等待瀏覽器的下一個重繪週期,觸發迴流。
            requestAnimationFrame(() => {
                elB.style.height = h + 'px'
            })
        }
        elA.onmouseleave = () => {
            elB.style.height = 0
        }
    </script>
</body>

</html>
A good memory is better than a bad pen. Record it down...
user avatar neixiangdehouzi 头像 huaiyug 头像 wubomu 头像 fanudekaixinguo 头像 zhuyunbo 头像 suporka 头像 kevinzhw 头像 yimo 头像 sukaaa 头像 iicode 头像 jsonlee_12138 头像 jrainlau 头像
点赞 20 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.