CSS實現漸隱漸現效果
實現漸隱漸現效果是比較常見的一種交互方式,通常的做法是控制display
屬性值在none
和其它值之間切換,雖說功能可以實現,但是效果略顯生硬,所以會有這樣的需求——希望元素消失時具有平滑的效果。
實現
opacity
opacity
是用以設置透明度的屬性,單純將opacity
設置為0
只能從視覺上隱藏元素,而元素本身依然占據它自己的位置並對網頁的布局起作用,它也將響應用戶交互例如點擊事件,對於其添加過渡屬性可以顯示動畫效果,使用transitionend
事件監聽過渡完成之后隱藏元素,此外對於opacity
屬性,可以利用其透明的視覺效果制作點擊劫持攻擊。
<!DOCTYPE html>
<html>
<head>
<title>opacity</title>
<style type="text/css">
.page{
width: 200px;
padding: 10px 20px;
border: 1px solid #eee;
}
.container {
overflow: hidden;
}
.container > .options{
opacity: 1;
transition: all .5s;
}
.container > .btn{
color: #4C98F7;
cursor: pointer;
text-decoration: underline;
}
.container > .hide{
display: none;
}
.container > .fold{
opacity: 0;
}
</style>
</head>
<body>
<div class="page">
<div class="container">
<div class="btn" onclick="operate(this)" unfold="1">隱藏</div>
<div class="options">
<div class="option">選項1</div>
<div class="option">選項2</div>
<div class="option">選項3</div>
<div class="option">選項4</div>
<div class="option">選項5</div>
<div class="option">選項6</div>
<div class="option">選項7</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
function operate(btn){
const optionsNode = document.querySelector(".container > .options");
const unfold = btn.getAttribute("unfold");
if(unfold && unfold==="1"){
btn.innerText = "打開";
optionsNode.classList.add("fold");
const finish = () => {
optionsNode.classList.add("hide");
optionsNode.removeEventListener("transitionend", finish); // 移除監聽器
}
optionsNode.addEventListener("transitionend", finish); // 添加監聽器
}else{
btn.innerText = "隱藏";
optionsNode.classList.remove("hide");
setTimeout(() => optionsNode.classList.remove("fold"));
}
btn.setAttribute("unfold", unfold === "0" ? "1" : "0");
}
</script>
</html>
visibility opacity
當visibility
屬性值為hidden
的時候,元素將會隱藏,也會占據着自己的位置,並對網頁的布局起作用,與opacity
不同的是它不會響應任何用戶交互,元素在讀屏軟件中也會被隱藏,如果對於子元素的visibility
被設置為visible
而父元素的visibility
設置為hidden
,子元素依舊可以顯示而父元素會被隱藏,這個屬性在兼容性方面需要在IE 9
以上的瀏覽器才能使用。此外從visibility: hidden;
到visibility: visible;
變化時,如果設置了過渡時間為3s
,那么在事件發生后,元素並不會立即呈現出從hidden
到visible
的效果,而是會先等待3s
,然后再瞬間隱藏,從顯示到最終消失視線中的時間確實3s
,只不過並不是逐漸過渡出現的,所以通常為了實現過渡效果,我們與opacity
一起使用來完成過渡效果。
<!DOCTYPE html>
<html>
<head>
<title>opacity</title>
<style type="text/css">
.page{
width: 200px;
padding: 10px 20px;
border: 1px solid #eee;
}
.container {
overflow: hidden;
}
.container > .options{
opacity: 1;
visibility: visible;
transition: all .5s;
}
.container > .btn{
color: #4C98F7;
cursor: pointer;
text-decoration: underline;
}
.container > .hide{
display: none;
}
.container > .fold{
opacity: 0;
visibility: hidden;
}
</style>
</head>
<body>
<div class="page">
<div class="container">
<div class="btn" onclick="operate(this)" unfold="1">隱藏</div>
<div class="options">
<div class="option">選項1</div>
<div class="option">選項2</div>
<div class="option">選項3</div>
<div class="option">選項4</div>
<div class="option">選項5</div>
<div class="option">選項6</div>
<div class="option">選項7</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
function operate(btn){
const optionsNode = document.querySelector(".container > .options");
const unfold = btn.getAttribute("unfold");
if(unfold && unfold==="1"){
btn.innerText = "打開";
optionsNode.classList.add("fold");
const finish = () => {
optionsNode.classList.add("hide");
optionsNode.removeEventListener("transitionend", finish); // 移除監聽器
}
optionsNode.addEventListener("transitionend", finish); // 添加監聽器
}else{
btn.innerText = "隱藏";
optionsNode.classList.remove("hide");
setTimeout(() => optionsNode.classList.remove("fold"));
}
btn.setAttribute("unfold", unfold === "0" ? "1" : "0");
}
</script>
</html>
每日一題
https://github.com/WindrunnerMax/EveryDay
參考
https://juejin.cn/post/6844903497998024711
https://www.cnblogs.com/MrZhujl/p/10315177.html
https://blog.csdn.net/u012767761/article/details/87369414