動的にDOMを追加削除するようなポップアップ(ここではアラートモーダル)のフェードイン/アウト、特にアウトを綺麗にアニメーションさせるのに試行錯誤した。
悩み点
フェードインしたポップアップにフェードアウト効果をつけていると、
ポップアップのDOMを設置した瞬間にフェードアウトアニメーションを実行してしまい、
画面がチラついてしまう。
対策
対策として、DOMを設置し、ポップアップを表示した際に、フェードアウト効果をつけることにした。
そうすることでDOMを設置した際にフェードアウト効果が発動しないようにした。
- ポップアップを設置する
- ポップアップに
.--show
クラス を付与してポップアップを表示する - ポップアップを表示した際に
.--shown
というクラスも付与する。(このクラスにフェードアウト用のアニメーションが設定してある) - ポップアップから
.--show
クラスを削除し、ポップアップを非表示にする。(フェードアウトアニメーションが実行される)
実際のコード
追加時にチラついてしまうパターン
index.html 追加時にチラついてしまうパターン
<!DOCTYPE html>
<html>
<head>
<title>ポップアップをcssと少しだけjsでフェードイン / アウト</title>
<style>
.popup {
position: absolute;
top: 0;
right: 0;
visibility: hidden;
opacity: 0;
width: 200px;
height: 200px;
background: #DDD;
padding: 1em;
animation: fadeOutAnimation 0.2s;
}
.popup--show {
visibility: visible;
opacity: 1;
animation: fadeInAnimation 0.2s;
}
@keyframes fadeInAnimation {
0% {
opacity: 0;
visibility: visible;
}
100% {
opacity: 1;
visibility: visible;
}
}
@keyframes fadeOutAnimation {
0% {
opacity: 1;
visibility: visible;
}
100% {
opacity: 0;
visibility: hidden;
}
}
</style>
<script>
function addPopup() {
const newDiv = document.createElement('div');
newDiv.classList.add('popup');
newDiv.innerHTML = "ポップアップテスト";
document.body.appendChild(newDiv);
}
</script>
</head>
<body>
<button onclick="addPopup()">ポップアップ追加</button>
</body>
</html>
追加時にチラつかないパターン
index.html 追加時にチラつかないパターン
<!DOCTYPE html>
<html>
<head>
<title>ポップアップをcssと少しだけjsでフェードイン / アウト</title>
<style>
.popup {
position: absolute;
top: 0;
right: 0;
visibility: hidden;
opacity: 0;
width: 200px;
height: 200px;
background: #DDD;
padding: 1em;
}
/* --showよりも先に書いておく */
.popup--shown {
animation: fadeOutAnimation 0.2s;
}
.popup--show {
visibility: visible;
opacity: 1;
animation: fadeInAnimation 0.2s;
}
@keyframes fadeInAnimation {
0% {
opacity: 0;
visibility: visible;
}
100% {
opacity: 1;
visibility: visible;
}
}
@keyframes fadeOutAnimation {
0% {
opacity: 1;
visibility: visible;
}
100% {
opacity: 0;
visibility: hidden;
}
}
</style>
<script>
function addPopup() {
const newDiv = document.createElement('div');
newDiv.classList.add('popup');
newDiv.innerHTML = "ポップアップテスト";
document.body.appendChild(newDiv);
}
</script>
</head>
<body>
<button onclick="addPopup()">ポップアップ追加</button>
</body>
</html>