CSSの重ね合わせコンテキスト

重ね合わせコンテキストとは

重ね合わせコンテキストとは、Webページを閲覧しているユーザーに対して、HTML 要素を仮想の Z軸 にそって並べられた要素を概念化したものです。

重ね合わせコンテキストは、文書の随所に様々な要素によって構成されますが、重ね合わせコンテキストを作れるのが一部の要素に限定されるため、重ね合わせコンテキストは HTML 要素の階層構造の部分集合となります。

  • 重ね合わせコンテキストは他の重ね合わせコンテキストに含めることができ、その結果重ね合わせコンテキストの階層構造ができます。
  • 重ね合わせコンテキストはすべて、その兄弟要素と完全に独立しています。重ね合わせ処理では、子孫要素だけが考慮されます。
  • 重ね合わせコンテキストははめ込み式です。要素の中身が重ねられた後、その要素がまるごと、今度は親の重ね合わせコンテキストの重ね合わせ順の中にあるとみなされます。

なお、重ね合わせコンテキストは以下の条件に当てはまる要素で構成されます。

  • 文書のルート要素( <html> 要素)
  • position の値が absolute または relative であり、かつ z-index の値が auto 以外の要素
  • position の値が fixed または sticky の要素
  • フレックス (flexbox) コンテナーの子であり、 z-index の値が auto 以外の要素
  • グリッド (grid) コンテナーの子であり、 z-index の値が auto 以外の要素
  • opacity の値が 1 未満である要素
  • mix-blend-mode の値が normal 以外の要素
  • 以下のプロパティ値が none 以外の要素。
    • transform
    • filter
    • perspective
    • clip-path
    • mask / mask-image / mask-border
  • isolation の値が isolate である要素
  • -webkit-overflow-scrolling の値が touch である要素
  • will-change の値が、初期値以外で重ね合わせコンテキストを作成する任意のプロパティを指定している要素
  • contain の値が layout または paint であるか、これらのどちらかを含む複合値 (すなわち contain: strict, contain: content) を持つ要素。

重ね合わせコンテキストの内部で、子要素が z-index プロパティの値に応じて重ね合わされて表示されます。

なお、z-index の値が影響するのは、親要素に対してのみで、「文書全体」での重ね合わせ順というわけではありません。

重ね合わせコンテキストは、その親の重ね合わせコンテキストでは不可分な一つの固まりとして扱われます。

重ね合わせ順の決定方法

z-index の指定がない場合

どの要素にも z-index プロパティが指定されていない場合、要素は以下の順序で下から上に重ね合わせられます。

  1. ルート要素の背景と境界
  2. 位置指定なしのブロックの子孫、 HTML 内での出現順
  3. 位置指定要素、 HTML 内での出現順
  4. flex コンテナーの中で order プロパティを設定した場合は、order プロパティの値の昇順

サンプル

<body>
    <div id="abs1" class="absolute">
        <strong>DIV #1</strong><br />position: absolute;
    </div>
    <div id="rel1" class="relative">
        <strong>DIV #2</strong><br />position: relative;
    </div>
    <div id="rel2" class="relative">
        <strong>DIV #3</strong><br />position: relative;
    </div>
    <div id="abs2" class="absolute">
        <strong>DIV #4</strong><br />position: absolute;
    </div>
    <div id="sta1" class="static">
        <strong>DIV #5</strong><br />position: static;
    </div>
</body>
body{
    margin: 2.0rem;
}
div {
    padding: 1.0rem;
    border: 1px dashed;
    text-align: center;
}
.static {
    position: static;
    height: 80px;
    background-color: #ffc;
    border-color: #996;
}
.absolute {
    position: absolute;
    width: 150px;
    height: 250px;
    background-color: #fdd;
    border-color: #900;
    opacity: 0.6;
}
.relative {
    position: relative;
    height: 40px;
    opacity: 0.7;
}
#abs1 {
    top: 1.0rem;
    left: 1.0rem;
}
#rel1 {
    top: 3.0rem;
    margin: 0px 3.0rem;
    background-color: royalblue;
    border-color: royalblue;
}
#rel2 {
    top: 2.0rem;
    left: 2.0rem;
    margin: 0px 3.0rem;
    background-color: lightgreen;
    border-color: lightgreen;
}
#abs2 {
    top: 1.0rem;
    right: 1.0rem;
}
#sta1 {
    background-color: peachpuff;
    margin: 0px 3.0rem;
}

この例では、DIV#1~DIV#4までが「位置指定あり」の要素、DIV#5が「位置指定なし」の要素になるので、HTML 文書内での登場順は一番最後ですが、DIV#5が一番下に表示されています。

浮動ブロックの重ね合わせ

浮動ブロックは位置指定なしのブロックと、位置指定ありのブロックのあいだに配置されます。ただ、「位置指定なしのブロック」の領域自体は、浮動ブロックの下に配置されますが、「位置指定無しブロック内のコンテンツ」は浮動ブロックより上に配置されます。

  1. ルート要素の背景と境界
  2. 位置指定なしのブロックの子孫、 HTML 内での出現順
  3. 浮動ブロック
  4. 位置指定なしのインライン要素の子孫
  5. 位置指定要素、 HTML 内での出現順

ただし、位置指定無しブロックであっても、 opacity 属性が指定された場合には、位置指定要素と同じように扱われます。

サンプル

<body>
    <div id="abs1">
        <b>DIV #1</b><br />position: absolute;</div>
    <div id="flo1">
        <b>DIV #2</b><br />float: left;</div>
    <div id="flo2">
        <b>DIV #3</b><br />float: right;</div>
    <span>SPAN #1 inline-item</span>
    <br />
    <div id="sta1">
        <p><b>DIV #4</b><br />no positioning</p></div>
    <div id="abs2">
        <b>DIV #5</b><br />position: absolute;</div>
    <div id="rel1">
        <b>DIV #6</b><br />position: relative;</div>
</body>
body{
    margin: 2.0rem;
}
div {
    padding: 10px;
    text-align: center;
}
b {
    font-family: sans-serif;
}
#abs1 {
    position: absolute;
    width: 150px;
    height: 200px;
    top: 10px;
    right: 140px;
    border: 1px dashed #900;
    background-color: #fdd;
    opacity: 0.6;
}
#sta1 {
    height: 100px;
    border: 1px dashed #996;
    background-color: #ffc;
    margin: 0px 10px 0px 10px;
    text-align: left;
}
#flo1 {
    margin: 0px 10px 0px 20px;
    float: left;
    width: 150px;
    height: 200px;
    border: 1px dashed #090;
    background-color: #cfc;
}
#flo2 {
    margin: 0px 20px 0px 10px;
    float: right;
    width: 150px;
    height: 200px;
    border: 1px dashed #090;
    background-color: #cfc;
}
#abs2 {
    position: absolute;
    width: 150px;
    height: 100px;
    top: 120px;
    left: 100px;
    border: 1px dashed #990;
    background-color: #fdd;
    opacity: 0.6;
}
#rel1 {
    position: relative;
    border: 1px dashed #996;
    background-color: #cff;
    margin: 0px 10px 0px 10px;
    text-align: left;
} 

この例では、SPAN#1とDIV#4が位置指定なしですので、位置指定要素のDIV#1、浮動ブロックのDIV#2、DIV#3はDIV#4よりも手前に表示されています。

また、DIV#1、DIV#5、DIV#6は位置指定要素なので、浮動ブロックのDIV#2やDIV#3よりも手前に表示されています。

z-index の使用

要素の重ね合わせ順を独自に定義したい場合、z-index プロパティを使用します。z-index プロパティには、整数値 (正の数、ゼロ、負の数)を指定することで、Z軸方向の要素の位置を指定できます。値が小さいほど画面の奥方向に、値が大きいほど画面の手前方向に配置されます。

なお、z-index の値が重複した場合は、「 z-index の指定がない場合」のルールに基づいて配置されます。

サンプル

<body>
    <div id="abs1">
        <b>DIV #1</b>
        <br />position: absolute;
        <br />z-index: 5;
    </div>
    <div id="rel1">
        <b>DIV #2</b>
        <br />position: relative;
        <br />z-index: 3;
    </div>
    <div id="rel2">
        <b>DIV #3</b>
        <br />position: relative;
        <br />z-index: 2;
    </div>
    <div id="abs2">
        <b>DIV #4</b>
        <br />position: absolute;
        <br />z-index: 1;
    </div>
    <div id="sta1">
        <b>DIV #5</b>
        <br />no positioning
        <br />z-index: 8;
    </div>
</body>
body{
    margin: 2.0rem;
}
div {
    padding: 10px;
    opacity: 0.7;
    text-align: center;
}
b {
    font-family: sans-serif;
}
#abs1 {
    z-index: 5;
    position: absolute;
    width: 150px;
    height: 350px;
    top: 10px;
    left: 10px;
    border: 1px dashed #900;
    background-color: #fdd;
}
#rel1 {
    z-index: 3;
    height: 100px;
    position: relative;
    top: 30px;
    border: 1px dashed #696;
    background-color: #ffc;
    margin: 0px 50px 0px 50px;
}
#rel2 {
    z-index: 2;
    height: 100px;
    position: relative;
    top: 15px;
    left: 20px;
    border: 1px dashed #696;
    background-color: #cfc;
    margin: 0px 50px 0px 50px;
}
#abs2 {
    z-index: 1;
    position: absolute;
    width: 150px;
    height: 350px;
    top: 10px;
    right: 10px;
    border: 1px dashed #900;
    background-color: #fdd;
}
#sta1 {
    z-index: 8;
    height: 70px;
    border: 1px dashed #996;
    background-color: #ffc;
    margin: 0px 50px 0px 50px;
}

このサンプルでは、5つの <div> 要素が <body> 要素の直下に並んでいて、<body> 要素が1つの重ね合わせコンテキストとなっています。

同じ重ね合わせコンテキストの中で、z-index プロパティが使用されているので、z-index プロパティの値が大きい要素が手前に表示されています。

ただし、DIV#5 に関しては、position 要素が指定されていません。つまり、位置指定要素ではないので、z-index プロパティを指定しても効力を持ちません。

長くなったので、複数の重ね合わせコンテキストが絡む場合のサンプルは次の記事で掲載します

 


このサイトでは、CSSのセレクタ・プロパティなどの定義は下記サイトを参考にしています。
MDN Web Docs: https://developer.mozilla.org/ja/
W3C仕様の正確な定義、最新情報は上記サイトをご覧ください。
CSSのプロパティがどのブラウザに対応しているのかは、下記のサイトで確認できます。
Can I Use?: https://caniuse.com/#home

コメント

タイトルとURLをコピーしました