【23-2】重なり順のルールと 新しいスタックコンテキストができる条件
最終更新日:2019年01月26日 (初回投稿日:2017年09月07日)
前回の z-indexプロパティでスタックコンテキストという概念が出てきました。
(前回はこちら→【23-1】要素の重なり順の上下関係を指定する z-indexプロパティ)
今回はその スタックコンテキストについてもう少し詳しく調べてみました。
スタックコンテキストじゃない要素も含めて、各要素にはあらかじめ重なり順のルールが決まっているんだそうです。
また、位置指定以外の 新しいスタックコンテキストが生成される条件についてもメモっておきます。
●本記事は、2019年1月に投稿したものですが、時系列的に z-indexプロパティの記事の直後に読んでいただくために 初回投稿を2017年9月に操作しています。ご了承ください。
参考:
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上に書いた順番で、後から書いたほうが上に重なってますね。これがツリー順の重なり方です。
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>
<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>
<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プロパティは、要素が文書ツリーの他の部分から独立していることを示す)
- mix-blend-mode値が「normal」以外の要素
上のうち使用頻度が高いのは 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」はまだ何も指定していないので、ただのブロック要素です。
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」のほうが上に乗っかりましたね。
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以上の位置指定された要素」が一番上になるので。
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」を指定した要素にのみ使える、要素を切り抜き表示するプロパティです。
これ、どうやら非推奨になったようなんですが、とにかくまだ今のところは多くのブラウザで表示されるので、一応紹介しておきます。
- 関連記事
-
- 【26-3】font-weightでフォントのウェイト(太さ)を指定しよう
- 【26-2】font-sizeプロパティでフォントのサイズを指定しよう
- 【26-1】font-familyプロパティでフォント(書体)を指定しよう
- 【25-3】クリッピングに便利! shape-outside と shape-margin
- 【25-2】clip-pathプロパティで SVGのパスを使って切り抜こう
- 【25-1】切り抜き(クリッピング)のための新プロパティ clip-path
- 【24】要素を切り抜き表示する clipプロパティ(非推奨ですが)
- 【23-2】重なり順のルールと 新しいスタックコンテキストができる条件
- 【23-1】要素の重なり順の上下関係を指定する z-indexプロパティ
- 【22-4】スクロールしていくとピタッと固定する position: sticky
- 【22-3】要素を固定位置に指定する position: fixed
- 【22-2】要素を絶対位置に指定する position: absolute
- 【22-1】位置指定の positionと top, right, bottom, leftプロパティ
- (ちょっとメモ)Web開発ツールでCSSがどう効いているか確認しよう
- 【21】floatプロパティと clearプロパティ。そして Clearfixについて
初心者にも使いやすい(と思う)レンタルサーバー
「初心者ですがレンタルサーバーはどこがいい?」というご質問をよくいただきます。
自由にファイルをアップロードできる自分のサーバがあると便利ですよね。ローカル環境じゃなくサーバ上で試してみたい時がありますからね。
私が使っているのは、
スターサーバーや ロリポップ!
です。どちらも管理画面がわかりやすく、マニュアルも充実していて、料金も安い。どちらもライトプラン以上で WordPress が使えます。
初心者が始めやすいサーバだと思います。
ちょっと料金は高いけど、さくらのレンタルサーバや、エックスサーバー
は、やはり老舗なのでおすすめです。
両方とも高スペックでコスパが良く、老舗でユーザーが多いので、質問する場がたくさんあります。初心者だけど仕事でサーバが欲しい場合は、安心なのではないかと思います。
スポンサーリンク