z-index のあれこれ

仕事で z-index プロパティを使う機会があったんですが、なんだか上手くいかなかった。いろいろ試行錯誤してようやく思い通りの動きをしてくれたので、ここに z-index プロパティの仕様を含めたまとめを書いてみる。

まずは z-index プロパティの仕様から。引用するのが面倒なので仕様書をそのまま見てください。

簡単に仕様をまとめると、

  • position プロパティで [fixed] [absolute] [relative] のいずれかの値を持つ要素(つまり [static] 以外の値)にのみ適用される
  • z-index プロパティの [auto] はボックスの重なり順が親要素と同じになる
  • [整数] は値が大きいほど値が小さいボックスよりも前面になり、小さいほど大きい値よりも背面に配置される
  • [整数] はマイナスの値も指定できる

以上のようになる。
これを踏まえたうえで以下のサンプルを作成してみる。

HTML ソース

<div id="zindex2">
z-index の値が 2<br />
要素の順番は 1
</div>

<div id="zindex1">
z-index の値が 1<br />
要素の順番は 2
</div>

<div id="zindex0">
z-index の値が 0<br />
要素の順番は 3
</div>

CSS ソース

div#zindex0 {
position: absolute;
top: 50px;
left: 180px;
z-index: 0;
width: 200px;
height: 200px;
background: yellow;
}

div#zindex1 {
position: absolute;
top: 80px;
left: 210px;
z-index: 1;
width: 200px;
height: 200px;
background: pink;
}

div#zindex2 {
position: absolute;
top: 110px;
left: 240px;
z-index: 2;
width: 200px;
height: 200px;
background: lime;
}

想定できる結果です。z-index プロパティの値が大きくなるほど前面に配置される。仕様通りの結果です。
では次にこうしたらどうなるだろうか。

HTML ソース

<div id="zindex2">
z-index の値が 2<br />
要素の順番は 1

<div id="zindex1">
z-index の値が 1<br />
要素の順番は 2

<div id="zindex0">
z-index の値が 0<br />
要素の順番は 3

</div>

</div>

</div>

つまり各要素を入れ子にしてしまう場合。そうすると先ほどとは表示結果が違うことが分かる。これは単純な話で、position プロパティが [absolute] の時、基点がサンプル 1 とサンプル 2 では違うからだ。

position CSS辞典 - position - 要素の配置方式を指定する

absolute
包含ブロック(祖先要素のうち、もっとも近い祖先の要素にあたるブロック要素の内容領域)の各辺を基準に配置され、"top, bottom, left, right" の各プロパティで指定する絶対的な位置指定となる(祖先要素に位置指定されている要素がなければ、初期包含ブロックを基準とする)。

"absolute" の説明を補足しておくと、たとえば、一番最初の包含ブロックである初期包含ブロックは、html要素の各辺が基準になるので、スクロール分も含めてページ全体が基準になります。つまり、topプロパティ・leftプロパティはページの左上が原点に、bottomプロパティ・rightプロパティはページの右下が原点となります。html要素に対して、widthプロパティ, heightプロパティを指定することで、初期包含ブロックの横幅・高さを指定することもできます。

上記の通り、id="zindex2" は最上位の基準となる先祖要素が無いため、初期包含ブロック(html 要素)を基準に配置されている。
id="zindex1" は id="zindex2" に包含されているため、id="zindex2" を基準として配置し、同様に id="zindex0" は id="zindex1" を基準に配置されている。

しかし問題はここではない。id="zindex1" と id="zindex0" が重なり合っている点が重要である。
通常であれば id="zindex0" の上に id="zindex1" が重なるはずだが、実際は逆に id="zindex1" の上に id="zindex0" が重なっている。

要素を入れ子にしたら z-index プロパティの挙動がおかしくなったと考えられる。しかしこれは恐らく仕様通りの結果のはずです。
z-index プロパティの仕様は以下のようになっています。

'z-index'
値:  auto | <integer> | inherit
初期値:   auto
適用対象:   位置決め要素
継承:   しない
パーセント値:   N/A
メディア:  視覚メディア

仕様では z-index プロパティは継承されません。ですので、子孫要素が新たな z-index プロパティを指定しても、それが親要素を継承していないため、例え値が 0 であったとしても親要素の背面に配置されることはないのです。
つまりここでは、id="zindex1" の値が 10 であったとしても、子要素の id="zindex0" からすると値は id="zindex1" は 0 に見えるのです。

なので、対応策としては id="zindex0" の値をマイナス値にしてしまえば解決します。

div#zindex0 {
position: absolute;
top: 50px;
left: 180px;
z-index: -1;
width: 200px;
height: 200px;
background: yellow;
}

しかし何故か IE6 と Opera9 ではダメなんですが・・・仕事でやった時は上手くいったんですけどね。ちょっと事情が違うみたいなので、今度また再検証してみます。

以下独り言(何
なんとなく position プロパティが怪しい感じ。仕事でやった時は[absolute] と [relative] の組み合わせだったから、なんかその辺が絡んでるのかも。
と思って試してみたが、やっぱ違うっぽい。そもそもの考え方が違うのかなぁ。ほぼ同じような構成で再度検証してみるしかないかも。

トラックバック(0)

このブログ記事を参照しているブログ一覧: z-index のあれこれ

このブログ記事に対するトラックバックURL: http://www.double-team.org/mt/mt-tb.cgi/22

コメントする

このブログ記事について

このページは、yu-sukeが2006年10月25日 19:14に書いたブログ記事です。

ひとつ前のブログ記事は「CSS Nite Vol13 に参加」です。

次のブログ記事は「Re: Firefox 2 にインストールする3個の拡張機能募集」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。