困った時のz-index:9999から抜け出す方法

この記事はAteam Brides Inc. Advent Calendar 2019　14日目の記事です。

本日はWebデザイナーの@naomunaomuが担当いたします。

今回のお題はみんな大好きなz-indexについてです。
ハンバーガーメニューや、パララックスを制御するなど、レイアウトの順序を並び替えるのに便利ですよね:relaxed:

## 困ったらとりあえずz-index:9999にしていませんか？

はい、私はしていました・・
`z-index:9999` とか、`z-index:10000` とか、やっていました。
え？1から9999までの間の数字は全部使ってるかって？
ええ、**当然使っていません。**

## カオスなz-index管理の末路
そんなざっくりした運用を続けると、どうなるかというと・・
![スクリーンショット 2019-12-13 18.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321220/9c572606-48ef-d6be-047b-a305a9654d08.png)

![image (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321220/ff08ec33-94c5-7928-6235-fee33e881367.jpeg)


**クリックボタンがクリックできなくなります**

「しまった、z-indexをどこに何回使ってるかわからない・・」
「z-index:999まで使ってったっけ・・えーい、9999でいけるはず！」
「あれ、変わらないぞ・・・？」

## なぜこんなことが起きるのか

この問題には2つの原因があります。

1.スタックコンテキストへの理解
2.スタックレベルの乱用

### 1.スタックコンテキストへの理解
![スクリーンショット 2019-12-14 0.05.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321220/23379859-9d9b-9f8b-65bb-7c5e0f7099bb.png)


z-indexは、`z-index:値`の値（スタックレベル）に入る数字が大きい方が、重なり順が上に表示されます。

今回の例でいくと、後ろになってしまったクリックボタンは`z-index:9999;`、アイコンたちは`z-index:999;`です。
数値だけ見れば、クリックボタンの方が上にきそうですよね。

ここで問題になるのが、z-indexを記述しただけでは、重なり順は変わらないということです。

CSSには**スタックコンテキスト**という概念があります。

#### スタックコンテキストとは?
ざっくり言うとauto以外のz-indexと、static以外のpositionを指定した要素同士は重なり順が指定できるよ、というものです。
逆に言えば、それらを指定しなければz-indexは指定できないのです。

詳しくはこちらの記事が参考になりますので、ぜひご覧ください。
[[CSS] z-index とスタックコンテキスト - Qiita](https://qiita.com/hoto17296/items/42e62989193504d512c7)

もし、「いやいや、z-indexとposition、ちゃんと設定してるのに、重なり順が変わらないよ・・＞＜」となる場合、
**z-indexを指定したい要素同士が、入れ子になっている親要素にも、positionとz-indexを指定**されているか確認してみましょう。

![スクリーンショット 2019-12-13 19.19.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321220/d8fbef5c-aedb-a6df-6ca4-413782c24618.png)

### 2.スタックレベルの乱用
`z-index:値`の値のことを**スタックレベル**と言います。
こちらを無秩序に使っていることが、今回の根本的な問題だと考えました。

スタックコンテキストを理解していても、
「しまった、z-indexをどこに何回使ってるかわからない・・」
上記は解決できないからです。
「とりあえず、困ったら`z-index:9999`で」
いやいや、`z-index:9999`、何回使うんじゃい、と。

## 今すぐz-index:9999を辞めるために検討したこと

次の3点から対応策を考えました。

1.ライブラリ、ツールの導入
2.Sassで一元管理
3.デザインガイドラインの制定

3の場合、運用でカバーする状況は極力避けたいので、
今後1,2で対応できた場合、その仕様を掲載しようかと思います。

### 1.ライブラリ、ツールの導入

#### Hide chrome frame in Layers view
弊社エンジニアが調べてくれました！:clap:

![スクリーンショット 2019-12-13 22.24.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321220/968de302-04ff-6fbd-e0b1-aeb48532dc0c.png)

Chromeの検証ツールでサイトのレイヤー構造が3Dで確認できます。
デフォルトでは表示されないため、検証ツール右側のメニューボタン＞More tools＞Layersで表示してください。

３Dが面白くてぐるぐる遊びました笑が、今回のミッションであるスタックレベルの確認には使えないかな・・と、断念

### 2.Sassで一元管理
mixinでいい感じに作れないかなと調べていたところ、
こちらの記事が非常にわかりやすく参考になりました！
[Sassy Z-Index Management For Complex Layouts — Smashing Magazine](https://www.smashingmagazine.com/2014/06/sassy-z-index-management-for-complex-layouts/)
[Sassを使ったz-indexの管理 - Qiita](https://qiita.com/kojika17/items/b4694e3afe0da97e6335)

Sassのindex関数でスタックレベルを管理します。

まずサイト上で必要になる要素を作成します。

```
//必要になる要素の洗い出し
$elementes:(
  header,
  navigation,
  modal
)
```
設定した要素にindex番号を付与することで、設定した要素に上から1,2,3..とスタックレベルを割り振ることができます。

```
//index関数で呼び出し
@function z-index($name){
  @return index($elementes,$name)
}

//呼び出し
.header {
  z-index: z-index(header);//1
}

.navigation {
  z-index: z-index(navigation);//2
}

```
非常に便利ですね！
Sassのベースファイルに要素の配列とfunctionまで記述しておけば、
z-indexがどこに使われているのかすぐに確認できます。
これで困った時の`z-index:9999;`から卒業できそうです:raised_hands:

## おまけ：z-indexの落とし穴
スタックコンテキストを正しく記述しているにも関わらず、z-indexとpositonがうまく機能しない事例があり、しばらくはまっていました・・

### transformなどのプロパティを設定するとずれる
同じ要素としてtransformのプロパティを設定した場合、transformのz軸で設定した値に依存してしまい、想定した要素の位置とはずれてしまいました。
この場合、transformプロパティを削除するか、該当の要素を`<div>`などでラップし、こちらにtranfromのz軸を指定することで対応できます。

## まとめ
困った時のz-index:9999から抜け出す方法、いかがでしたか？
煩雑になりがちなz-indexを意識的に管理することで、みなさんの素敵なデザインを実現していってください！:clap:

# 私たちのチームで働きませんか？
![alt](https://brides.a-tm.co.jp/wp-content/uploads/2019/11/ATEAM_BRIDES.jpg)
[エイチーム](https://www.a-tm.co.jp/)は、インターネットを使った多様な技術を駆使し、幅広いビジネスの領域に挑戦し続ける**名古屋の総合IT企業**です。
そのグループ会社である**株式会社エイチームブライズ**では、一緒に働く仲間を募集しています！

- [ハナユメ サイト開発グループ](https://jobs.qiita.com/employers/brides-a-tm/development_teams/138)
- [HIMARI開発チーム](https://jobs.qiita.com/employers/brides-a-tm/development_teams/147)
- [技術開発部](https://jobs.qiita.com/employers/brides-a-tm/development_teams/148)

上記求人をご覧いただき、少しでも興味を持っていただけた方は、まずは**チャットでざっくばらんに話**をしましょう。
技術的な話だけでなく、私たちが大切にしていることや、お任せしたいお仕事についてなどを詳しくお伝えいたします！

[Qiita Jobs](https://jobs.qiita.com/)よりメッセージお待ちしております！