opacity ってこんな動作だっけ?
◆ opacity が 1 以外だと stacking context が作られる
◆ position と同じようになるので z-index 指定しないと後に来る要素が上のレイヤになる
◆ position と同じようになるので z-index 指定しないと後に来る要素が上のレイヤになる
変なところが透過されて驚いたので書いてみます
こういう HTML を用意します
上部に固定するヘッダー部分とメインコンテンツがあります
ヘッダー部分は position がついていて メイン要素をスクロールするとメイン要素がヘッダーの裏に隠れます
なのですがメイン要素の中に opacity をつけるとなぜかヘッダーが透過されます
スクリーンショットです
右側は opacity がないものです
黄色い部分とヘッダー部分が重なっている部分が灰色になっていることからヘッダーのほうが上に来ていることがわかります
左側は opacity を付けて透過しています
ヘッダー自体は透過させず メイン要素の左側だけを透過させているのにヘッダーが透過されて裏側にあるはずのメイン要素が見えています
右側をみてわかるように メイン要素はヘッダーの裏側にあって いくら裏側が透けていてもそれより重なりが上のヘッダー要素が透過されていなければ裏側は見えないと思うのですが見えています
バグにしか思えなかったのですが 他ブラウザでも同じ挙動なので正しい動きみたいです
ヘッダー要素に 1 など 0 より大きな値をつけるか opacity を設定した要素に -1 など 0 より小さな値を設定すれば透過されなくなりました
position を付けていない .left の要素に -1 を付けても動きました
opacity って自身の透過という意味じゃなくて 上下問わず z-index が同じ階層になってる要素間でのアルファブレンド率ってことなんでしょうか
https://developer.mozilla.org/en-US/docs/Web/CSS/opacity
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
通常は DOM のツリー的に後から来たものがレイヤが上になります
position を使うとレイヤの重なりが特殊になって position を付けた要素が position を指定していない要素より上になります
上のページではヘッダーの要素が HTML 的に先に来てるのに右半分ではヘッダーのほうが上に来ている理由です
この特殊なレイヤは stacking context と言ってこれ用のルールで重なりを制御できます
z-index が有効なのはここに対してです
opacity を 1 以外に設定した場合でも この stacking context が作られ position を設定したのと同じように扱われるようです
今回の場合のメイン要素の左側は opacity があるのでヘッダーと同じ z-index が 0 のレイヤにいます
同じ z-index なら HTML 的に後のメイン要素のほうが上側にいます
「ヘッダー要素が透過されてメイン要素が見えている」 のではなく 「上側にあるメイン要素が透過されているからヘッダーが見えている」 が正しいです
position をつけていないのに z-index を -1 にしたら透過されなくなったのが不思議でしたが これなら納得です
とは言ってもこれまで普通に opacity を使ってましたが全然知りませんでしたし意識したことなかったです
position がなくても opacity を使うときは z-index を意識したほうが良いようですね
position と opacity 以外にも stacking context が作られる CSS プロパティがあって使われそうなものだと
のあたりです
頻繁にではありませんが 凝ったことしようとすると使われるものです
詳しいことは MDN のページをみてみてください
こういう HTML を用意します
<!doctype html>
<style>
body {
margin: 0;
}
header {
position: sticky;
background: #888;
color: white;
top: 0;
height: 40px;
}
section {
display: flex;
}
div {
width: 50%;
height: 200vh;
padding: 10px;
}
div p {
font-size: 30px;
margin: 10px;
background: #ffee99;
}
.left {
opacity: .3;
}
</style>
<header>STICKY HEADER</header>
<section>
<div class="left">
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
</div>
<div class="right">
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
<p>aaaaaaaaaaaaaaaaaaaa</p>
</div>
</section>
上部に固定するヘッダー部分とメインコンテンツがあります
ヘッダー部分は position がついていて メイン要素をスクロールするとメイン要素がヘッダーの裏に隠れます
なのですがメイン要素の中に opacity をつけるとなぜかヘッダーが透過されます
スクリーンショットです
右側は opacity がないものです
黄色い部分とヘッダー部分が重なっている部分が灰色になっていることからヘッダーのほうが上に来ていることがわかります
左側は opacity を付けて透過しています
ヘッダー自体は透過させず メイン要素の左側だけを透過させているのにヘッダーが透過されて裏側にあるはずのメイン要素が見えています
右側をみてわかるように メイン要素はヘッダーの裏側にあって いくら裏側が透けていてもそれより重なりが上のヘッダー要素が透過されていなければ裏側は見えないと思うのですが見えています
バグにしか思えなかったのですが 他ブラウザでも同じ挙動なので正しい動きみたいです
対処方法
ヘッダーが透けないようすることは可能で z-index を指定すれば大丈夫ですヘッダー要素に 1 など 0 より大きな値をつけるか opacity を設定した要素に -1 など 0 より小さな値を設定すれば透過されなくなりました
position を付けていない .left の要素に -1 を付けても動きました
opacity って自身の透過という意味じゃなくて 上下問わず z-index が同じ階層になってる要素間でのアルファブレンド率ってことなんでしょうか
答えは
opacity を調べてみると答えがわかりましたhttps://developer.mozilla.org/en-US/docs/Web/CSS/opacity
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context
通常は DOM のツリー的に後から来たものがレイヤが上になります
position を使うとレイヤの重なりが特殊になって position を付けた要素が position を指定していない要素より上になります
上のページではヘッダーの要素が HTML 的に先に来てるのに右半分ではヘッダーのほうが上に来ている理由です
この特殊なレイヤは stacking context と言ってこれ用のルールで重なりを制御できます
z-index が有効なのはここに対してです
opacity を 1 以外に設定した場合でも この stacking context が作られ position を設定したのと同じように扱われるようです
今回の場合のメイン要素の左側は opacity があるのでヘッダーと同じ z-index が 0 のレイヤにいます
同じ z-index なら HTML 的に後のメイン要素のほうが上側にいます
「ヘッダー要素が透過されてメイン要素が見えている」 のではなく 「上側にあるメイン要素が透過されているからヘッダーが見えている」 が正しいです
position をつけていないのに z-index を -1 にしたら透過されなくなったのが不思議でしたが これなら納得です
とは言ってもこれまで普通に opacity を使ってましたが全然知りませんでしたし意識したことなかったです
position がなくても opacity を使うときは z-index を意識したほうが良いようですね
position と opacity 以外にも stacking context が作られる CSS プロパティがあって使われそうなものだと
- mix-blend-mode
- transform
- filter
- perspective
- clip-path
- mask
のあたりです
頻繁にではありませんが 凝ったことしようとすると使われるものです
詳しいことは MDN のページをみてみてください