例えば、サイトのヘッダー画像やギャラリー形式のアーカイブページなどでは、画像の上にサイトタイトルや投稿タイトルとなる文字列を重ねて表示するデザインを施す場合、画像とテキストが同化して見難くならないよう、テキストが白文字ならば画像はbrightness
で明るさを落としたり、白文字が映えるような背景カラーのレイヤー要素を画像にオーバーレイさせるなどの工夫をする場合があります。
今回のケースでは、テキストを色で塗りつぶすのではなく、CSSのみで色を重ね合わせた画像の上に表示されているテキスト(文字列)の形状部分だけ色を切り抜いたようなデザインでテキストを表示する方法をいくつか試してみました。
細かい想定としては、WordPressのテーマオプションとしてサイトのキーカラーを決め、指定したヘッダー画像や個々のアイキャッチ画像にキーカラーを合成させ、その上に表示するタイトルなどのテキスト部分のシェイプだけキーカラーを透過して画像が透けて見えるような感じです。
このため、画像ごとに見やすくなるように個別に微調整をしてCSSを組まなければいけないような手法はNGで、どんな画像でも前面の文字列が見えるような汎用的な手法を考えてみます。
今回チェックした2パターンの結果はこちら。
4アイテムありますが、左側はCSSのブレンドモードを利用した場合、右側は画像をテキストの形状に切り出した場合の表示例で、1行目と2行目で画像を変えてチェックしています。
See the Pen Show text with CSS 3 mix-blend-mode and background-clip by digistate (@digistate) on CodePen.
background-blend-mode と mix-blend-mode を併用
まず思い浮かぶのは、CSSのブレンドモードのためのプロパティを利用すると簡単に表現できそうです。
背景(background
)のブレンドモードを指定するbackground-blend-mode
と、2つの要素が重なり合ったときの見え方(合成の仕方)を指定するmix-blend-mode
があり、この2つのプロパティの組み合わせを調整してみます。
まず、background-image
で画像を指定し、background-color
で同じ要素に背景カラーも指定しておき、background-blend-mode
プロパティで画像と背景カラーを合成します。
そして、テキストには mix-blend-mode:overlay
を指定します。
表示結果
background-blend-mode
の値は、画像にもよりますが色々試した中ではoverlay
が想定する利用シーンにおいて一番無難な様子。
背景画像要素のCSS
.image{ background-position:center; background-size:cover; background-image:url(画像のURL); background-color:#449dad; background-blend-mode:overlay; }
切り抜くテキスト要素のCSS
.text{ color:#962719; mix-blend-mode:overlay; }
background-blend-mode
のそれぞれの値の比較は以下をご覧ください。
See the Pen background-blend-mode patterns by digistate (@digistate) on CodePen.
これらのうち、hue、saturation、color、luminosityについてはSafari、iOS版SafariとChromeにて利用できません。
最新のブラウザ対応状況はこちら。
background-blend-mode と mix-blend-mode の併用の問題
background-blend-mode
と mix-blend-mode
の組み合わせは、同じ設定でも画像内の色の変化や明暗の差が多い画像では、前面のテキストが見えにくくなってしまいます。
というわけで、MS系のブラウザが全滅な上に汎用的にはとても利用できないため、background-blend-mode
とmix-blend-mode
の組み合わせは却下。
-webkit-background-clipで背景画像をテキストの形状に切り出す
背景要素のbackground-blend-mode
とテキストの mix-blend-mode
の組み合わせは画像によってテキストの視認性が左右されるため、仕方なく背景画像には::before疑似セレクタを利用して透過度を持たせたカラーレイヤーを重ねてみます。
さらにその上に表示されるテキストの要素(figcaption
)は、直前にある背景要素のサイズと大きさを同じにして、さらに同じ背景画像(background-image
)を指定します。
最後にポイントとなるのが、最前面にくるテキストの要素には -webkit-background-clip
というプロパティに text
キーワードを指定します。
これにより、背景画像のテキスト部分のみが切り出された状態になります。
ちなみに、このプロパティはFireFoxであっても、-moz-background-clip
ではなく、webkitのベンダープリフィクスを付けないと反映されません。
これら、背景要素、背景カラーレイヤー、テキストの重なり(位置関係)をわかりやすく3次元で可視化してみると、このような状態です。
See the Pen Structure of background-clip:text by digistate (@digistate) on CodePen.
表示結果
この方法であれば、どのような画像でも前面のテキストの視認性は保てそうです。
それぞれの要素のCSSは以下の構成となります。
背景画像要素のCSS
.image { width: 100%; height: 100%; background-size: cover; background-position: center; background-image:url(画像のURL); }
背景画像のカラーレイヤー用CSS
.image::before { position:absolute; top:0; left:0; width:100%; height:100%; content: ''; background-color: #13c5fd; opacity: .72; /* 不透明度 */ }
テキスト要素のCSS
.text { background-size: cover; background-position: center; background-image:url(画像のURL); -webkit-background-clip: text; color: rgba(0, 0, 0, 0.24); /* 完全に透過する場合は、transparent */ }
Internet Explorer 10以降 と Edge対策
毎度のことながら、、IEとEdgeはやはりbackground-clip:text
など解釈してくれないため、画像(background-image
)だけが表示されてしまい、テキストが見えません。
IE9以下は考慮せず、IE10, 11そしてEdgeについてはCSSハックを利用して、画像とカラーレイヤーを重ねた上に不透明度を指定したテキストを表示するようにします。
IE10, 11そしてEdgeのみにCSSを適用するには、以下のCSSハックの書式で記述します。
_:-ms-lang(x), .selector { property:value }
IE10, 11, Edge用のCSS
/* カラーレイヤーを生成 */ _:-ms-lang(x), .image::before{ position:absolute; top:0; left:0; width:100%; height:100%; content:''; background-color:#13c5fd; opacity:.42; } /* background-clip:textが効かないため、背景を無効化 */ _:-ms-lang(x), figcaption{ background-image:none; } /* テキスト */ _:-ms-lang(x), figcaption p{ color:rgba(255,255,255,.68); }
IE10, 11、 Edgeでの表示
IEとEdgeはさておき、本来利用したかった background-blend-mode
と mix-blend-mode
の組み合わせではなく、少々強引なやり方で-webkit-background-clip:text
を利用したパターンなのでスマートではないかもしれませんが、視認性を考えるとこの方法が汎用的に利用できそうです。