【23-2】重なり順のルールと 新しいスタックコンテキストができる条件

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

前回の z-indexプロパティスタックコンテキストという概念が出てきました。
(前回はこちら→【23-1】要素の重なり順の上下関係を指定する z-indexプロパティ

今回はその スタックコンテキストについてもう少し詳しく調べてみました。
スタックコンテキストじゃない要素も含めて、各要素にはあらかじめ重なり順のルールが決まっているんだそうです。
また、位置指定以外の 新しいスタックコンテキストが生成される条件についてもメモっておきます。

●本記事は、2019年1月に投稿したものですが、時系列的に z-indexプロパティの記事の直後に読んでいただくために 初回投稿を2017年9月に操作しています。ご了承ください。

本日のINDEX
  1. 重なり順はツリー順と、そうでない場合がある
    1. 要素の重なり順のルール
  2. 新しいスタックコンテキストが生成される条件
    1. opacity: 1未満 で重なり順が上になるサンプル

参考:
W3C CSS Positioned Layout Module Level 3 - 12.2. Painting order(描画順序)
CSS の z-index を理解する | MDN
重ね合わせコンテキスト | MDN

重なり順はツリー順と、そうでない場合がある

HTMLに書かれた要素の描画は、まず一番下に html要素(ルート要素)が描画され、その上に他の要素(body要素とその中身)が描画されるようになってます。

ブラウザが要素を描画するときの重なり順は、
・親子関係の要素なら子孫の要素ほど重なりは上
・兄弟要素ならHTMLに後に書いた要素ほど上
という基本のルールがあります。
この重なり順を tree order(ツリー順)と言います。

基本的に描画はこのツリー順で重なるのですが、要素に指定されたCSSプロパティの値によって、ツリー順以外の重なり順になる場合があります。

ちょっと試してみます。
下の3つのボックスは、位置指定していない ただのdiv要素です。ネガティブマージンで ちょっとずつ重ねています。
(ネガティブマージンについては【11-3】はみ出て便利♪ ネガティブ・マージンをご覧ください)

HTML上に書いた順番で、後から書いたほうが上に重なってますね。これがツリー順の重なり方です。

DIV 1
DIV 2
DIV 3

HTML と CSS

<div>
 <div class="div1">DIV 1</div>
 <div class="div2">DIV 2</div>
 <div class="div3">DIV 3</div>
</div>

<style>
.div1, .div2, .div3 {line-height:5em; width:70%; text-indent:1em}
.div1 {background:#88d7b0}
.div2 {background:#fc6; margin-left:10px; margin-top:-1em}
.div3 {background:#e4afb9; margin-left:20px; margin-top:-1em}
</style>

「DIV 1」「DIV 2」に「position: relative」を指定してみます。
最後の「DIV 3」には 何も指定しません(= position: static ってこと)。この最後の「DIV 3」は一番下になります。
このように、位置指定(positionプロパティの static以外)をした要素は、そうじゃないものより重なり順が上になるルールがあるんです。
「DIV 1」「DIV 2」の関係はまだツリー順になってますね。同じレベルのものはツリー順に従うルールがあるから。

DIV 1
DIV 2
DIV 3
<div>
 <div class="div1" style="position:relative">DIV 1</div>
 <div class="div2" style="position:relative">DIV 2</div>
 <div class="div3">DIV 3</div>
</div>

では、「DIV 1」を一番上に持って来るために「z-index: 1」と指定してみます。
「position: relative」を指定して z-index が auto以外に指定されたので「DIV 1」は新しいスタックコンテキストを生成し、このサンプルでは他の兄弟のスタックレベルが0なので、一番上になったんです。

DIV 1
DIV 2
DIV 3
<div>
 <div class="div1" style="position:relative; z-index:1">DIV 1</div>
 <div class="div2" style="position:relative">DIV 2</div>
 <div class="div3">DIV 3</div>
</div>

要素の重なり順のルール

HTML上の要素の重なり順(z軸に沿った並び方)のルールが、W3Cの仕様書CSS Positioned Layout Module Level 3 - 12.2. Painting orderにあったので、ものすごく大雑把に図にまとめてみました。

(注:この仕様は2016年のドラフトで、clip-pathプロパティその他の新しいプロパティについては触れられていません。また、私の日本語訳や解釈が間違っている可能性もあります。あくまでもざっくりとしたイメージとして見てください )

要素の重なり順のルール

ややこしいですね。(原文はもっとややこしいので、訳があってるかどうか...w)

3の「z-index値がマイナスの位置指定された要素」が、もしも 4の「位置指定されていないブロックレベルの要素の子孫」であっても、その下に来る(親要素の背景や内容物よりも下に)という解釈でいいんじゃないかなぁと思っています。

注目すべきは 8-2(opacityが1未満)と 8-3(transformがnone以外)の要素が、「位置指定されたz-index値が auto や 0 の要素(8-1)」より上に来るところ。
ここは日本語訳は間違っていないです(笑)。「opacity: 1未満」はサンプルで試してみましたし。(サンプルはこちら(本記事後半にあります)

また、float(位置指定なし)でも重なり順が変わるそうですが、floatは、その後に続く兄弟要素をすべて自分に回り込ませる、けっこう特殊なプロパティなので「重なり順」を気にする機会はあんまり無いんじゃないかと思います(私感です)
まあとにかく、floatを指定すると重なり順は上になってたんですね。
(floatについてはこちら→【21】floatプロパティと clearプロパティ。そして Clearfixについて

上の図は、スタックコンテキストもそうじゃないものも、すべての要素の重なり順を示してます。スタックコンテキストなのは、1. 3. 6. 8. 9. といったところでしょうか。
位置指定以外にも新しくスタックコンテキストができる条件があるそうなので、次の項にまとめてみました。

新しいスタックコンテキストが生成される条件

新しくスタックコンテキストができる条件が MDN Web Docs に掲載されていましたのでメモっておきます。
ルート要素(html要素)がスタックコンテキストなのは当たり前なので省いて、ローカルスタックコンテキストができるやつだけリストにしておきます。
(参考:重ね合わせコンテキスト | MDN

新しくローカルスタックコンテキストができる条件
  • position値が「absolute」か「relative」で、z-index値が「auto」以外の要素
  • position値が「fixed」か「sticky」の要素(z-index: auto でも)
  • Flexアイテム(display:flexな要素の子要素)で、z-index値が「auto」以外の要素(要位置指定)
    フレックスボックスについてはこちら→【18-1】Flexboxを使おう!
  • opacity値が「1未満」な要素
    opacityプロパティについてはこちら→【8】CSSの「色」と「透明度」の指定
  • transform値が「none」な要素
    transformプロパティは、要素を変形(回転・拡大縮小・傾斜・移動)する)
  • その他、以下のプロパティの値が指定された要素
    • mix-blend-mode値が「normal」以外の要素
      mix-blend-modeプロパティは、子要素の中身と親要素の中身や背景を、どのようなモードで混合するか設定)
    • filter、perspective、clip-path、mask、mask-image、mask-border値が「none」以外の要素
      filterプロパティは、要素に「ぼかし・色変化」などのグラフィック効果を適用する)
      perspectiveプロパティは、3D配置された要素に遠近感を与える設定をする)
      clip-pathプロパティは、要素のクリッピング領域を作る→【25-1】切り抜き(クリッピング)のための新プロパティ clip-path
      maskプロパティは、要素のマスキングのための指定をする)
    • isolation値が「isolate」な要素
      isolationプロパティは、要素が新しいスタックコンテキストを生成するかどうか決める)
    • will-change値が「auto」以外で、スタックコンテキストを作成する任意のプロパティを指定している要素
      will-changeプロパティは、どのような要素の変更が予測されるかブラウザーに助言)
    • contain値が「layout」か「paint」か「layout paint」な要素
      containプロパティは、要素が文書ツリーの他の部分から独立していることを示す)

上のうち使用頻度が高いのは position と opacity くらいですかね。
positionでも「fixed」「sticky」なら z-index値が auto でもスタックコンテキストができるんですね。う〜ん複雑。

正直なところ、何かプロパティを指定したことで新しいスタックコンテキストができるのは、たぶんブラウザが描画する上で必要だからだと思う。
なので、何を指定したらスタックコンテキストができるかなんて覚えなくていいや、と思ってますw(単なる私感です)

どちらかというと、先程の「重なり順のルール」の上のほう(8〜9)を知っていたほうが役に立ちそう。

opacity: 1未満 で重なり順が上になるサンプル

opacityを 1未満にしたら、重なり順は「z-indexを指定していない位置指定した要素」よりも上になるんでしたね。
opacityは使用頻度が高めなので、ちょっとサンプルで確かめてみます。

まず、下のサンプルは「DIV 1」に position: absolute を指定しただけ。
「位置指定された要素(z-indexは指定していないので autoのまま)」になったので、記事の前半の 要素の重なり順のルール のとおり、上に乗っかっています。
「DIV 2」はまだ何も指定していないので、ただのブロック要素です。

DIV 1
DIV 2

HTML と CSS

<div class="oya">
 <div class="smplDiv1">DIV 1</div>
 <div class="smplDiv2">DIV 2</div>
</div>

<style>
.oya {
	padding:1em;
	border:solid 1px #ccc;
	position:relative; /*親要素に position:relative*/
	text-align:center}
.smplDiv1 {
	background:maroon;
	color:white;
	border-radius:50%; /*楕円にしています*/
    line-height:6;
	width:6em; /*line-height も width も6文字分なので正円になります*/
	position:absolute;
	top:-.5em} /*topをマイナスにして親よりはみ出させています*/
.smplDiv2 {
	background:powderblue;
	line-height:13em;
	margin-left:3em}
</style>

「DIV 2」に opacity: 0.8 と指定して透明度を80%にします。
すると あらホントだ! 「DIV 2」のほうが上に乗っかりましたね。

DIV 1
DIV 2

HTML と CSS(opacity:0.8 はインラインで直接指定しています)

<div class="oya">
 <div class="smplDiv1">DIV 1</div>
 <div class="smplDiv2" style="opacity:0.8">DIV 2</div>
</div>

記事の前半の 要素の重なり順のルール のとおり、
「DIV 1」は「z-index値が auto か 0 の位置指定された要素」(図の8-1)で、「DIV 2」に「opacity: 0.8」を指定した(図の8-2)ことで、それより上になったんですね。

「DIV 1」を上に重ねたままにしたければ「DIV 1」に z-index を1以上を指定するだけ。
要素の重なり順のルール では「z-index値が1以上の位置指定された要素」が一番上になるので。

DIV 1
DIV 2

HTML と CSS(z-index: 1 はインラインで直接指定しています)

<div class="oya">
 <div class="smplDiv1" style="z-index:1">DIV 1</div>
 <div class="smplDiv2" style="opacity:0.8">DIV 2</div>
</div>

要素の重なり順が意図しない表示になったら、要素の重なり順のルールのせいかな?と疑ってみると解決が早いかも。
「上に重ねたい要素」に position指定して、z-indexでスタックレベルを上げたら解決することが多いんじゃないかな。
そのためにも、z-indexはむやみに使わずに、ここぞという時のために使ったほうが良さそうです。

次回予告

さて次回は、clipプロパティを紹介します。
「position: absolute」か「position: fixed」を指定した要素にのみ使える、要素を切り抜き表示するプロパティです。
これ、どうやら非推奨になったようなんですが、とにかくまだ今のところは多くのブラウザで表示されるので、一応紹介しておきます。

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

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

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

「レンタルサーバーはどこがいい?」とご質問をよくいただきますが、自分でも使っていてオススメなのは スターサーバー (ミニバードがスターサーバになりました)。管理画面がわかりやすくていい感じす。
仕事で使ってるロリポップ!もわかりやすい管理画面で、初めてでもすんなり使えます。
両方とも、なんといっても料金が安いです。

ちょっと料金は高いけど、高スペックでコスパが良く、信頼性も高いサーバといえば、やはりさくらのレンタルサーバと、エックスサーバー 。この2つは老舗でユーザーも多いので、質問する場がたくさんあり、初心者の方でもイケるだろうと思います。

スポンサーリンク

コメントの投稿

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

スポンサーリンク
最新記事
Category
オススメの本
Links
Calendar
08 | 2019/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
RSS Link
Profile

yuki★hata

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

メールフォームはこちら

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