何かと問題を起こしやすい z-index について調べる機会があったので  まとめました。
  要素を意図した通りの重なり順序で表示するには、根本から理解しておいた方が、結果的に早道なのではないかと思います。
この記事は W3C  の勧告を元に書きましたが、z-index  はブラウザによってバグ等の理由で挙動が違うこともあるようなのでご注意ください。
  前提
    これはすでにご承知と思いますが、念のため。
  §   要素の重なり順序は、基本的にマークアップした順に奥から手前になります。
  親より子供が手前であり、兄弟ならば  あとからマークアップした要素が手前に表示されます。
  これを踏まえつつ、z-index  を指定した場合を考えていきます。
  スタック  レベルとスタック  コンテキスト
    スタック  レベルとは、要素の重なり順序を決める値です。
  z-index は、要素のスタック  レベルを指定するプロパティです。
  スタック  コンテキストとは、z-index  を指定した要素をベースとする、子孫要素の集合を指します。その子孫要素たちは、「同じスタック  コンテキストに所属している」と表現します。
  ルート要素(html  要素)は z-index  を指定しても  しなくても、ルート  スタック  コンテキストを生成します。そのため、どの要素も初期状態ではルート  スタック  コンテキストに所属します。
  ルール
    §   z-index  を指定していない要素のスタック  レベルはゼロです。(z-index: auto;  の指定と同等)
  §   z-index  を指定すると、スタック  レベルをゼロ以外に設定できます。
  同時に、z-index  を指定した要素をベースとする、新しいスタック  コンテキストが生成されます。
  (これがクセモノです)
  §   つまり、z-index: 0;  と z-index: auto;  は、スタック  レベルはどちらもゼロですが、スタック  コンテキストが生成されるか  されないかの大きな違いがあります。
  §   要素は、同じスタック  コンテキスト内でスタック  レベルが大きいほどマークアップ順序を無視して手前に表示されます。
  §   z-index  は、あくまで「同じスタック  コンテキスト内」の重なり順序の指定であることに注意です。
  違うスタック  コンテキスト内の要素に対しては重なり順序を指定できません。
  ルールの詳細
    上記のルールを図にしてみました。
  四角はスタック  コンテキスト、色は要素の親子関係を示しています。
  (親)  青 >  緑 >  黄  (子孫)
  div A  と div D、div   E と div F  はそれぞれ兄弟要素です。
  マークアップ順序はアルファベット順(html  〜 div A  〜 div F)と考えてください。
  div E  が破線なのは、z-index: auto;  の指定ではスタック  コンテキストが生成されないからです。
  §   div A  と div D  は、同じ html  のルート  スタック  コンテキストに所属していますので、z-index  が大きい div D  が手前に表示されます。
  §   div A  より div B  の z-index  は小さいですが、div B  が手前に表示されます。なぜなら、div B  は div A  とは違うスタック  コンテキストに所属しているからです。(div B  の所属は div A  のスタック  コンテキスト、div A  の所属は html  のルート  スタック  コンテキストです)
  所属するスタック  コンテキストが違う場合には、基本的にマークアップ順序による重なり順序になります。
  §   div F  は div E  より  あとにマークアップされていますが、div F  が奥に表示されます。div E  と div F  が所属する div D  のスタック  コンテキストにおいて、div F  の方が z-index  が小さいからです。
  (z-index: auto;  のスタック  レベルはゼロであることを思い出してください)
  §   div C  はすべての中で最も大きな z-index  が指定されていますが、div D  とその子孫要素より奥に表示されます。なぜなら、div C  が所属しているのは div B  のスタック  コンテキストだからです。
  §   div C  を最も手前に表示させたいなら、例えば div A  と div B  の z-index  指定を消去します。
  (div A  と div B  の z-index  指定を消去すると、div C  の所属するスタック  コンテキストは html  のルート  スタック  コンテキストになります。同じルート  スタック  コンテキストに所属する div D  より div C  の方が z-index  が大きいので手前に表示されます)
  さらなるルール
    これで重なりの順序は自由自在?
  いいえ、残念ながら  あなたを更に混乱させる情報をお伝えしなければなりません。
  §   z-index  の指定を有効にするためには、position  を static  以外にする必要があります。
  また、position  を   static 以外にすると、z-index  を指定しなくても、その要素をベースとした新しいスタック  コンテキストが生成されます。
  §   opacity を指定した要素も同様にスタック  コンテキストが生成されます。
  §   transform を指定した要素も同様にスタック  コンテキストが生成されます。
  §   z-index  を指定しない場合、スタック  レベルはどの要素もゼロです。
  スタック  レベルが同じとき、スタック  コンテキストのベースになっている要素は、マークアップ順序を無視して、そうでない要素より手前に表示されます。
  position: fixed; を指定した要素が  しばしば最も手前に表示されるのはこれが理由です。
  ベスト  プラクティス
    z-index  が効かない! 重なり順序が思った通りにならない!
  そんなときには、以下を試してみましょう。
  §   z-index  を指定する要素を必要最小限にしてみる
  §   position  の指定を消去して(static  にして)位置調整は padding  や margin  にしてみる
  §   いったん opacity  や transform  の指定を消去してみる
  §   ブラウザによって重なり順序が違うようならバグを疑ってみる
  参考サイト
    以下のサイトも詳しく解説されています。
  §   要素の重なりについて本気出して考えてみた(z-indexとか何とかとか)   — No.1026
  ちなみに、昨今CSS3なるものが流行していますが、この記事はW3CのCSS2.1勧告(と付録)を元に書いています。
  と書かれていますが、調べてみたところ、CSS3  の勧告草案と CSS2.1  の勧告は、z-index  の記述部分について現状、大差がないようです。
  以下のサイトは、z-index  も含めて  すべての重なり順序の詳細が説明されています。
  「コンテキスト」が「文脈」と直訳されてしまっているので少し注意です。
  §   CSSでレイアウトするなら絶対覚えておきたい配置のルール:フロートや絶対配置、z-index  とかいろいろ
  以下は関連する W3C  の勧告と、日本語情報のページです。
  §   Elaborate   description of Stacking Contexts(英語)
  §   CSS   Positioned Layout Module Level 3(英語)
  §   Elaborate   description of Stacking Contexts – CSS 2.1 spec (ja)
  §   CSS3の日本語訳集   – 血統の森   web実験小屋
  (CSS Positioned Layout Module Level 3  の日本語版はないようです…)


 
0 件のコメント:
コメントを投稿