どうも、くまだです。
CSSのisolation: isolateについて。
isolation: isolate
isolation: isolate;は自分を新しいスタッキングコンテキストにするプロパティです。
スタッキングコンテキストとは、重なり順を管理するグループのようなものです。同じグループ内でしか z-index は比較されません。
<section class="pattern-block">
<div class="pattern-block__columns">
<div class="pattern-block__column">
<div class="pattern-block__caption" data-status="before">before:<code>.isolation-wrapper</code> に isolation なし</div>
<div class="blend-stage" data-stage="case2-before">
<div class="big-square">
<div class="isolation-wrapper">
<div class="small-square">small-square (difference)</div>
</div>
</div>
</div>
</div>
<div class="pattern-block__column">
<div class="pattern-block__caption" data-status="after">after:<code>.isolation-wrapper</code> に <code>isolation: isolate</code></div>
<div class="blend-stage" data-stage="case2-after">
<div class="big-square">
<div class="isolation-wrapper" data-isolation="on">
<div class="small-square">small-square (difference)</div>
</div>
</div>
</div>
</div>
</div>
</section> * { box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Yu Gothic UI", sans-serif;
padding: 24px;
max-width: 1200px;
margin: 0 auto;
background: #f5f5f7;
color: #222;
line-height: 1.6;
}
h1 { font-size: 1.4rem; margin-bottom: 6px; }
h2 { font-size: 1.1rem; margin-top: 0; }
.intro {
color: #666;
font-size: 0.85rem;
margin-bottom: 24px;
}
.intro code {
background: #eee;
padding: 1px 5px;
border-radius: 3px;
font-size: 0.8rem;
}
.pattern-block {
background: #fff;
border: 1px solid #e0e0e0;
border-radius: 10px;
padding: 20px;
margin-bottom: 28px;
}
.pattern-block__columns {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
}
.pattern-block__column {
border: 1px solid #e0e0e0;
border-radius: 8px;
overflow: hidden;
}
.pattern-block__caption {
padding: 8px 12px;
font-size: 0.8rem;
font-weight: bold;
}
.pattern-block__caption[data-status="before"] {
background: #fde8e8;
color: #c0392b;
}
.pattern-block__caption[data-status="after"] {
background: #e3f7e7;
color: #1f7a3d;
}
/* ============================================================ */
/* mix-blend-mode の合成範囲(MDN 公式例ベース) */
/* big-square (lime) > isolation 親 > small-square (lime + difference) */
/* 期待: */
/* isolation なし → 合成が祖先 big-square (lime) まで遡る → */
/* lime - lime = 黒 */
/* isolation あり → 合成が isolation 親内で完結 → */
/* 親背景なし → 別の色(lime - 白系) */
/* ============================================================ */
.blend-stage {
position: relative;
height: 240px;
overflow: hidden;
}
.big-square {
width: 100%;
height: 100%;
background: #00ff00; /* lime(緑)祖先要素の背景 */
display: grid;
place-items: center;
padding: 20px;
}
.isolation-wrapper {
position: relative;
width: 160px;
height: 160px;
}
.isolation-wrapper[data-isolation="on"] {
isolation: isolate;
}
.small-square {
position: absolute;
inset: 30px;
background: #00ff00; /* 親 big-square と同じ lime */
mix-blend-mode: difference;
display: grid;
place-items: center;
color: white;
font-size: 0.8rem;
font-weight: bold;
text-shadow: 0 0 4px black;
}
isolation なしの状態では、.small-square の mix-blend-mode: difference は、合成範囲が祖先 .big-square まで遡ります。同じ lime 同士の difference 合成なので、結果は黒(lime – lime = 黒)になります。
isolation を .isolation-wrapper`に付けた状態の場合、.small-square の合成範囲は .isolation-wrapperの中に限定されます。.isolation-wrapperには背景色を付けていないので、祖先 .big-square (lime) と直接合成されなくなり、.small-square は元のime 色で表示されます。
isolation: isolate がいちばん活躍するのは、コンポーネント内の z-index が外側の z-index 体系に干渉するのを防ぎたいときです。
ここまで読んでくださりありがとうございました。