【CSS】z-indexの基本の使い方、要素の重なり順を指定する|HTML&CSS入門講座(16)

HTML&CSS
この記事は約26分で読めます。

【CSS】z-indexの基本の使い方、要素の重なり順を指定する|HTML&CSS入門講座(16)のPodcast

下記のPodcastは、Geminiで作成しました。

ストーリーブック

はじめに

ウェブサイトのデザインにおいて、要素を重ね合わせて表示するレイアウトは今や不可欠な要素となっています。画面上部に固定されるナビゲーションバー、画像の上に重なるテキスト、クリックした際に最前面に浮き上がるモーダルウィンドウなど、これらすべての表現はCSSによる「重なり順」の制御によって支えられています。通常、HTMLは文書の構造を上から下へと流れる二次元的な平面として処理しますが、CSSの特定のプロパティを適用することで、画面に対して奥行き方向、すなわち「Z軸」という概念が導入されます 。この重なり順を制御する中心的なプロパティが z-index です。しかし、このプロパティは一見単純に見えて、実際には多くの開発者が「数値を大きくしたのに上にこない」「特定の状況で突然効かなくなる」といったトラブルに直面する、CSSの中でも特に理解が難しい項目の一つとして知られています 。本稿では、最新のブラウザ仕様とモダンなフロントエンド開発の知見に基づき、z-index の基礎から、その背後にある「重ね合わせコンテキスト(Stacking Context)」という高度な仕組み、そして現代的な管理手法までを徹底的に解説します。

重なり順の基本原理とデフォルトの挙動

ブラウザは「ペインターズアルゴリズム(画家のアルゴリズム)」と呼ばれる手法を用いて、HTMLソースコードの記述順に従い、奥にあるものから手前にあるものへと順に描画を行っていきます 。

自然な重なり順(スタック順序)

特別なCSS指定がない場合、要素の重なり順は「自然な重なり順(Natural Stacking Order)」と呼ばれるルールに従います 。このルールでは、HTMLのソースコード上で後に記述された要素ほど、視覚的には手前に表示されることになります 。具体的には、以下の表のような優先順位で描画が行われます。

描画の優先順位要素のカテゴリ重なり方のルール
1(最背面)ルート要素(\<html>)文書の土台として最も奥に配置されます。
2通常フローのブロック要素position が static な要素が記述順に重なります。
3浮動要素(float)通常のブロック要素よりも手前に表示されます。
4インライン要素テキストやリンクなどが浮動要素よりも手前にきます。
5(最前面)位置指定要素position が static 以外の要素が最も手前に配置されます。

同じ階層にある要素同士であれば、このルールに基づいて「後から書いたものが上」という原則が適用されます。しかし、デザイン上の要請から、HTMLの記述順に関わらず特定の要素を最前面に持っていきたい、あるいは背景の下に隠したいという場面が発生します。そこで登場するのが z-index プロパティです。

z-indexプロパティの定義と値

z-index プロパティは、位置指定された要素に対して、Z軸方向のスタックレベルを整数で指定するものです。この値には正の整数、ゼロ、負の整数を指定することができ、数値が大きいほど観察者に近い(手前)位置に配置され、数値が小さいほど観察者から遠い(奥)位置に配置されます 。

レイヤー区分指定される値視覚的な配置
手前のレイヤー以上の整数数値が大きいほど手前に表示されます。
デフォルトのレイヤーまたは未指定z-index が指定されていない要素と同じ高さです。
奥のレイヤー以下の整数背景や他の要素よりも後ろに回り込ませる際に使用します。

プロパティが定義されていない要素は、既定の描画レイヤー として扱われます 。複数の要素が同じ z-index 値を持つ場合、前述の「HTML内の記述順」が最終的な決定要素となります 。

z-indexを正しく動作させるための必須条件

初心者が z-index を使用する際に最も頻繁に遭遇する問題は、「プロパティを記述したのに全く反映されない」というものです。これは、z-index が特定の条件下にある要素に対してのみ有効であるという性質を持っているためです 。

位置指定(position)との関係

原則として、z-index は「位置指定要素(Positioned Elements)」に対してのみ効果を発揮します。位置指定要素とは、position プロパティの値が static(初期値)以外に設定されている要素を指します 。具体的には、以下のいずれかの値が設定されている必要があります。

position: relative;(相対位置指定)

position: absolute;(絶対位置指定)

position: fixed;(固定位置指定)

position: sticky;(粘着位置指定)

もし要素の位置を現在の場所から動かしたくない場合でも、z-index を有効にするためには position: relative; を指定することが推奨されます 。これは、単に「重なり順を制御可能な状態にする」ためのスイッチのような役割を果たします。

モダンな例外:フレックスアイテムとグリッドアイテム

従来のCSS仕様では位置指定が必須でしたが、現在のモダンなブラウザにおいては、新しいレイアウトモデルである「Flexbox」や「CSS Grid」のアイテム(直接の子要素)に対しても、position: static; のまま z-index が適用されるようになっています 。これはレイアウトの柔軟性を高めるための仕様変更であり、不必要な position: relative; の記述を減らすことにつながっています 。

重ね合わせコンテキスト(Stacking Context)の深い理解

z-index の挙動を複雑にし、多くの開発者を悩ませる最大の原因が「重ね合わせコンテキスト(Stacking Context)」という概念です 。これは、要素の重なりを管理するための「独自の階層グループ」のようなもので、一度このコンテキストが生成されると、その内部の要素は外部の要素と単純な数値比較ができなくなります。

重ね合わせコンテキストのメカニズム

重ね合わせコンテキストは、特定のプロパティが適用された要素をルートとして形成されます。このコンテキスト内に含まれる子要素たちは、そのコンテキストの中だけで重なり順が決定され、親のコンテキストからは「一つのまとまった層」として扱われます 。これを理解しやすくするために、よく「書類のフォルダ」や「バージョン番号」に例えられます。

例えば、以下のようなケースを考えてみましょう。

要素A(親):z-index: 10; を持ち、新しい重ね合わせコンテキストを形成している。

要素B(親):z-index: 5; を持ち、新しい重ね合わせコンテキストを形成している。

要素B-1(子):要素Bの中にあり、z-index: 9999; が指定されている。

この場合、要素B-1の数値がどんなに大きくても、親である要素B自体が要素Aよりも低い階層()にあるため、要素B-1が要素Aの前面に表示されることは絶対にありません 。要素B-1は「バージョン 5.9999」のような存在であり、要素Aという「バージョン 10.0」を超えることはできないのです 。

重ね合わせコンテキストを生成する主な要因

新しい重ね合わせコンテキストは、単に z-index を指定する以外にも、現代のCSSにおける様々なプロパティによって自動的に生成されます 。主要な条件を以下の表にまとめます。

カテゴリプロパティと条件特徴と注意点
基本文書のルート要素(\<html>)すべての重なり順の土台となります。
配置position: absolute / relative かつ z-index が auto 以外最も一般的なコンテキスト生成条件です。
配置position: fixed / stickyz-index の値に関わらずコンテキストを生成します。
透明度opacity が 未満のような値でも新しい階層が作られます。
変形transform が none 以外scale や rotate などを含むすべての変形が対象です。
合成filter や backdrop-filter が none 以外ぼかしや色調補正などのフィルタ効果です。
特殊isolation: isolate強制的に新しいコンテキストを作成する明示的な指定です。
最新container-type が設定されているコンテナクエリの使用時に生成されます。

特に、opacity や transform は意図せず重なり順のルールを書き換えてしまうことが多いため、デバッグの際にはこれらのプロパティが先祖要素に含まれていないかを確認することが重要です 。

isolation: isolate プロパティによる階層の隔離

複雑なUIコンポーネントを設計する際、コンポーネント内部の z-index 設定が外部のレイアウトに干渉したり、逆に外部の影響で内部の表示が崩れたりすることがあります。このような「z-indexの汚染」を防ぐための強力な武器が isolation プロパティです 。

●役割とメリット

isolation: isolate; を指定された要素は、その内部で完結する新しい重ね合わせコンテキストを強制的に生成します 。これにより、その要素の子要素たちは、親要素の外側にある要素と直接 z-index を競い合うことがなくなります 。

例えば、ボタン要素の中にアイコンがあり、そのアイコンを z-index: -1; でボタンの背景の下に隠しているとします。このボタンを他の要素の上に重ねた際、isolation が指定されていないと、アイコンがボタンを突き抜けて「ページの背景」まで沈み込んでしまうことがあります 。ボタン自体に isolation: isolate; を設定することで、アイコンの -1 は「ボタンというグループの中での最背面」として隔離され、安全にボタン内部に留まることができます 。

デザインシステムにおける z-index の管理戦略

プロジェクトが大規模になるにつれ、z-index: 100; や z-index: 9999; といった「マジックナンバー(意味不明な数値)」がソースコード中に散在するようになります。これはメンテナンス性を著しく低下させ、予期せぬ表示崩れの原因となります 。プロフェッショナルな現場では、以下のような管理手法が取り入れられています。

CSS変数(カスタムプロパティ)による集約管理

重なり順の定義を一つの場所にまとめ、意味のある名前を付けて変数化する手法が非常に効果的です 。これにより、サイト全体の階層構造を俯瞰して把握することが可能になります。

css

:root {
  /* 基本レイヤー */
  --z-index-base: 0;
  --z-index-above: 1;
  
  /* コンポーネント用レイヤー(10刻みで定義) */
  --z-index-sticky: 100;
  --z-index-dropdown: 200;
  --z-index-overlay: 300;
  --z-index-modal: 400;
  --z-index-tooltip: 500;
}

.main-header {
  position: sticky;
  z-index: var(--z-index-sticky);
}

このように変数を使用することで、「どの要素がどの要素の上にくるべきか」という設計意図が明確になり、後から数値を微調整する際も一箇所の変更ですべての要素に反映させることができます 。

スケール設計のベストプラクティス

値を飛ばして定義する: のように連続した数値を使うのではなく、 や のように間隔を空けて定義します。これにより、後から「ヘッダーとモーダルの間に通知バーを入れたい」といった要望が出た際、既存の建物を壊さずに隙間へ要素を滑り込ませることができます 。

セマンティックな命名: 数値そのものではなく、--z-index-modal や --z-index-toast のように役割に応じた名前を付けます 。

ローカルコンテキストの活用: コンポーネント内部の微細な重なり(ボタン内のアイコン等)には 小さな値を使い、それを isolation: isolate; で包み込みます。一方で、グローバルな要素(ナビゲーション、ダイアログ等)には 100 以上の大きな値を割り当てることで、局所的な変更が全体に悪影響を及ぼさないようにします 。

最上位レイヤー(Top Layer)と最新のブラウザAPI

近年、ウェブ標準には「最上位レイヤー(Top Layer)」という画期的な仕組みが導入されました。これは、従来の z-index による数値の競い合いを根本から解決するものです 。

Popover API と showModal() の挙動

HTMLの popover 属性を使用した要素や、JavaScriptの showModal() メソッドで呼び出された \<dialog> 要素は、自動的にこの「最上位レイヤー」へと昇格します 。

絶対的な優先順位: 最上位レイヤーに配置された要素は、ドキュメント内の他のいかなる要素(たとえ z-index: 2147483647; が指定されていても)よりも常に手前に表示されます 。

スタッキングコンテキストの脱出: これらの要素は親要素の overflow: hidden; や z-index の制限を完全に無視し、ビューポート全体を基準として描画されます 。

この仕組みの登場により、これまで開発者が苦労してきた「モーダルが親要素の重なり順に負けて隠れてしまう」という問題は過去のものとなりました 。

ブラウザ開発者ツールによるデバッグ技術

重なり順の問題が発生した際、コードだけを見て原因を特定するのは非常に困難です。主要なブラウザの開発者ツール(DevTools)には、視覚的に階層構造を分析するための強力な機能が搭載されています 。

3Dビューによる階層の可視化

ChromeやEdgeの開発者ツールでは、ウェブページを三次元的に傾けて表示し、どの要素がどの高さにあるのかを立体的に確認できます 。

1. ブラウザで右クリックして「検証」を選択し、デベロッパーツールを開きます 。

2. 「その他のツール(三点リーダー)」から「Layers」または「3D View」を選択します 。

3. 「Z-index」タブをクリックすると、重ね合わせコンテキストのツリーが3Dキャンバス上に表示されます 。

4. マウスで画面を回転させることで、特定の要素が新しいコンテキストを作っている様子や、要素同士の物理的な距離感を確認できます 。

Z-indexタブでの数値確認

デベロッパーツールの「Elements」パネル内にある「Z-index」タブを使用すると、現在ページ内で z-index が指定されている要素の一覧を、値の大きい順に並べて表示できます 。どの要素が原因で重なり順が乱れているのか、数値の重複やマジックナンバーの存在を即座に特定するのに役立ちます 。

z-index が効かない時のトラブルシューティング

問題が発生した際には、以下のチェックリストを順に確認してください 。

確認項目解決策
position は設定されているかstatic(初期値)以外の値が指定されているか確認します。
先祖要素に opacity 等はないか親やその上の要素が新しい重ね合わせコンテキストを作っていないか調査します。
z-index の値は適切か整数値(単位なし)で記述されているか確認します。
HTMLの記述順はどうなっているかz-index が同じ場合、後に書かれた要素が優先されます。
属性のタイポはないかzIndex(JavaScript)と z-index(CSS)の書き分けに注意します。

また、まれに transform: scale() などの変形処理によって z-index が無視されるような挙動を見せることがありますが、これは変形によって要素が自動的に新しい重ね合わせコンテキストのルートになるためです 。このような場合は、対象要素の親に対して z-index を適用し、階層構造そのものを再設計する必要があります。

結論と今後の展望

z-index プロパティは、単純な数字の大小を競う道具ではなく、ブラウザの描画パイプラインにおける「階層構造の宣言」です。初心者がこのプロパティを使いこなすためには、まず「位置指定が必要であること」という基本を定着させ、次に「重ね合わせコンテキスト」という見えない境界線の存在を意識することが不可欠です。

現代のウェブ開発においては、isolation: isolate; による安全な階層の切り出しや、CSS変数を用いた中央集約的な管理、および Popover API や Top Layer といった「z-index競争を終わらせる新しい仕様」を積極的に活用することが求められています 。さらに、将来的には「CSS Anchor Positioning」などの新しい配置技術が普及することで、要素同士を関連付けながら重なりを制御する手法はより宣言的で簡潔なものへと進化していくでしょう。本稿で解説した原理原則を理解することで、どのような複雑なデザイン要求に対しても、予測可能でメンテナンス性の高いスタイリングを実現できるはずです。

参考資料

1. Using z-index - CSS: Cascading Style Sheets | MDN, https://developer.mozilla.org/ja/docs/Web/CSS/Guides/Positioned_layout/Using_z-index

2. Understanding z-index - CSS: Cascading Style Sheets | MDN, https://developer.mozilla.org/ja/docs/Web/CSS/Guides/Positioned_layout/Understanding_z-index

3. z-index の競合を isolation: isolate で解決する, https://zenn.dev/zozotech/articles/d988276f3902eb

4. z-index を設定した親要素に isolation: isolate; をする, https://tech.basicinc.jp/articles/170

5. z-index の値があるものとないものとを比べた時, https://ics.media/entry/200609/

6. z-index のルール:コンポーネントのルートには isolation: isolate を指定する, https://zenn.dev/zozotech/articles/7609d2c7af30df

7. テクニック:スタックを切ることで意図的にレイヤー独立させる, https://qiita.com/CRUD5th/items/3d6605e8a4ab4071efb7

8. Chromeの開発者ツールでshow layerを選択すると立体的にz-indexを考慮したレイヤーが見れる, https://qiita.com/msht0511/items/09b061bc1bc6243b8379

9. 「DevTools z-index」でz-indexがかかっている要素をChromeで確認する, https://webrandum.net/devtools-z-index/

10. 検証ツールのレイヤ機能を活用すればWebページの全体を俯瞰できる, https://noveltyinc.jp/media/show_layer

11. Chrome開発者ツール:Layersで立体的にサイトを見る, https://webrandum.net/z-index-management/

12. Chromeデベロッパーツールの起動方法とショートカット, https://willcloud.jp/knowhow/dev-tools-01/

13. CSS isn't that simple — CSS positioning, transformation, containment, and other features can cause elements to overlap, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Understanding_z-index

14. The z-index property in CSS controls how elements stack on top of each other, https://penpot.app/blog/understanding-the-z-index/

15. CSS z-index explained: Stop the stacking chaos - manage layers like a pro, https://dev.to/satyam_gupta_0d1ff2152dcc/css-z-index-explained-stop-the-stacking-chaos-manage-layers-like-a-pro-1fcj

16. Modern z-index management: Evolving a classic Sass pattern, https://medium.com/@mevbg/modern-z-index-management-evolving-a-classic-sass-pattern-0042724da65c

17. What z-index value should you use? - Strategies and stacking contexts, https://www.ltvco.com/engineering/what-z-index-value-should-i-use/

18. z-index CSS property reference, https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/z-index

19. Using z-index: Layers on the z-axis, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Using_z-index

20. Tailwind CSS z-index utilities, https://tailwindcss.com/docs/z-index

21. How to better set z-index for elements using JavaScript, https://medium.com/geekculture/how-to-better-set-zindex-for-elements-f8d6277ae280

22. CSS z-index: A guide to stacking context and isolation, https://www.diaconou.com/blog/css-z-index-a-guide/

23. Stacking context details and rendering order, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Stacking_context

24. z-index not working in CSS - Identifying common issues, https://medium.com/@sableconfusion/z-index-not-working-in-css-6c63b5db4a8c

25. CSS Stacking Context best practices, https://favourcodes.com/writings/css-stacking-context

26. CSS isolation Property - forced creation of a new stacking element, https://www.geeksforgeeks.org/css-isolation-property/

27. Use the 3D View tool to debug z-index stacking issues, https://learn.microsoft.com/en-us/microsoft-edge/devtools/3d-view/

28. Chrome Developer Tools guide for layout debugging, https://www.browserstack.com/guide/chrome-developer-tools

29. Debug JavaScript using breakpoints in Chrome DevTools, https://developer.chrome.com/docs/devtools/javascript

30. Chrome DevTools for beginners - freeCodeCamp, https://www.freecodecamp.org/news/chrome-devtools/

31. z-index の使い方:CSSで重なり順を指定する | サルワカ, https://saruwakakun.com/html-css/basic/z-index

32. z-indexの管理にCSS変数を利用するメリット, https://css-tricks.com/handling-z-index/

33. The top layer is guaranteed to be the top-most layer above any other stacking context, https://www.htmhell.dev/adventcalendar/2025/1/

34. Place an element above the top layer - Stack Overflow, https://stackoverflow.com/questions/75509725/place-an-element-above-the-top-layer

35. Popover API lands in Baseline, https://web.dev/blog/popover-api

36. Popover API and CSS Anchor Positioning, https://www.oidaisdes.org/popover-api-accessibility.en/

37. Using CSS anchor positioning, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Anchor_positioning/Using

38. CSS anchor positioning module reference, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Anchor_positioning

39. The Painters Algorithm and stacking contexts, https://css-tricks.com/almanac/properties/z/z-index/

40. Anchor Positioning: The problem and the CSS solution, https://ishadeed.com/article/anchor-positioning/

41. MDN CSS positioned layout module guide, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Using_z-index

42. The z-index problem: Misunderstanding stacking contexts, https://medium.com/@ss-tech/the-z-index-problem-91226fb74955

43. Introduction to the CSS cascade and layers, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascade/Introduction

44. Complete guide to CSS cascade layers, https://css-tricks.com/css-cascade-layers/

45. CSS modern stacking context updates 2024-2025, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Stacking_context

46. CSS Snapshot 2025 - W3C Working Group Note, https://www.w3.org/TR/css-2025/

47. New CSS features in 2025 you should know, https://www.augustinfotech.com/blogs/css-in-2025-new-css-features-you-should-know/

48. Latest CSS features in 2024-2025, https://dev.to/prathamisonline/latest-css-features-in-2024-2025-whats-new-and-exciting-3ojj

49. Centralize Your Global Z-Index Scale, https://dev.to/satyam_gupta_0d1ff2152dcc/css-z-index-explained-stop-the-stacking-chaos-manage-layers-like-a-pro-1fcj

50. Understanding the integer values of the z-index property, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Understanding_z-index

51. Layering and Stacking in CSS Grid, https://codefinity.com/courses/v2/fbdb2224-63e2-41d9-95ee-5c6ae2f88561/40d64c28-cebf-40a5-9369-8ba42e085305/0f222c31-9226-479f-8e98-9d10bc67cb99

52. Understanding z-index stacking order - Stack Overflow, https://stackoverflow.com/questions/32513540/understanding-z-index-stacking-order

53. Stacking elements: CSS z-index and stacking context explained, https://netgen.io/blog/stacking-elements-css-z-index-and-stacking-context-explained

54. Shopify theme z-index management for specific sections, https://community.shopify.com/t/z-index-for-specific-section/374453

55. Sassy z-index management for complex layouts, https://www.smashingmagazine.com/2014/06/sassy-z-index-management-for-complex-layouts/

56. Issues with Shopify App Bridge Modal z-index, https://community.shopify.dev/t/issues-with-shopify-app-bridge-modal-z-index-and-splide-autoscroll/17941

57. transform:scale() breaking my z-index order - Stack Overflow, https://stackoverflow.com/questions/35681829/transformscale-breaking-my-z-index-order

58. Polaris React z-index stacking order issues, https://github.com/Shopify/polaris-react/issues/37

59. Wikimedia Codex design tokens for z-index, https://doc.wikimedia.org/codex/latest/design-tokens/z-index.html

60. U.S. Web Design System z-index tokens, https://designsystem.digital.gov/design-tokens/z-index/

61. IBM Carbon Design System color tokens and layering, https://carbondesignsystem.com/elements/color/overview/

62. IBM Carbon Design System spacing and stacking, https://carbondesignsystem.com/elements/spacing/overview/

63. Migrating to Carbon v11 - token naming updates, https://carbondesignsystem.com/migrating/faq/

64. isolation | CSS-Tricks Almanac, https://css-tricks.com/almanac/properties/i/isolation/

65. isolation CSS property reference | MDN, https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/isolation

66. Stacking contexts are treated atomically, https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Positioned_layout/Stacking_context

67. Fix any CSS z-index issue with this one trick: isolation, https://dev.to/railsdesigner/fix-any-css-z-index-issue-with-this-one-trick-387c

コメント

タイトルとURLをコピーしました