ワイ「z-index完全に理解した」

# ある日の我が家
娘「ねぇ、パパ！」

ワイ「おお、なんや？娘ちゃん」

娘「HTMLとCSSで**ダイアログ**を作る方法を教えて欲しいの！」

ワイ「おお、ええでぇ」
ワイ「ちょうど今、ワイの個人ブログを作ってるところでな」
ワイ「これからダイアログを作るから、やり方を見せてあげるでぇ」

娘「わ〜い、ありがとう！」
娘「わたし、`z-index`がうまく使えなくて困ってたの！」

ワイ「おぉ、パパに任せとき！」
ワイ「パパは`z-index`を**完全に理解**してるからな！」

# `z-index`完全理解ワイ、説明開始

ワイ「今、こんなサイトを作ってるんやけどな？」

<img width="373" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/e0efefa3-ae80-4dae-b6ed-00ba520cdc16.png" alt="スクリーンショット">

ワイ「↑このサイトにダイアログを表示できるようにしたいんや」

> 「記事の投稿が完了しました。」

ワイ「↑こういうメッセージを表示するためのダイアログや」

娘「なるほどね」

ワイ「ほな、コードを書いていくで」
ワイ「まず、現状のコードは──」

```diff_html
<body>
  <header>
    <h1>やめ太郎のサイト</h1>
  </header>
  <main>
    <section>
      <h2>記事一覧</h2>
      <ul>
        <li>
          <article>
            <h3>記事タイトル</h3>
            <p>記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。</p>
          </article>
        </li>
<!-- 〜以下省略〜 -->
```

ワイ「↑こんな感じや」
ワイ「ここに、ダイアログ用のHTMLを追加するで」

```diff_html
<body>
  <header>
    <h1>やめ太郎のサイト</h1>
  </header>
  <main>
+   <div id="dialog-area">
+     <p>z-index完全に理解した。</p>
+   </div>
    <section>
      <h2>記事一覧</h2>
      <ul>
        <li>
          <article>
            <h3>記事タイトル</h3>
            <p>記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。記事の内容。</p>
          </article>
        </li>
<!-- 〜以下省略〜 -->
```

ワイ「↑こうやな」
ワイ「そんで、次はCSSを書くで」

```diff_css
    #dialog-area {
+     position: fixed;
+     z-index: 1;
      padding-top: 57px;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba(0, 0, 0, 0.3);
    }
```

ワイ「↑こうや」
ワイ「ほな、ブラウザで動作確認してみるで！」



<img width="373" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/6c41d20c-57d9-a389-98ec-7a310043a268.png" alt="スクリーンショット">

**ワイ「ファッ！？」**

娘「ダイアログが、ヘッダの後ろ側になっちゃってるね」

ワイ「せやな・・・」

娘「文字も10%くらい隠れちゃってる」

ワイ「ああ・・・」
ワイ「10%くらい隠れてもうてるってことは」
ワイ「**90**%くらいしか`z-index`を理解できていなかったみたいや・・・」

娘「そうだね・・・」

よめ太郎「（そうなのか・・・！？）」

# 原因を探して行く

娘「あ、パパ！」
娘「分かったかも！」

```diff_css
    header {
      position: fixed;
      z-index: 10;
      /* 〜省略〜 */
    }
```

娘「↑ヘッダ部分の`z-index`が`10`になってるでしょ？」
娘「そして──」

```diff_css
    #dialog-area {
      position: fixed;
      z-index: 1;
      /* 〜省略〜 */
    }
```

娘「↑ダイアログ部分の`z-index`が`1`になってる！」
娘「ここが原因じゃない？」

ワイ「おお、さすが娘ちゃん！」
ワイ「ほな、ダイアログ部分の`z-index`を`11　`にしたるで！」


```diff_css
    #dialog-area {
      position: fixed;
-     z-index: 1;
+     z-index: 11;
      /* 〜省略〜 */
    }
```

ワイ「↑こうやな！」
ワイ「ほな、もう一回ブラウザで動作確認してみるで！」

<img width="373" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/6c41d20c-57d9-a389-98ec-7a310043a268.png" alt="スクリーンショット">

ワイ「ぐぬぬ・・・」
ワイ「なんでや・・・」
ワイ「ワイは`z-index`を完全に理解したはずなのに・・・！」

娘「パパ、仕方ないよ・・・！」
娘「きっと、**完全に理解した期**の後の」
娘「**なんも分からん期**に突入したんだよ！」

ワイ「おお、そういうことか・・・」
ワイ「ワイもまた一歩、成長したんやな！」

**よめ太郎「いや何でやねん」**
よめ太郎「まだ何も理解できてないだけやろ」

ワイ「Oh・・・」
ワイ「せやな・・・」

# よめ太郎氏、解説開始

よめ太郎「`z-index`はな」
よめ太郎「**親要素どうしの戦い**で負けてたらアカンねん」

ワイ「親要素どうしの戦い・・・どういうこと？」

よめ太郎「今回の例でいうと──」

```diff_html
<body>
  <header>
    <h1>やめ太郎のサイト</h1>
  </header>
  <main>
    <div id="dialog-area">
      <p>z-index完全に理解した。</p>
    </div>
    <section>
      <h2>記事一覧</h2>
<!-- 〜以下省略〜 -->
```

よめ太郎「↑こう、`header`要素と`main`要素が**兄弟**になってるやん」

ワイ「せやな」

よめ太郎「そんで──」


```diff_css
    header {
      position: fixed;
      z-index: 10;
      /* 〜省略〜 */
    }
```

よめ太郎「↑こう、`header`要素の`z-index`が`10`になってて」

```diff_css
    main {
      position: relative;
      z-index: 0;
      /* 〜省略〜 */
    }
```

よめ太郎「↑こう、`main`要素の`z-index`が`0`になっとる」
よめ太郎「これが原因や」

ワイ「つまり、どういうこと・・・？」

よめ太郎「つまりな──」

- `header`要素・・・`z-index: 10`
- `main`要素・・・`z-index: 0`
    - `main`要素の子要素であるダイアログ部分も、`header`要素に勝てない

よめ太郎「↑こういうことや」

ワイ「なるほど・・・！」
ワイ「`親要素どうしの戦いで負けてたらアカン`っていうのは」
ワイ「こういう意味だったんか・・・！」

娘「そっか！」
娘「じゃあ、こうすればいいんだね！」

```diff_html
<body>
  <header>
    <h1>やめ太郎のサイト</h1>
  </header>
+ <div id="dialog-area">
+   <p>z-index完全に理解した。</p>
+ </div>
  <main>
-   <div id="dialog-area">
-     <p>z-index完全に理解した。</p>
-   </div>
    <section>
      <h2>記事一覧</h2>
<!-- 〜以下省略〜 -->
```

娘「↑ダイアログ部分を、`main`要素の外に出して」
娘「`header`と兄弟になるようにしてみたよ！」

ワイ「おお」

娘「`z-index`の数値は──」

```diff_css
    header {
      position: fixed;
      z-index: 10;
      /* 〜省略〜 */
    }
```

```diff_css
    #dialog-area {
      position: fixed;
      z-index: 11;
      /* 〜省略〜 */
    }
```

娘「ダイアログ部分の方が大きくなってるから、これでいいんじゃない！？」

ワイ「よっしゃ、ブラウザで見てみよか！」

<img width="373" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/ed6cfd72-37ea-25e9-febd-17d14f49319f.png" alt="スクリーンショット">

ワイ「おお、ええ感じや！」
ワイ「これがやりたかったんや！」

# まとめ

- 親要素どうしの`z-index`争いで負けていると、その子要素も負けてしまう
    - 負けないためには
        - 自分の親要素が`z-index`争いで負けないようにする
        - もしくは自分自身が兄弟要素になって`z-index`争いで勝つ

娘「こういうことだね！」

ワイ「せやな！」
ワイ「ダイアログみたいに最前面に表示したい要素は、`body`直下とかに書くのがええかもな！」

よめ太郎「せやな」
よめ太郎「出来るだけ外側のHTMLタグになって、親要素どうしの勝敗に左右されん方がええよな」
よめ太郎「Reactだったら**ポータル**とか」
よめ太郎「Vueだったら**Teleport**（PortalVue）を使うと」
よめ太郎「要素を外側に配置できるからいいよな」

ワイ「おお〜、なるほど」

よめ太郎「あと、`z-index`を指定する場合は、`position`の指定も忘れずにな」
よめ太郎「`position`を指定しなかった場合は、初期値の`position: static;`扱いになってしまうからな」
よめ太郎「`position: static;`の状態で`z-index`を指定しても、**効かへんねん**」
よめ太郎「`relative`とか`absolute`とか`fixed`とか`sticky`、そういうのを指定せなあかんねん」

ワイ「おお、そういえばせやったな」

娘「ママ、すご〜い！」

# その日の夜

ワイ「いや〜、今日も勉強になったわ」
ワイ「ワイ、また成長してもうたで」
ワイ「**完全に理解した** を超えて」
ワイ「**なんも分からん** も超えて」
ワイ「**チョットデキル** に到達してしまったかもしれんわ！」

娘「わ〜い！」
娘「パパ、CSSチョットデキル！チョットデキル！」

よめ太郎「いやリアルに**ちょっとできる**だけやん」

**〜おしまい〜**