Glassmorphism(グラスモーフィズム)に興味があります。
このデザインに欠かせないのが、backdrop-filter: blur()です。
透明度を調整した背景色(rgba(255,255,255,0.3)等)にbackdrop-filter: blur() を追加すると、Glassmorphismデザインになります。
このデザインについては、photoshopvipのページが大変参考になります。
ジェネレーターも紹介されています。
しかし今回のテーマは、Glassmorphismについてではなく、backdrop-filterプロパティの関数についてです。
このプロパティの関数にはblur()以外にも複数あり、気になっていたのでこれらの関数を調査し、実際に画像を使って検証してみました。
backdrop-filterとは
backdrop-filterは、CSSのプロパティで、要素の背後の領域に、ぼかしや色変化のようなグラフィック効果を適用することができます。要素の背後のすべてに適用されるため、効果を見るためには少なくとも一部が透明な要素またはその背景を作成する必要があります。
MDN カスケーディングスタイルシート backdrop-filter より引用
Photoshopで編集するようなことが(もちろん全てはカバーできないですが)、CSSでもある程度可能です。
残念ながら、引用させていただいたページを開いても、実際のグラフィック効果を目で見て確認できるのは、backdrop-filter: blur()だけです。
backdrop-filterプロパティとfilterプロパティの違い
同じようなCSSプロパティにfilterというものがあります。
例えば、filter: drop-shadow(2px 4px 6px black); のように、要素に影を付けたい時によく使用されます。
このプロパティとの違いは、フィルターをかける対象です。
filterはCSSのプロパティで、ぼかしや色変化などのグラフィック効果を要素に適用します。フィルターは画像、背景、境界の描画を調整するためによく使われます。
MDN カスケーディングスタイルシート filter より引用
backdrop-filterプロパティの関数の種類
関数 | 説明 | 値(引数)の単位 |
blur | 背景画像をぼかします。 値が大きくなる程ぼかしが大きくなります。 | px、em、rem等 の長さ |
brightness | 背景画像の明度を調整します。 0%では背景は黒くなってしまいます。 100%では元の画像と同じ明度になります。 よって、100%以上の値の指定も可能です。 | % |
contrast | 背景画像のコントラストを調整します。 0%では背景はグレーになってしまいます。 100%では元の画像と同じコントラストになります。 よって、100%以上の値の指定も可能です。 | % |
drop-shadow | 背景画像に影をつけます。 影の幅・高さ・ぼかしの長さ・色を指定可能です。 | 長さと色 |
grayscale | 背景画像をグレースケールにします。 0%では元の画像と同じになります。 100%ではモノクロのようになります。 | % |
hue-rotate | 背景画像の色の色相環を回転します。 色相環とは色みを近い順に変更し環にしたものです。 色相環で検索するとたくさん出てきます。 色相環の反対側の色が補色です(例えば赤と緑、黄と青紫等)。 0deg及び360degでは元の画像のままです。 | 色相の回転角度deg |
invert | 背景画像の色を反転します。 反転色は補色と似ていますが、こちらはRGB方式で計算されます RGBカラーのそれぞれの値を全て反転計算したものになります。 0%では元の画像と同じ、100%で完全に反転されます。 | % |
opacity | 背景画像の透明度を調整します。 0%で完全に透明、100%では元の画像のままです。 | % |
sepia | 背景画像をセピア調にします。 0%では元の画像と同じで、100%まで指定可能です。 100%以上を指定しても100%と変わりません。 | % |
saturate | 背景画像の彩度を調整します。 0%では無彩色(モノクロ)、100%では元の画像のままです。 よって、100%以上の値の指定も可能です。 | % |
これら複数の関数を同時に設定することも可能です。
CODEPENで検証
グラフィック効果の視認性を高めるため、以下の条件で検証してみました。
「Run Pen」をクリックしてください。
検証したボックスは全てで24個ありますが、画面上には収まっていないため、スクロールしてご覧ください。
See the Pen backdrop-filter by blue moon (@blue-moon) on CodePen.
HTMLファイル
一部のみ抜粋しています。
<!-- これより上省略 -->
<li> <!-- 1番目のliタグ、boxの背景色は完全に透明、backdrop-filterは設定なし(初期値) -->
<img src="yourpath" alt="roses">
<div class="box transparent">
<p>background: transparent;</p>
<p>backdrop-filter: initial;</p>
</div>
</li>
<li> <!-- boxの背景色は白に透明度を追加、backdrop-filterは設定なし(初期値) -->
<img src="yourpath" alt="roses">
<div class="box translucent">
<p>background: rgba(255,255,255,0.3);</p>
<p>backdrop-filter: initial;</p>
</div>
</li>
<li class="blur1"> <!-- Glassmorphism(グラスモーフィズム)デザインの要件を満たす -->
<img src="yourpath" alt="roses">
<div class="box translucent">
<p>background: rgba(255,255,255,0.3)</p>
<p>backdrop-filter: blur(2px)</p>
</div>
</li>
<li class="blur2"> <!-- Glassmorphism(グラスモーフィズム)デザインの要件を満たす -->
<img src="yourpath" alt="roses">
<div class="box translucent">
<p>background: rgba(255,255,255,0.3);</p>
<p>backdrop-filter: blur(5px);</p>
</div>
</li>
<!-- これ以降省略、liタグは残り20個あり -->
CSSファイル
一部のみ抜粋しています。
body {
background: #d3f7ff; /* 薄い水色 */
}
ul {
margin: 20px auto 0;
padding: 0;
width: 365px;
display: grid; /* グリッドレイアウトに */
grid-template-columns: 1fr 1fr; /* 横に2つ並べる */
gap: 5px; /* グリッドアイテムの間隔 */
}
/* 途中省略 (liタグ) */
li.drop-shadow1, li.drop-shadow2 {
opacity: 0.99; /* opacityの値を1未満にする */
}
/* 途中省略 (imgタグ) */
.box {
position: absolute; /* 画像の上に重ねるため */
top: 22%; /* 画像からはみ出すように調整 */
left: 8%; /* 画像からはみ出すように調整 */
width: 84%;
height: 72%;
border-radius: 5px;
border: 1px rgba(225,225,225,0.3) solid; /* 透明なボックスにも境界が分かるように透明度のある枠を */
border-bottom: 1px rgba(40,40,40,0.35) solid; /* ボックス下の枠を少し濃く立体感を */
border-right: 1px rgba(40,40,40,0.35) solid; /* ボックス右の枠を少し濃く立体感を */
}
.box.translucent {
background: rgba(255,255,255,0.3); /* 白に透明度を追加、αの値が0.3なので若干白っぽい感じが残る程度 */
}
.box.transparent {
background: transparent; /* 完全に透明 */
}
.blur1 .box {
backdrop-filter: blur(2px);
}
.blur2 .box {
backdrop-filter: blur(5px);
}
/* 途中省略
ここに、.blurクラスの.boxと同じように、18個分の.boxのbackdrop-filterの関数を記述
*/
.multiple1 .box {
backdrop-filter: blur(2px) invert(90%); /* 複数の関数を指定 */
}
.multiple2 .box {
backdrop-filter: sepia(80%) contrast(250%); /* 複数の関数を指定 */
}
/* 以降、pタグ省略 */
補足説明
まず、画像に重ねて配置されているボックス自身の背景色は2種類用意しました。
それが最初の2つで、まだbackdrop-filterプロパティは設定していません。
その後は、これらのどちらかのボックスに(ほとんどのボックスは、最初の完全に透明な背景ですが)、backdrop-filterの関数の値を変更したものを2つずつ作成しています。
よって、値による違いを比較することができると思います。
3つ目と4つ目の画像のボックスでは、Glassmorphismデザインを実現したものです。
ボックスの透明度を調整し重ね合わせると、より面白いデザインになると思います。
そして最後の2つが、複数の関数を設定したものです。
検証した結果気づいたこと(CODEPENには表示していない)
backdrop-filter: drop-shadow(); では、当初グラフィック効果が見られませんでした。
調べてみたところ、背景に透明度が設定されていないと効果が見られないことが判明しました。
そのため、このliタグのみopacityプロパティで、ほとんど周囲が見分けがつかない程度に透明度を追加しています。
backdrop-filter: drop-shadow(); は、透明度のある背景にのみグラフィック効果が得られる、ということにご注意ください。
backdrop-filter: invert(); では、50%ではボックスがグレーになり背景は見えない状態になりました。
そのため、検証用のCODEPENでは、より近い40%を設定しています。
そして、50%より値が大きくなると、またグラフィック効果が得られます。
invertが反転色を意味するものということから、それも納得です。
backdrop-filter: saturate(); では、50%以上になると、はっきりとしたグラフィック効果は見られませんでした(見えづらいだけなのか、背景画像によるのかもしれません)。
drop-filter: hue-rotate(180deg); では、色相環の反対色、つまり補色になっていました。
黄色は青紫系の色に、赤は緑にというようにです。
結果、グラフィック効果が不明なものが
今回の場合、筆者のボックスや画像の配置方法や設定が誤っていたのか、グラフィック効果が見られなかったものが1つありました。
backdrop-filter: opacity(); です。
ボックスの背景色を変更してみたり、背景色に透明度を追加したりと、諸々試してみたのですが、今回の条件では効果は見られませんでした。
今後、原因が分かり次第、追記したいと思います。
ブラウザのサポート状況
Mozillaが提供しているMDNサイトも参考にしていたのですが、 Mozilla社が母体のFirefoxではサポートされていないのです。
MDNにはGoogle、Microsoftも情報を集積し、情報を統合することになった経緯がありました。
参考までに、MDN Web Docs(英語サイトです)。