【23-1】要素の重なり順の上下関係を指定する z-indexプロパティ

最終更新日:2019年01月26日  (初回投稿日:2017年09月06日)

今回は z-indexプロパティ を使ってみましょう。
z-indexプロパティ は、要素の表示の重なり順を変えたいときに使います。

これがまた、けっこう ややっこしいルールがありますので、じっくり見ていきましょう。

2019年1月:このページは「スタックコンテキストの生成」について誤った表記があったので全面修正しました。
また「要素の重なり順」についての補足情報を新しい記事にしましたので、本記事と合わせてご覧ください。
【23-2】重なり順のルールと 新しいスタックコンテキストができる条件

本日のINDEX
  1. z-indexプロパティの値
  2. 値の数値の大小で表示の上下関係を指定する
    1. z-indexの「マイナスの値」は要注意
  3. スタックコンテキスト と スタックレベル
    1. スタックコンテキスト(stack context)
    2. スタックレベル(stack level)
    3. 「ルートスタックコンテキスト」と「ローカルスタックコンテキスト」
    4. 「新しいスタックコンテキストができる」とどうなる?
  4. 他のスタックコンテキストの中との関係はコントロール不可
  5. z-indexプロパティのルール まとめ

参考:
こちら↓はドラフトの仕様
CSS Positioned Layout Module Level 3 -- W3C Working Draft, 17 May 2016
CSS Positioned Layout Module Level 3 -- W3C Editor’s Draft, 26 September 2018
勧告済みの CSS2 はこちら↓
Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification
W3C Recommendation 07 June 2011, edited in place 12 April 2016 to point to new work -- 9 Visual formatting model

z-indexプロパティの値

z-indexプロパティは、位置指定された要素(Positioned elements)にのみ指定できます。 これは positionプロパティposition: static 以外の指定がしてある要素ということ。これ以外に指定しても何も起きません。これうっかり忘れがちなので重要。

z-indexプロパティの値はこうなっています。

auto これがデフォルト値
新しいスタックコンテキストは作られません。スタックレベルは親要素と同じになります。
整数 単位なしの整数。0も含む。マイナスの値も使えます。
この整数値がこの要素自身のスタックレベルになります。
この値は兄弟のスタックコンテキストに対しての重なり順を指定します。
この要素内の入れ子の要素のz-index値は、他の兄弟要素内の入れ子の要素のz-index値に影響しません。 ちなみに「2の31乗 -1(符号付き32bit整数の最大値なんだって)」までの数値を使えるそうで、-2147483647 から 2147483647 まで指定できるんだって。へぇ〜。
(そんなに作ったら管理できないけどね〜w)
値の継承 なし 適用できる要素 位置指定された要素
position: static 以外の potision指定した要素

「スタックコンテキスト」「スタックレベル」という、聞き慣れない言葉が出てきました。これらは順を追って説明します。

まずはとにかく z-index を使ってみよう。

値の数値の大小で表示の上下関係を指定する

まずは、こんなボックスを用意しました。まだどれにも position指定をしていません。

子・グリーン
子・ピンク

HTML と CSS

<div class="oya">
 <div class="ko_green">子・グリーン</div>
 <div class="ko_pink">子・ピンク</div>
</div>

<style>
.oya {
  background:#fffddb;
  border:solid 10px #fffddb} /*後で子要素に位置指定をした時にマージンやパディングが効かなくなるのでボーダーを使っています*/
.ko_green, .ko_pink { /*2つの子要素共通の指定です*/
  line-height:5em;
  width:70%;
  text-indent:1em}
.ko_green {
  background:#88d7b0}
.ko_pink {
  background:#e4afb9;
  border-radius:50%} /*楕円にしています*/
</style>

次に2つの子要素に position: absolute を指定。(親要素には position: relative を指定)
まだどれにも z-index は指定していません。
「子・ピンク」のほうが上に乗っかります。HTML上で後に書いた兄弟が上になるのでこれが普通。

子・グリーン
子・ピンク

HTML と CSS

<div class="oya">
 <div class="ko_green">子・グリーン</div>
 <div class="ko_pink">子・ピンク</div>
</div>

<style>
.oya {
  background:#fffddb;
  border:solid 10px #fffddb;
  height:5em; /*子要素の高さに依存していたので高さ指定します*/
  position:relative} /*親にはposition:relative*/
.ko_green, .ko_pink { /*2つの子要素共通の指定です*/
  line-height:5em;
  width:70%;
  text-indent:1em;
  position:absolute; /*2つの子要にposition:absolute*/
  bottom:0;} /*2つの子要にbottom:0*/
.ko_green {
  background:#88d7b0;
  left:0} /*子グリーンはleft:0で左寄せに*/
.ko_pink {
  background:#e4afb9;
  border-radius:50%;
  right:0} /*子ピンクはright:0で右寄せに*/
</style>

ここで、「子・グリーン」に z-index: 2 を、「子・ピンク」に z-index: 1 を指定します。
数値の小さい方が下になりました。z-index はこんなふうに重なり順を変えるために使います。

子・グリーン
子・ピンク

HTML と CSS

<div class="oya">
 <div class="ko_green" style="z-index:2">子・グリーン</div>
 <div class="ko_pink" style="z-index:1">子・ピンク</div>
</div>

<style>
/*z-index は div要素にインラインで指定しています */
/*他のスタイルはさっきと変わりません*/
</style>

z-indexの「マイナスの値」は要注意

マイナスの値も指定できるんでしたね。では「子・ピンク」に z-index: -1 を指定してみます。
すると、あれ? 消えちゃった
「2」よりも「-1」の方が小さいし、さっきと同じかと思ったけど...

子・グリーン
子・ピンク

HTML と CSS

<div class="oya">
 <div class="ko_green" style="z-index:2">子・グリーン</div>
 <div class="ko_pink" style="z-index:-1">子・ピンク</div>
</div>

親要素に「opacity: 0.5」を指定して半透明にしてみます(中の子要素も半透明になるけどね)
いますね。親の後ろに隠れちゃってたんですね。

子・グリーン
子・ピンク

HTML と CSS

<div class="oya" style="opacity:.5">
 <div class="ko_green p_ab_left" style="z-index:2">子・グリーン</div>
 <div class="ko_pink p_ab_right" style="z-index:-1">子・ピンク</div>
</div>

これは実際には、親の背景色が半透明になったからすぐ下にいる要素ピンクが見えたわけじゃないんです。
親要素(oya)に opacityの1未満を指定したことで、親要素がスタックコンテキストになったから、子のスタックコンテキストが親の上に表示されたんです。
まあ、子ピンクは存在はしているということ。親がスタックコンテキストじゃないと、マイナスのz-index値の子は親の下に潜るということです。
opacity以外にもスタックコンテキストを生成する条件があります。詳しくは【23-2】重なり順のルールと 新しいスタックコンテキストができる条件 をご覧ください。

マイナスのz-index値にすると、親の下に潜るのは、親要素がスタックコンテキストじゃないから。
親要素(class="oya")は、ルートスタックコンテキストに含まれていて スタックレベルが0のままだからです。

なんのこっちゃ?
ですね。
どんどん進みましょう↓

スタックコンテキスト と スタックレベル

CSSには、縦方向(y軸)、横方向(x軸)に加えて、z軸方向の「重なり」の概念もあります。z軸の向きは、ユーザーに近いか遠いか。ユーザーから見て一番奥に見えるのが遠い、一番手前にあるのが近いってかんじです。

この「重なり順」の概念を スタックコンテキストと言います。
スタックコンテキストは入れ子にすることもできます。(だからややこしい)

スタックコンテキスト(stacking context)

W3Cの仕様書では「stacking context(スタッキング コンテキスト)」ですが、なんとなく慣れた呼び方の「スタック コンテキスト」で書いていきますね。

スタック(stack)は「積み重ねる」といった意味。
(立ち往生する stuck とは違う単語です。日本語読みは同じスタックだけど)

コンテキスト(context)は、よく「文脈」って訳されるけど、今の場合は「前後関係」と言ったほうがわかりやすいかも。

で、スタックコンテキスト(stack context)は直訳だと 重なり順の関係ってとこです。
「1つのまとまり(グループというか)」が複数あって「それらがお互いに影響し合う重なり順をもっている、という概念」です。

Photoshop や Illustrator の「レイヤー」みたいなイメージ でも最初はいいかも。
1つのレイヤーにオブジェクトを入れたら、それを1セットとして扱えて、他のレイヤーと重なり関係を変えられますよね。アレに近いイメージ。
ただ、実際には似て非なるもの。もっと概念的な重なり順をもつグループです。

スタックコンテキストは、「位置指定された要素」の他にも、opacityプロパティや transformプロパティなどを指定した時でも生成されます。
(→【23-2】重なり順のルールと 新しいスタックコンテキストができる条件
今回の記事は、z-inexプロパティを指定できる「位置指定された要素」だけで説明をしていきます。

スタックレベル(stack level)

これはもう そのままズバリ、重なり順のレベルです。カウント方法。

「z-index: 整数値」を指定すると、この「整数値」がスタックレベルになります。
例えば z-index: 3 と指定したら、スタックレベルは「3」
z-index: -8 と指定したら、スタックレベルは「-8」です。
レベルの数値が大きいほど重なり順は上、小さいほど下になります。

「ルートスタックコンテキスト」と「ローカルスタックコンテキスト」

<html>要素は「ルート要素」とも言われます。
この <html>要素ルートスタックコンテキスト というのをもともと生成しています。

その他の要素が条件を満たした時に 新しく作られるのは ローカルスタックコンテキスト と言います。

新しいローカルスタックコンテキストが全く生成されてないなら、<html>要素の ルートスタックコンテキストだけがある状態です。
ルートスタックコンテキストのスタックレベルは 0 です。

私はスタックコンテキストを「器(うつわ)」のようなイメージで考えています。
こんなふうに↓ (これは横から見た図ね)

上の図のように スタックレベル「0」が ルート要素以外のスタックコンテキストがない状態です。
この中に、まずは一番下に <body>要素があり、親子関係の要素なら子孫の要素ほど重なりは上のほうになり、兄弟要素ならHTML上に後に書いた要素ほど上のほうに表示されます。(これを tree order(ツリー順)と言います)

「新しいスタックコンテキストができる」とどうなる?

さっき「子・グリーン」に z-index: 2、「子・ピンク」に z-index: 1 を指定したらこうでしたね。

親要素
子・グリーン
子・ピンク

これは 下図のように 2つの新しい ローカルスタックコンテキストができたということ。
で、「スタックレベル2」のほうが「スタックレベル1」より上に表示されました。

次に「子・グリーン」に z-index: 2、「子・ピンク」に z-index: -1 を指定したら、ピンクのほうが親より下に行って、親の背景色のせいで見えなくなりましたね。

親要素
子・グリーン
子・ピンク

これは スタックレベル -1 だと親要素のスタックレベル0より下になったから

「position: absolute」を指定したら親以外とは位置関係は切り離されるんでしたが、「z-index」を指定したら重なり順はこんな世界になるってことです。親は親のままなんですが、重なり順はまったく別問題になると。
ここが Photoshop などのレイヤーと違うところ。スタックコンテキストは概念的な重なり順を持つグループってかんじです。

他のスタックコンテキストの中との関係はコントロール不可

どんどん行きます。
次はこんなサンプルを作ってみました。
「孫 z-index:4」(茶色の四角)が一番上に来そうなもんですが、「子 z-index:2」(ブルー)「孫 z-index:1」(黄緑)の下になっていますね。

子 z-index:2
孫 z-index:1
子 z-index:1   
孫 z-index:4   
孫 z-index:2   

HTML と CSS

<div class="oya2">親
 <div class="ko_z2">子 z-index:2  <!--ブルーの四角-->
  <div class="mago_z1">孫 z-index:1</div> <!--黄緑の角丸四角-->
 </div>
 <div class="ko_z1">子 z-index:1 <!--にぶめのピンクの四角-->
  <div class="mago_z4">孫 z-index:4</div> <!--茶色の四角-->
  <div class="mago_z2">孫 z-index:2</div> <!--濃いピンクの角丸四角-->
 </div>
</div>

<style>
.oya2 {
  border:solid 1px #ccc;
  height:250px;
  position:relative;
  text-indent:1em;
  font-weight:bold}
  
.oya2 div {
  position:absolute}  /*親の中のdivは子も孫も全部 position:absolute*/

/*以下、一部省略(topやleftプロパティなどは省略しています。長くなるので)*/
.ko_z2 {
	z-index:2;
    background:rgba(118,188,254,.6)}  /*ブルー*/
.mago_z1 {
    z-index:1;
    background:rgba(193,217,94,.7)}  /*黄緑*/
.ko_z1 {
    z-index:1;
    background:rgba(195,151,181,1)}  /*にぶめのピンク系*/
.mago_z4 {
    z-index:4;
    background:rgba(112,78,31,1)}  /*茶色*/
.mago_z2 {
    z-index:2; 
    background:rgba(184,86,125,1)}  /*濃いピンク*/
</style>

これは、スタックコンテキストが入れ子になっているから。

スタックレベルは、同じスタックコンテキストの中の兄弟スタックコンテキストどうししか影響し合わないんです。
自分が属してないスタックコンテキストの中身に対して、自分のスタックレベルは無意味。これ重要。

例えばこのような3人がいたとして、

これだけ見ると、住んでる階は上から「Z:4」>「Z:2」>「Z:1」の順番に思えますよね。

でも、住んでるところがこう↓だったら、

親が「z-index: 2」の「Z:1」が、誰よりも上の階層にいるんですね。
他の2人は、同じ親のスタックコンテキストにいるので、「Z:4」>「Z:2」が成り立ちます。

こんなふうに、入れ子のスタックコンテキストの「スタックレベル」は、同じスタックコンテキストの中でしか影響しないんです。

もしも「Z:4(茶色のおじさん)」を「Z:1(緑の人)」より上にいさせたかったら、今の親のスタックコンテキスト(建物)から出して単独で飛んでもらう(今の親と兄弟にする)か、「Z:1(緑の人)」と同じスタックコンテキスト(山の上の建物 = z-index: 2)に住まわせるか、「z-index: 3以上」のスタックコンテキストに住まわせるか、です。

もう1つ実験。
「子 z-index:2」の中の「孫」(グリーンの角丸四角)を「z-index: -6」にしてみます。
マイナス6(地下6階?!)にすると、どうなるでしょう。
重なり順は変わりませんね。やはり、親のスタックコンテキスト内限定の重なり順なのがわかります。

子 z-index:2
孫 z-index: -6(コレ!)
子 z-index:1   
孫 z-index:4   
孫 z-index:2   

HTML と CSS

<div class="oya2">親
 <div class="ko_z2">子 z-index:2
  <div class="mago_z1_6">孫 z-index: -6(コレ!)</div>
 </div>
 <div class="ko_z1">子 z-index:1
  <div class="mago_z4">孫 z-index:4</div>
  <div class="mago_z2">孫 z-index:2</div>
 </div>
</div>

<style>
/*CSSは追加したものだけ*/
.mago_z1_6 {z-index:-6}
</style>

じゃあここで、水色の「子 z-index:2」の z-index 無しにしてみます。
デフォルト値「z-index: auto」を指定することで無効になりますよ。
するとこんなことに。「孫」(グリーンの角丸四角)がいなくなった。

子 z-index:なし(コレ!)
孫 z-index: -6
子 z-index:1   
孫 z-index:4   
孫 z-index:2   

HTML と CSS

<div class="oya2">親
 <div class="ko_z2" style="z-index:auto">子 z-index:なし(コレ!)
  <div class="mago_z1_6">孫 z-index: -6</div>
 </div>
 <div class="ko_z1">子 z-index:1
  <div class="mago_z4">孫 z-index:4</div>
  <div class="mago_z2">孫 z-index:2</div>
 </div>
</div>

水色の「子 z-index:なし」は z-index指定がなくなったので「ルートスタックコンテキスト」に属すようになり、スタックレベル「0」になりました。なので「子 z-index:1」(ピンクの四角)よりも下になってます。
「孫」(グリーンの角丸四角)は、親の z-index 指定が無くなったことで、「子 z-index:1」(ピンクの四角)と兄弟スタックコンテキストになったんですが、スタックレベルが「-6」なのでスタックレベル「0」の親よりも下になったってわけです。

全員の親(oya2)に「opacity: 0.5」を指定してみた(全員半透明になります)
いますね。水色の「子 z-index:なし」の下に。

子 z-index:なし(コレ!)
孫 z-index: -6
子 z-index:1   
孫 z-index:4   
孫 z-index:2   

ということで、マイナスの値を使うときは、親要素がスタックコンテキストを持ってないと親より下に潜る
これが z-index を使う時にありがちな珍現象の原因。
親要素がスタックコンテキストであれば、マイナスの z-index値でも親の背景の下には行かない。親スタックコンテキスト内の「兄弟のスタックコンテキスト同士の重なり順」だけを指定するのが z-index値です。

z-indexプロパティのルール まとめ

最後に今回の話をまとめておきます。

  • z-indexプロパティは、「position: static(デフォルト値)」以外の position指定を指定した要素にのみ適用できる
  • 「z-index: 整数値」ローカルスタックコンテキストのスタックレベルになる。スタックレベルが大きい方が上に重なる
  • スタックレベルは、兄弟スタックコンテキストどうしにしか影響しない
  • 親要素が ローカルスタックコンテキストじゃないとき、子孫要素に「z-index: マイナスの値」を指定すると親より下のレベルになるので要注意。

次回予告

z-index って、ややこしいですよね。

次回は、そのスタックコンテキストについてもう少し詳しく補足します。
スタックコンテキストでなくても、各要素にはあらかじめ重なり順のルールがあります。
これを知っておくと役に立つかも。

関連記事
このエントリーをはてなブックマークに追加

やる気を保つためにランキングに参加しています。
応援してくださると すっごいやる気を出します! (笑)

初心者にも使いやすい(と思う)レンタルサーバー

「初心者ですがレンタルサーバーはどこがいい?」というご質問をよくいただきます。
自由にファイルをアップロードできる自分のサーバがあると便利ですよね。ローカル環境じゃなくサーバ上で試してみたい時がありますからね。
私が使っているのは、 スターサーバーロリポップ!です。どちらも管理画面がわかりやすく、マニュアルも充実していて、料金も安い。どちらもライトプラン以上で WordPress が使えます。
初心者が始めやすいサーバだと思います。

ちょっと料金は高いけど、さくらのレンタルサーバや、エックスサーバー は、やはり老舗なのでおすすめです。
両方とも高スペックでコスパが良く、老舗でユーザーが多いので、質問する場がたくさんあります。初心者だけど仕事でサーバが欲しい場合は、安心なのではないかと思います。

スポンサーリンク

コメントの投稿

ご注意:メールアドレスは書かないで
「コメントを送信する」ボタンを押した後の「確認画面」で、メールアドレス・URL などを入力できるようになっており、メールアドレス・URL は、そのままオートリンクになる仕様です。
当方でメールアドレスだけ削除することも、メールアドレスを非公開にすることもできません
メールアドレスは書かないでください。詳しくはこちらにまとめましたのでご覧ください。

わかりやすい

すごくわかりやすかったです。図が。
知らなかったことが、わかりやすく説明されていて、とても良かった。
ありがとうございます‼︎

Re: わかりやすい

monminmunさん
コメントありがとうございます。
お役に立てて何よりです。

opacityが1未満だと重なり順が上になる

コメントをくださった方、ごめんなさい、誤ってあなたのコメントを削除してしまいました。(不要な広告系のコメントを削除していた時に不注意で)

Codepen の「マウスオーバーした場合の要素の重なりに変化」の質問でしたね。

本記事では、触れていませんが、
「opacityが1未満」の要素は、位置指定した要素(z-index値が0かauto)よりも重なり順は上になるそうです。

W3Cの仕様書の 12.2. Painting order(表示順)を見てみてください。
https://www.w3.org/TR/css-position-3/#painting-order


マウスオーバーで img要素に「opacity:0.8」が適用されると、このときだけ img要素が position: absolute な要素(NEWというテキストのspan要素)より上に乗っかる表示になるんだと思います。

この件は、後日記事にまとめようと思います。
コメントありがとうございました。
スポンサーリンク
最新記事
Category
オススメの本
Links
Calendar
08 | 2023/09 | 10
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archive
Profile

yuki★hata

Author : yuki★hata
せめて月1回の更新をめざします~。

メールフォームはこちら

スポンサーリンク
スポンサーリンク
Copyright © ほんっとにはじめてのHTML5とCSS3 All Rights Reserved.