そもそも "opacity
が 1
以外の要素" が スタック文脈 を作るということを初めて知った情弱なのですが、Google Chrome で opacity
の値をアニメーションさせた場合に意図しない挙動をしたのでメモ。
<div class="red">
<div class="yellow">
</div>
</div>
<div class="blue">
</div>
こんな HTML があったとして、yellow
は red
や blue
より手前に持っていきたいとする。
ここで次のような CSS を指定すると Google Chrome だけはアニメーション完了後も yellow
が blue
の裏に回ったままになってしまう。
div {
width: 150px;
height: 150px;
position: relative; /* ← 再現条件 */
}
.red {
background: red;
animation: fadeIn 2s linear 1 forwards; /* ← forwards で 100% の値を保持するのが再現条件 */
}
@keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
@-webkit-keyframes fadeIn {
0% { opacity: 0; }
100% { opacity: 1; }
}
.blue {
background: blue;
}
.yellow {
background: yellow;
position: absolute;
bottom: -20px;
right: -20px;
z-index: 1; /* 手前に持っていきたい */
}
どうも animation-fill-mode
を forwards
に指定して 100%
のフレームで opacity: 1
としても opacity
が 1
扱いされずにスタック文脈が出来たままになる様子。
今回はアニメーションでフェードインさせた部分で Bootstrap の tooltip を表示させようとして重なり順がおかしくなったので { container: 'selector' }
を指定してやってツールチップ用の div
をスタック文脈を作ってしまった要素より外側に逃がして回避しましたが、DOM 構造を変えられない場合は困りそう……