CSSとSVGで曇りガラスのような効果を作る
公開:
更新:
2011年の9月に「CSSとSVG filterでガラスっぽい効果をつける」というのを書きましたが、これはFirefoxのみを対象としたものでした。 Frosted glass effect with CSS & SVG 背景画像にはWetFoto.comによる#246 Wetlook with Beautiful Brunette in Leggings and Jacket. Girl in black jacket, white wetlook leggings and skirt in boots, get wet fully clothed in the sea.を使用しています(リンク先はFlickrです)。 背景画像にはBeryl Chanによる「Bunny - Rainy」を使用しています(リンク先はFlickrです)。 デスクトップブラウザはIE 10, Firefox 19, Chrome 25, Opera 12.14で期待通りに表示されます。 モバイルブラウザはAndroid 4.1で確認したところ、Firefox 19, Opera Mobile 12.1で期待通りに表示されます。 完成コードの主な部分は次のようになっています。 CSSの部分で「SVG Image Data URI」と書かれているものは次のようなSVGです。 「SVG Filter Data URI」と書かれているものはこれ。前のものから 基本的には以前作ったものと同じなんですが、複数のブラウザに対応するためにやったことについて説明してみます。 まず、フィルタ効果と対応ブラウザについて。 IE 9以下にはDX Filterがありますが、ぼかし効果の挙動がよく分からないので諦めました。 はじめはこのSVGだけで大丈夫だと思っていたんですが、CSSで読み込むSVGの外部リソースはセキュリティの関係上FirefoxとChromeでは無視されます。IE 9, 10とOperaは大丈夫。 複数指定の IE 10とOperaは読み込むSVGでフィルタを適用済み、且つCSSからフィルタをかけることができません。 以上がモダンブラウザへの対応です。 次はIE 8への対応。 他の仕組みはほとんど前と同じなのでそちらを参照してください。 2020年1月11日 追記:
そこで今回はできるだけ多くのブラウザに対応したものを作ってみます。完成品
この画像はCC BY-NC-SA 2.0でライセンスされています。
この画像はパブリックドメインです。
IE 8, 9はぼかし効果なしです。IE 7以下向けには書いていないので未確認。
Safari 6は未確認。
Chrome for Android 25はぼかし効果はかかるものの、background-position: fixed
の挙動がおかしくてちゃんと表示できません。
Android Browserではぼかし効果なしで表示されます。
Mobile Safariは未確認。<div class="header glass">
<!--[if lt IE 9]>
<div class="legacy-ie-fix"></div>
<![endif]-->
<h1>WET</h1>
</div>
html {
background-image: url("bg.jpg");
background-position: center bottom;
background-attachment: fixed;
background-size: cover;
height: 100%;
font-size: 100%;
}
body {
margin: 0;
}
.glass {
position: relative;
border-bottom: 1px solid;
border-bottom-color: #ccc;
border-bottom-color: rgba(255, 255, 255, 0.2);
background-color: rgba(255, 255, 255, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
}
.glass::before {
position: absolute;
top: 0;
left: 0;
z-index: -1;
width: 100%;
height: 100%;
background-image: url("data:image/svg+xml,(SVG Image Data URI)"), url("bg.jpg");
background-position: center bottom;
background-attachment: fixed;
background-size: cover;
content: "";
filter: url("data:image/svg+xml,(SVG Filter Data URI)#blur");
-webkit-filter: blur(5px);
filter: blur(5px);
}
.glass .legacy-ie-fix {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #fff;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=20)";
}
.glass h1 {
position: relative;
margin: 0;
color: #fff;
color: rgba(255, 255, 255, 0.3);
font-size: 200px;
font-weight: normal;
font-family: "Megrim", sans-serif;
line-height: 1.2;
text-align: center;
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(opacity=50)";
}
@media only screen {
.glass h1 {
-ms-filter: "none";
}
}
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1600" height="1066">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5"/>
</filter>
</defs>
<image xlink:href="http://unformedbuilding.com/demo/2013/frosted-glass-effect/bg.jpg" width="1600" height="1066" filter="url(#blur)"/>
</svg>
image
要素を消したものですね。<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<filter id="blur">
<feGaussianBlur stdDeviation="5"/>
</filter>
</defs>
</svg>
解説みたいなもの
.glass::before
の部分。background-image
にbg.jpgを読み込んでフィルタをかけたSVGとbg.jpgを指定している理由について。
これがどうなるのかというと、FirefoxとChromeでは何もない透明なSVGが読み込まれます。IE 10とOperaでは、画像にフィルタをかけたSVG画像が読み込まれます(IE 9はフィルタなし)。background-image
は書いた順に上位のレイヤーとなるので、IE 9, 10とOperaでは2つ目の指定url("bg.jpg")
は最初に読み込んだSVGに覆い隠されて見えなくなります。
そしてimage
要素が無視されるFirefoxとChromeでは、2つ目の画像が表示されます(実際には透明なSVG画像が上にかぶさってますが)。
FirefoxはData URIとして読み込んだSVGフィルタを適用し、背景画像をぼかします。
Chromeも同様にCSSフィルタを適用します。
あくまでも現状での動作なので、IE 11でSVGの外部リソースが無視されるようになったりしたらアウトです。
IE 8はrgba()
指定に対応していないので、DX Filterによる不透明度指定でそれっぽくしておきます。
ただし、DX Filterは擬似要素に適用できませんので、IE 8向けに空のdiv
を作ってあげます。他のブラウザに影響を与えないようにコンディショナルコメントによる指定も行います。
また、IE 8はダブルコロンの擬似要素セレクタに対応していないので、.glass::before
の部分にあるルールセットを無視しますが、あんまり関係ないのでそのままで。
あとは他のブラウザと似たような感じになるように背景色と不透明度調整のフィルタをかけます。.glass h1
の部分ですが、文字を半透明にするためにここでもDX Filterを使っています。
が、これは IE 9も解釈してしまうので、その直後にIE 9では取り消すよう指定を行います。
IE 8が@media
のonly
キーワードを解釈しないことを利用して-ms-filter
の指定を取り消します。
当初「#246 Wetlook with Beautiful Brunette in Leggings and Jacket. Girl in black jacket, white wetlook leggings and skirt in boots, get wet fully clothed in the sea.」という写真を使っており、記事の公開時点では、その画像はCC BY-NC-SA 2.0でライセンスされていました。
しかし、現在ではAll rights reservedに変更されているため、デモで使用している画像と、記事内の画像を差し替えました。