W3CのFilter Effects Module Level 2で導入された、CSSのbackdrop-filterプロパティについて解説します。特に構文、ブラウザーの対応、応用方法を取り上げます。
デモを含め、記事中のすべての画像の出典はPixabay.comです。
Backdrop-filterは従来のfilterプロパティとは別物
CSSフィルターのことは、よく知っているでしょう。おさらいをするなら『Photoshopはもういらない?明度も彩度も超手軽に変えられるCSSフィルターがスゴい』がおすすめの記事です。
従来のfilterプロパティは指定した要素にぼかし(blur)やセピアなどの効果を加えられます。一方で、backdrop-filterプロパティは要素の背後の領域に同じような効果を加えるものです。filterとbackdrop-filterプロパティの違いが分かるデモを以下に掲載します。Chromeブラウザーの「Experimental Web Platform features(試験運用中の機能)」フラッグを有効にするなど、各ブラウザーで対応してください。ブラウザーの対応状況については後述します。
デモの上の画像はフィルターが全体に適用されていますが、下の画像はテキスト部分の背景だけにフィルターが適用されています。ここで強調したいことは、フィルター効果は「この要素自体」の背景に適用されているのではなく、「この要素の下に位置する別の要素」に対して適用される、という点です。したがって、フィルターを適用する要素の背景を透明にしておかなければなりません。
構文とブラウザーの対応状況
backdrop-filterプロパティは、使い慣れたfilterプロパティと多くの点で共通しています。以下の構文で、どのような要素にも適用できます。
backdrop-filter: <filter-function> [<filter-function>]* | none
filterプロパティと同様に、要素の背景にいくつものフィルターを適用できます。filterプロパティで使える値は、すべてbackdrop-filterプロパティでも同じように使えます。アニメーション表示もできるのです。
この2つのプロパティは良く似ているものの、filterプロパティと違ってbackdrop-filterプロパティは、多くのブラウザーがまだ対応していません。現時点ではSafari 9だけが特別なフラグ設定をせずに使えますが、-webkit-プレフィックスを使わなければいけません。
ChromeとOperaの場合、chrome://flagsの「Experimental Web Platform Features(試験運用中の機能)」を有効にします。FirefoxとEdgeは、backdrop-filterプロパティをまったくサポートしていません。さらに詳しいブラウザー対応はCan I useで一覧できます。
Backdrop-filterを使う
backdrop-filterプロパティを正しく適用するには少なくとも2つの要素が必要です。1つはターゲット要素、もう1つはその下に置く別の要素で、下に置いた要素に対してフィルター効果が表れます。上のデモで背景に効果をつけるために、以下のタグを使っています。
<div class="backdrop">
<div class="content">
<h3>A Heading</h3>
<p>Some random text related to the heading.</p>
</div>
</div>
さらに、次のCSSで要素の背後にフィルターをかけ、テキスト部分の背景をセットしました。
.backdrop {
background: url('path/to/image.jpg');
}
.content {
position: relative;
top: 30%;
background: rgba(100,150,100,0.35);
backdrop-filter: hue-rotate(180deg);
}
backdrop-filterプロパティのおもしろい使い方として、1つの画像の別々の部分に、別々のフィルターを使えることです。画像全体に何種類ものフィルターを同時にかける、という意味ではありません(それも可能です)。ここで言いたいのは、たとえば画像の左側にはgrayscaleフィルターをかけ、右側にはsepiaフィルターをかける、あるいは画像をいくつもの部分に分割してそれぞれに値の異なるhue-rotateを適用する、といったことです。方法は対象要素の不透明度opacityをゼロ(透明)に設定することで、下にあるフィルター効果を付けたい要素が隠れないようにします。
必要なHTMLは次のようになります。
<div class="backdrop">
<div class="target a">
</div>
<div class="target b">
</div>
....
</div>
以下がCSSです。
.target {
position: absolute;
top: 0%;
height: 100%;
width: 20%;
opacity: 0;
}
.a {
left: 0%;
backdrop-filter: hue-rotate(30deg);
}
.b {
left: 20%;
backdrop-filter: hue-rotate(90deg);
}
/* Filters for other sections of the image */
最終的な結果は次のようになります。
最終的な画像の見栄えは選んだフィルターや画像次第ですが、backdrop-filterプロパティをうまく使うと本当に素敵な効果を発揮できます。どのようなものができあがるか、いろいろなフィルターを試してください。
また対象要素の各プロパティに、アニメーション効果を付けられます。たとえば次のデモでは画像の上に2つのdivがあり、それぞれに別々のフィルターを適用しています。
画像にカーソルを乗せると、0.5秒の間に最初のdivの幅ともうひとつのdivの高さが0%から80%まで変化します。結果、画像が4つのセクションに分かれ、それぞれに別々のフィルターが適用されます。
別の方法として、SVGフィルターを使って対象要素に適用したフィルターをアニメーション化します。
応用
backdrop-filterプロパティで素敵なフィルターが作れるのはすばらしいのですが、実践的な応用方法もたくさんあります。このプロパティを知ったときすぐに頭に浮かんだのは、画像をぼかすことで、完全なグラフィックコンテンツを見せる前に、ユーザーに予告ができないかということでした。
最初に必要なHTMLはこちらです。
<div class="graphic-content">
<img src="path/to/graphic/image.jpg">
<div class="warning">
<p>Click on the button below to see the image from the murder scene.</p>
<button>Show Me</button>
</div>
</div>
ここではぼかしたい画像と、予告のテキストの両方をひとつのdivに収めました。予告のテキストは、画像と同じ幅と高さをもつ別のdivに入れてあります。
画像にぼかし効果を付けるCSSは以下です。
.warning {
background: rgba(0,0,0,0.75);
backdrop-filter:contrast(4) blur(20px);
}
どのような背景色やフィルターが調和するか、いろいろと試してください。デモでは「Show me」ボタンがクリックされたあと予告のテキストを隠すため、JavaScriptも加えています。
backdrop-filterプロパティの使い道は、モーダルウィンドウを表示するときに背景をぼかしたり、オフキャンバスメニューを表示したときに背景をぼかしたりできます。別の使い方として、Mediumで使われているように、Webページが完全に読み込まれるまでは画像をぼかしておくという手法もあります。
最後に
backdrop-filterプロパティのおかげで、従来JavaScriptが必要だったいろいろな効果が表現できます。しかし本番で使うのは、ブラウザー側の対応が十分に整うまで待ったほうが良いでしょう。もう1つ考慮しなければならないのは、パフォーマンスです。このプロパティをWebページの広範囲あるいは大量の要素に対して使うと、パフォーマンスが低下します。
backdrop-filterプロパティについての、さらに詳しい情報はW3CのドラフトやMDNのドキュメントから入手できます。
(原文:Create Stunning Image Effects with CSS Backdrop-filter)
[翻訳:西尾健史/編集:Livit]