z-indexが言うことを聞いてくれない場合はこの辺のことが原因だと思うよ

z-indexをつかって要素の順番を変えていたのですが、どうにも思った通りにいかないことがありました。
今回はそんなハマったパターンになります。


## 親子関係になっているタグで親要素に `z-index: auto` 以外の値を指定した場合

<img width="282" alt="スクリーンショット 2017-06-12 18.59.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/db487a70-f3ee-7c26-febf-f55759f03056.png">

```html
<html>
  <head>
    <title></title>
    <style type="text/css">
      .parent {
        padding-top: 20px;
        padding-left: 20px;
        width: 100px;
        height: 100px;
        background-color: #ff0000;
        position: relative;
        z-index: 2;
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: #ff9999;
        position: absolute;
        top: 60px;
        left: 60px;
        z-index: 1;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      z-index 2
      <div class="child">z-index 1</div>
    </div>
  </body>
</html>
```

## 疑似要素を設定している状態で要素に`z-index: auto`以外を指定した場合

<img width="281" alt="スクリーンショット 2017-06-12 19.09.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/34f6c04a-17fb-c13b-091e-e1164f7a19fe.png">

```html
<html>
  <head>
    <title></title>
    <style type="text/css">
      .parent {
        padding-top: 20px;
        padding-left: 20px;
        width: 100px;
        height: 100px;
        background-color: #ff0000;
        position: relative;
        z-index: 2;
      }
      .parent:before {
        content: "before z-index: -1";
        width: 100px;
        height: 100px;
        background-color: #ff9999;
        position: absolute;
        top: 60px;
        left: 60px;
        z-index: -1;
        border: 1px solid #333;
      }

      .parent:after {
        content: "after z-index: -2";
        width: 100px;
        height: 100px;
        background-color: #ffdddd;
        position: absolute;
        top: 10px;
        left: 80px;
        z-index: -2;
        border: 1px solid #333;
      }
      }
    </style>
  </head>
  <body>
    <div class="parent">z-index 2</div>
  </body>
</html>
```
## 親要素にopacityをつけた場合

<img width="349" alt="スクリーンショット 2017-06-12 19.14.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/19ce87a8-2bf0-8070-62a1-feb33e75370e.png">

```html
<html>
  <head>
    <title></title>
    <style type="text/css">
      .parent {
        width: 100px;
        height: 100px;
        background-color: #ff0000;
        position: relative;
        opacity: 0.5;
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: #ff9999;
        position: absolute;
        top: 50px;
        left: 50px;
        z-index: -1;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      z-index 2
      <div class="child">z-index -1</div>
    </div>
  </body>
</html>
```

## 親要素にtransform指定した場合

<img width="262" alt="スクリーンショット 2017-06-13 19.13.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/6fe10c83-39bd-4231-4729-3156cadc509c.png">

```html
<html>
  <head>
    <title></title>
    <style type="text/css">
      .parent {
        width: 100px;
        height: 100px;
        background-color: #ff0000;
        position: relative;
        transform: rotate(-10deg);
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: #ff9999;
        position: absolute;
        top: 50px;
        left: 50px;
        z-index: -1;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      z-index auto
      <div class="child">z-index -1</div>
    </div>
  </body>
</html>
```


## 親要素にposition: fixed、position: stickyを指定した場合

<img width="281" alt="スクリーンショット 2017-06-13 19.21.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/4a1128bd-377e-6fe8-e3f9-a5c1b90c4f62.png">

```html
<html>
  <head>
    <title></title>
    <style type="text/css">
      .parent {
        margin: 20px;
        width: 100px;
        height: 100px;
        background-color: #ff0000;
        position: fixed;
      }
      .child {
        width: 100px;
        height: 100px;
        background-color: #ff9999;
        position: absolute;
        top: 50px;
        left: 50px;
        z-index: -1;
      }
    </style>
  </head>
  <body>
    <div class="parent">
      z-index auto
      <div class="child">z-index -1</div>
    </div>
  </body>
</html>
```

## なんでこうなるのか？

キーワードは**「スタックコンテキスト（スタック文脈）」**

z-indexについてのw3cの仕様を見てみると

> 位置指定されるボックスに対して、'z-index'プロパティは以下を指定する：
1. 現在のスタックコンテキストにおけるボックスのスタックレベル。
2. ボックスがスタックコンテキストを設置するかどうか。
値は次の意味を持つ：
**integer**
この整数値は、現在のスタックコンテキストにおける生成ボックスのスタックレベルである。ボックスはまた、新しいスタックコンテキストを設置する。
**auto**
現在のスタックコンテキストにおける生成ボックスのスタックレベルは0になる。ボックスが'position: fixed'である場合、またはボックスがルートである場合、ボックスはまた、新しいスタックコンテキストを設置する。


なるほど、わからん...


かいつまんでいうと、z-indexの指定は同じスタックコンテキスト内での順番（スタックレベル）を指定するものになるので、スタックコンテキストが違う場合は意図した通りに設定されない可能性があります。

スタックコンテキストを生成するパターンとして

- `position: relative`または`position: absolute`で `z-index: auto`以外を指定
- `position: fixed`または`position: sticky`を指定
- `opacity: 1`以外を指定
- `transform: none`以外を指定

この辺を指定した場合はz-indexが意図した通りにならない可能性があります！
`z-index: 0`と`z-index: auto`は意味が違うから気をつけて！

スタックコンテキストについては下記記事が詳しいよ
[z-index再入門](https://app.codegrid.net/entry/z-index-1)
[z-index とスタックコンテキスト](http://qiita.com/hoto17296/items/42e62989193504d512c7)