mozilla

スタック文脈

This article is in need of an editorial review.

« CSS « CSS の z-index の理解

スタック文脈

前回の例、z-index の追加 では、ある DIV 要素の描画順がその要素の z-index 値から影響を受けていました。これは、DIV 要素が スタック文脈 を生じさせるような特定のプロパティを持っていたからです。

スタック文脈は、次のうちのいずれかの要素によって、文書のどこであっても作られます

  • ルート要素(HTML)
  • 位置指定されていて(absolutely か relatively)、z-index 値が "auto" 以外の要素
  • z-index 値が "auto" 以外の flex アイテム
  • 1 未満の opacity 値を持つ要素(不透明度の仕様をご覧ください)
  • transform 値が "none" 以外の要素
  • mix-blend-mode 値が "normal" 以外の要素
  • isolation 値が "isolate" に指定されている要素 
  • mobile WebKit と Chrome 22+ では、position: fixed が常に新しいスタック文脈を作ります。z-index が "auto" の場合にもです(この記事をご覧ください)
  • いずれかのプロパティの名前が will-change に指定されている(たとえこのプロパティが書かなくても)要素(この記事をご覧ください
  • -webkit-overflow-scrolling 値が "touch" に指定されている要素

スタック文脈の内部で、子要素は前に説明したルールに従って積み重なります。重要なのは、子要素の z-index 値は、その親要素に対してのみ意味を持つということです。スタック文脈は、その親のスタック文脈では不可分な一つの固まりとして扱われます。

まとめると:

  • HTML 要素を位置指定し、z-index 値を与えるとスタック文脈が作られます(完全な不透明でないとき)
  • スタック文脈は他のスタック文脈に含めることができ、その結果スタック文脈の階層構造ができます。
  • スタック文脈はすべて、その兄弟要素と完全に独立しています: 積み重ね処理では、子孫要素だけが考慮されます。
  • スタック文脈ははめ込み式です:要素の中身が重ねられた後、その要素がまるごと、今度は親のスタック文脈のスタック順の中にあるとみなされます。
注記: スタック文脈を作れるのが一部の要素に限定されるため、スタック文脈は HTML 要素の階層構造の部分集合です。それ自身のスタック文脈を作らない要素は、その親のスタック文脈に同化される、と言えます。

Example of stacking rules modified using z-index

この例では、位置指定された要素はすべて、位置と z-index の値によって、それ自身のスタック文脈を作ります。スタック文脈の階層構造が、次のように構成されます:

  • ルート要素
    • DIV #1
    • DIV #2
    • DIV #3
      • DIV #4
      • DIV #5
      • DIV #6

重要なのは、DIV #4、DIV #5、DIV #6 は DIV #3 の子要素なので、DIV#3 の内側で重なり方が完全に決まることです。一旦DIV #3 内部の重ねあわせと描画が終われば、DIV #3 は ルート要素に丸ごと渡され、兄弟要素との重ねあわせ処理が行われます。

注記:

  • DIV #4 は DIV #1 の下(奥)に描画されます。これは、DIV #1 の z-index (5) はルート要素のスタック文脈でだけ有効な値で、DIV #4 の z-index (6) は DIV #3 のスタック文脈でだけ有効な値だからです。DIV #4 は DIV #3 の内部にあり、DIV #3 は DIV #1 よりも小さな z-index 値を持っているので、DIV #4 は DIV #1 の下になります.
  • 同じ理由で DIV #2 (z-index 2) は DIV#5 (z-index 1) の下に描画されます。これは DIV #5 が DIV #3 に含まれていて、DIV #3は DIV #2 より高い z-index 値を持っているからです。
  • DIV #3 の z-index は4ですが、この値は DIV #4、DIV#5、DIV#6 の z-index とは独立しています。異なるスタック文脈に含まれるためです。
  • Z軸方向に重なった要素の 描画順序 の簡単な計算方法は、それがバージョン番号のようなものを持っていると考えることです。親要素のメジャーバージョン番号の下に、子要素のマイナーバージョン番号があるものとします。この方法で、z-index 1 を持つ要素 (DIV #5) がどうやって z-index 2 を持つ要素 (DIV #2) の上になるのか、そして、z-index 6 を持つ要素 (DIV #4) がどうやって z-index 5 を持つ要素 (DIV #1) の下になるのか、簡単にわかります。用意した例では次のようになります(以下は最終的な描画順に並べています):
    • ルート要素
      • DIV #2 - z-index 2
      • DIV #3 - z-index 4
        • DIV #5 - z-index 1。z-index 4 を持つ要素の下に重なります。これは描画順序 4.1 から導かれる答えです
        • DIV #6 - z-index 3。z-index 4 を持つ要素の下に重なり、これは描画順序 4.3 から導かれる答えです
        • DIV #4 - z-index 6。z-index 4 を持つ要素の下に重なり、これは描画順序 4.6 から導かれる答えです
      • DIV #1 - z-index 5

ソースコード例

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  <head>

    <title>Understanding CSS z-index: The Stacking Context: Example Source</title>

    <style type="text/css">
      * {
        margin: 0;
        }
      html {
        padding: 20px;
        font: 12px/20px Arial, sans-serif;
        }
      div {
        opacity: 0.7;
        position: relative;
        }
      h1 {
        font: inherit;
        font-weight: bold;
        }
      #div1, #div2 {
        border: 1px dashed #696;
        padding: 10px;
        background-color: #cfc;
        }
      #div1 {
        z-index: 5;
        margin-bottom: 190px;
        }
      #div2 {
        z-index: 2;
        }
      #div3 {
        z-index: 4;
        opacity: 1;
        position: absolute;
        top: 40px;
        left: 180px;
        width: 330px;
        border: 1px dashed #900;
        background-color: #fdd;
        padding: 40px 20px 20px;
        }
      #div4, #div5 {
        border: 1px dashed #996;
        background-color: #ffc;
        }
      #div4 {
        z-index: 6;
        margin-bottom: 15px;
        padding: 25px 10px 5px;
        }
      #div5 {
        z-index: 1;
        margin-top: 15px;
        padding: 5px 10px;
        }
      #div6 {
        z-index: 3;
        position: absolute;
        top: 20px;
        left: 180px;
        width: 150px;
        height: 125px;
        border: 1px dashed #009;
        padding-top: 125px;
        background-color: #ddf;
        text-align: center;
        }
    </style>

  </head>
  <body>

    <div id="div1">
      <h1>Division Element #1</h1>
      <code>position: relative;<br/>
      z-index: 5;</code>
    </div>

    <div id="div2">
      <h1>Division Element #2</h1>
      <code>position: relative;<br/>
      z-index: 2;</code>
    </div>

    <div id="div3">

      <div id="div4">
        <h1>Division Element #4</h1>
        <code>position: relative;<br/>
        z-index: 6;</code>
      </div>

      <h1>Division Element #3</h1>
      <code>position: absolute;<br/>
      z-index: 4;</code>

      <div id="div5">
        <h1>Division Element #5</h1>
        <code>position: relative;<br/>
        z-index: 1;</code>
      </div>
   
      <div id="div6">
        <h1>Division Element #6</h1>
        <code>position: absolute;<br/>
        z-index: 3;</code>
      </div>

    </div>

  </body>
</html>

Div 要素 #1

position: relative;
z-index: 5;

Div 要素 #2

position: relative;
z-index: 2;

Div 要素 #3

position: absolute;
z-index: 4;

Div 要素 #4

position: relative;
z-index: 6;

Div 要素 #5

position: relative;
z-index: 1;

Div 要素 #6

position: absolute;
z-index: 3;

関連情報

原典情報

  • 原著者: Paolo Lombardi
  • この記事は原著者が YappY のためにイタリア語で書いた記事の英訳の邦訳です。Creative Commons: Attribution-Sharealike license の条件に従う限り、全内容の共有を認めます。
  • 最終更新日: 2005 年 7 月 9 日

ドキュメントのタグと貢献者

Contributors to this page: ethertank, sosleepy, Dolphin_Wood
最終更新者: Dolphin_Wood,