CSS z-indexとスタッキングコンテキストを3Dで分解
CSS z-indexとスタッキングコンテキストのガイド
CSSのz-indexが効かない?スタッキングコンテキストを3Dで確認 | We.Inc
z-indexが無視される理由、スタッキングコンテキストを作るすべてのプロパティ、レイヤーの3D分解ビュー、固定ヘッダーとドロップダウン、z-indexのスケール、そしてデバッグ用のチェックリストを紹介します。
z-indexは重なり合う要素の順序を決めますが、それは同じスタッキングコンテキストの中に限られます。親がより低いz-indexでコンテキストを作っている場合、z-index: 9999の子要素でも、親の外にある要素より上には出られません。コンテキストは、positionとz-indexの組み合わせ、1未満のopacity、transform、filter、isolation: isolate、その他いくつかのプロパティによって作られます。
z-indexが無視されるように見える理由
- z-indexがまったく効かない
- 要素がposition: staticで、フレックスやグリッドの子要素でもない
- 巨大なz-indexでも後ろに隠れる
- 祖先要素がより低いレイヤーでスタッキングコンテキストを作っている
- ドロップダウンが次のセクションの下に隠れる
- 親要素に変形、不透明度、フィルターの指定がある
- メニューが端で切れる
- 原因はz-indexではなく、祖先要素のoverflow: hidden
下の3Dビューでは、小さなページをスタッキングレイヤーごとに分解し、どのボックスがどのコンテキストに閉じ込められているかを確認できます。z-indexの値を変えたり、親要素にコンテキストを作るプロパティを切り替えたりしてみてください。その後に、MDNに基づくすべてのトリガー、ドロップダウン付きの固定ヘッダー、トークンのスケール、段階的なデバッグ手順を紹介します。
- ヘッダー、カード、カード内のドロップダウンにz-indexの値を設定します。
- カードにスタッキングコンテキストのトリガーを切り替えて付け、ドロップダウンが閉じ込められる様子を確認します。
- 3Dビューをオンにすると、レイヤーが分離され、コンテキストごとにまとめて表示されます。
- isolation: isolateを使うか、ドロップダウンをコンテキストの外に移動して解決します。
- 数値を上げる前に、スタッキングコンテキストを探しましょう。閉じ込められたコンテキストの中でz-indexを上げても効果はありません。
- z-indexの値は名前付きのトークンで管理し、値の間に余裕を持たせましょう。そうすれば新しいレイヤーを番号の振り直しなしで追加できます。
- コンポーネントにisolation: isolateを使うと内部のz-indexを閉じ込められ、ページのほかの部分と競合しなくなります。
- モーダルやポップオーバーには、ネイティブのダイアログ要素やポップオーバー属性を使いましょう。これらはどのz-indexよりも上にあるトップレイヤーを使います。
よくある質問
z-indexが効かないのはなぜですか?
要素が配置されていない(z-indexにはstatic以外のposition、またはフレックスやグリッドの親が必要)か、スタッキングコンテキストに閉じ込められているかのどちらかです。結果を決めるのは親自身のコンテキスト内での位置で、子要素はどんな数値を持っていてもそこから抜け出せません。
スタッキングコンテキストは何によって作られますか?
ルート要素、z-indexを持つ配置済み要素、固定配置と粘着配置の要素、z-indexを持つフレックスやグリッドの子要素、1未満のopacity、transform、filter、clip-path、mask、mix-blend-mode、perspective、isolation: isolate、一部のcontainやwill-changeの値、サイズコンテナー、そしてトップレイヤーの要素です。
isolation: isolateは何をするものですか?
新しいスタッキングコンテキストを作るだけで、それ以外には何もせず、見た目も変わりません。コンポーネントのルートに付ければ、負のz-indexを持つ子要素がページの後ろに落ちず、コンポーネント自身の背景の後ろにとどまり、内部のレイヤーが外部のレイヤーと混ざることもなくなります。
ドロップダウンを次のセクションより上に表示し続けるには?
ドロップダウンを含むヘッダーやコンテナーに、後続のセクションより高いz-indexを付けます。どちらも配置済みである必要があります。コンテナーに変形や不透明度の指定がある場合はそれ自体がコンテキストになるので、z-indexはドロップダウンではなくそのコンテナーに付けましょう。
負のz-indexは安全ですか?
有効な値ですが、要素はスタッキングコンテキストの背景の後ろに回ります。親にコンテキストがない場合、ページの背景の後ろに回って見えなくなることがあります。親にisolation: isolateを付けて、内側にとどめましょう。
描画順序の仕組み
- 1つのスタッキングコンテキストの中では、ブラウザーは決まった順序で描画します。まずコンテキスト自身の背景、次に負のz-indexを持つ子要素、通常のブロックコンテンツ、フロート、インラインコンテンツ、z-indexがautoまたは0の配置済み要素をソース順に、そして最後に正のz-indexを低いものから高いものへと描画します。
- 子のコンテキストは、その順序の中で親の位置にひとまとまりとして描画されます。内部のものは兄弟要素との間でしか並べ替えられません。z-index: 1のカードの中にある9999が、z-index: 2の隣の要素に負ける理由はまさにこれです。
デバッグの手順
- まず、それが本当に重なり順の問題かを確認します。要素がまっすぐな端で切れているなら、代わりに祖先要素のoverflowを探しましょう。次に、DevToolsで隠れている要素から上にたどり、各祖先の計算済みスタイルに、このページで挙げたトリガーがないか確認します。
- ChromiumのDevToolsにはLayersパネルが、Edgeには3D Viewがあり、合成レイヤーを視覚的に確認できます。コンテキストを作っている祖先が見つかったら、その祖先を上げる、トリガーを取り除く、浮かせたい要素をその外にレンダリングする、のいずれかで解決します。
スタッキングコンテキストを作るもの一覧
MDNのスタッキングコンテキストのリファレンスに基づいています。どれか1つの条件を満たせば十分です。
スタッキングコンテキストのトリガー
- ルート要素
- htmlは常にルートのスタッキングコンテキスト
- position: absoluteまたはrelative
- auto以外のz-indexがある場合のみ
- position: fixedまたはsticky
- 常に。z-indexは不要
- フレックスまたはグリッドの子要素
- auto以外のz-indexがある場合。positionがstaticでも該当
- container-type: sizeまたはinline-size
- サイズクエリのコンテナーである要素すべて
- 1未満のopacity
- opacity: 0.99も含む
- transform、scale、rotate、translate
- 未指定(none)以外の値
- filterまたはbackdrop-filter
- 未指定(none)以外の値
- mask、mask-image、mask-border
- 未指定(none)以外の値
- isolation: isolate
- まさにこの目的のためのもので、見た目への副作用なし
- 設定するとスタッキングコンテキストを作るプロパティを指定した場合
- layout、paint、またはそれらを含むショートハンド(strict、content)
- トップレイヤー
- 開いているモーダルdialog、popover、フルスクリーン要素、およびそれらの::backdrop
落とし穴と解決策
z-index 9999なのに負けてしまう
青いカードはz-index 1のコンテキストです。そのツールチップは9999ですが、カード内の要素とだけ比較されるため、z-index 2のオレンジのボックスに覆われてしまいます。
isolation: isolateで負のレイヤーを内側にとどめる
isolateがないと、z-index: -1の装飾はセクションの背景の後ろに落ちて消えてしまいます。isolateがあれば、セクション自体がコンテキストになります。
ドロップダウン付きの固定ヘッダー
ヘッダーはstickyなので、すでにコンテキストです。コンテンツより上のz-indexを付ければ、内部のドロップダウンはそのレイヤーを引き継ぎます。巨大な数値は必要ありません。
- 通常のコンテンツ
- ホバー時に浮き上がるカード、固定のテーブルヘッダー
- メニュー、オートコンプリートのリスト
- 固定のサイトヘッダー
- ドロワーの背景
- 独自のモーダル(ネイティブのダイアログは代わりにトップレイヤーを使用)
- すべての上に表示すべき通知
3D分解ビュー付きのスタッキング実験室
ヘッダーのz-index
カードのz-index(またはauto)
ドロップダウンのz-index
バナーのz-index
カードのコンテキストトリガー
カードに追加するプロパティ
3D分解ビュー(レイヤーを回転して引き離す)
レイヤーを分離して表示。上にあるほど後に描画されます
フラット表示、実際のCSS
ヘッダー z {z}
カード z {z}
ドロップダウン z {z}
バナー z {z}
(カード内)
バナーより上
バナーより下
カードはスタッキングコンテキストを作っています({why})。ドロップダウンの{d}はカード内でしか意味を持たないため、カードと同じく{pos}にあります。
カードはスタッキングコンテキストではないため、ドロップダウンが直接競います:{d}とバナーの{b}の比較です。結果は{pos}です。
この設定のCSS
CSSをコピー
試してみましょう:カードのzをauto、ドロップダウンを9999にしてから、transformを選びます。プロパティ1つでドロップダウンが閉じ込められます。
コピーして使えるz-indexスケール
トークンをコピー
トークン
値
用途
無料で始める · クレジットカード不要
関連: ガイド|Webマーケティングと集客を学ぶ
製品
ご利用いただける方
機能
リソース
会社情報
サイトマップを見る