每天学点知识点,每天进步一点点,本文记录了高度过渡变化的四种方式,大家一块来查漏补缺,或者回顾知识吧😉😉😉
常见的四种方式的高度过渡
目前常见的高度过渡的方式有四种
transition + height
transition + max-height
transition + tranform:scale(0/1)
JS方式计算元素的高度
实际上,还有一个
height: calc-size(auto)
也能实现,只是兼容性目前还不行,估计还得等个三五年,才能放心用
1. 通过transition + height方式
transition只针对数值变化有效,所以 height:auto 不触发过渡动画,height:200px可触发动画 但该数值固定,无法满足不固定长度的情况。

html
<!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方式
因无法确认显示内容最大高度,会导致设置高度过大,回缩时有延迟

html
<!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)
使用这种方式时,展示收回会出现一个压缩的过程

html
<!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
计算

html
<!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...