ブログ
mix-blend-modeとスタックコンテキスト
CSSのmix-blend-mode
を使うと、重なり合った要素同士の色の合成方法を設定できます。これによりPhotoshopなどのグラフィックツールにあるブレンド機能と同じような効果を実現できます。
See the Pen mix-blend-mode basic by Yuhei Yasuda (@yuheiy) on CodePen.
背景にグラデーションを設定し、ブレンドしたい要素にはmix-blend-mode
を適用するだけで同じ見た目を実現できます。今回は画像に適用します。
.wrapper {
background-image: linear-gradient(to bottom, yellow, red);
}
img {
mix-blend-mode: multiply;
}
Chromeには<body>とその子孫要素をブレンドできないというバグがあります。そのためページ全体の背景と合成したいというような場合でも、<body>の直下に余分な<div>を作って背景を指定するような処置が必要になります。
このような単純な例を見るととても簡単に扱えるプロパティに見えますが、要素同士がブレンドされる範囲について知っておかなければハマりどころになることがあります。
See the Pen mix-blend-mode stacked by Yuhei Yasuda (@yuheiy) on CodePen.
これは最初のデモに対して、画像を配置するグリッド要素(以下グリッド要素と呼びます)にtransform: rotate(-2deg)
を適用して傾けたものです。デモでは、背景のグラデーションと画像がブレンドされていません。これはグリッド要素がスタックコンテキストを形成しているためです。
スタックコンテキストとは、ウェブページ上で特定の条件を満たした要素によってZ軸に形成される階層構造のことです。詳しくはz-index再入門 - z-indexの仕組みを参照してください。
transform
にnone
以外の値が適用されている要素はスタックコンテキストを形成します。
mix-blend-mode
の仕様が含まれているCompositing and Blending Level 1には、3.2. Behavior specific to HTMLで次の記述があります。
An element that has blending applied, must blend with all the underlying content of the stacking context [CSS21] that that element belongs to.
つまり要素同士がブレンドされるためには、いずれの要素も同じスタックコンテキストに属している必要があります。ブレンドは、ブレンドモードが適用された要素が属するスタックコンテキストの中でのみ行われるからです。
先ほどのデモにおいては、ブレンドモードが適用された画像が属するスタックコンテキストはグリッド要素でした。すると、ブレンドの対象に含まれるのはグリッド要素およびその子孫要素のみです。そのため背景のグラデーションと画像はブレンドされなかったというわけです。
See the Pen mix-blend-mode stacked hacks by Yuhei Yasuda (@yuheiy) on CodePen.
対して、このデモでは先ほどと同じくグリッド要素がスタックコンテキストを形成していますが、画像はブレンドされています。これはグリッド要素にラッパー要素と同じ背景を適用しているためです。
.wrapper {
background-color: yellow;
}
.grid {
background-color: yellow;
transform: rotate(-2deg);
}
img {
mix-blend-mode: multiply;
}
一見無意味に見えるこのハックのおかげで、実質的にラッパー要素の背景と画像がブレンドされた見た目を実現することができます。
ただし、背景が単色でなければ同じアプローチを取るのが難しいという制約があります。mix-blend-mode
の持ち味を活かしきれていない感があり残念ですが、これだけでも便利になる場面はあるはずです。
背景色を適用する範囲を制限することで部分的にブレンドすることもできます。
See the Pen mix-blend-mode stacked hacks 2 by Yuhei Yasuda (@yuheiy) on CodePen.
使いどころが難しいですが、もしかすると効果的な表現をするために役立てられるかもしれません。