結論
opacityが1未満の要素だと重なり順が昇格する。
目的
要素の重なり順について、以下のようななんとな〜くの理解を持っている方にむけた記事です。
-
z-indexで重なりを定義できるのは知っている - position:(初期値)static以外を設定すると、通常の重なりのフローからは外れて上位にくる、みたいなふんわりした理解を持っている
- 親要素の
z-indexの値が小さいとどんなに値を大きくしても、なんかうまくいかないらしいよ〜、みたいなことは知っている
私もこんな感じでなんとなく理解していて、なんとなくで今までやってきました。
しかし今回
positionも特に指定していない要素に、positon:fixed;を指定した要素が負ける
という事象を経験しちょっと詳しくなったのでこの記事を書いています。
起きたこと
兄弟要素で要素Aがdisplay:blockになったとき(表示)時に、要素Aが最前面にくるかと思ったら、
要素Bが最前面で、その下に要素Aが来た。
- 要素A(header):
position:fixed;の要素(デフォルトはdisplay:none;、ボタンクリックでdisplay:block;を持つクラスが付与され表示) - 要素B(h1):position何もつけていない要素
See the Pen Untitled by nako (@nakonako) on CodePen.
原因
opacityが1未満の要素の場合でも、スタックコンテキストが作られるためである。
スタックコンテキストとは
MDNを見ても日本語が難解なのでGeminiに説明してもらった。
ウェブページ上の要素は、単に横や縦に並んでいるだけでなく、3次元的に重なり合って表示されます。
どの要素が手前に来て、どの要素が奥に隠れるかを決めるのが、このスタックコンテキストという仕組みです。例えるなら、スタックコンテキストは、**要素を乗せるための専用の「トレイ」**です。
通常の要素の場合、土俵が1つであるが、
positionがついてしまうと、それぞれ土俵が形成されるみたいなイメージ。
各土俵の重なり順(z-index)で勝負して、値が高いとレイヤー上位になる。
ただ、重なり順(z-index)が指定されていない場合は、HTMLの順序に沿って重なり順が決まる(=HTMLファイル内で下に記述されている要素の方が上位に来る)
つまり今回は、
要素A同様、要素Bもスタックコンテキストが形成された。
要素Aのz-indexの指定がなかったため、順序が下だった要素Bが上位にきた。
(上のコーディング例のopacity:0.9;を外すとHEADERが上位に来るようになる)
実はpositonやopacity以外にもスタックコンテキストが作られる要素はある
全く知らなかったが、結構ある😦
- 文書のルート要素 (
<html>) - position の値が absolute または relative であり、かつ z-index の値が auto 以外の要素
- position の値が fixed または sticky の要素
- フレックスコンテナーの子であり、 z-index の値が auto 以外の要素。
- グリッド (grid) コンテナーの子であり、 z-index の値が auto 以外の要素。
などなど...
感想
MDNの日本語は難しい。
参考