WWW Watch

CSS filter プロパティで 「半透明ガラス」 効果を再現してみる

iOS 7 で採用された半透明ガラスを重ねたようなレイヤー効果を、CSS filter プロパティを使って再現できないか簡単に試してみたので紹介。デモページで実際の動作を確認できます。

2つ前の記事、「Chrome Canary が dialog 要素に対応、ダイアログボックスの表示が簡単に」 で、::backdrop 疑似要素に色々スタイル当てて遊んでたとき、::backdrop 疑似要素に対しては半透明の白いレイヤーになるようにスタイル当てて、その上で、CSS filter プロパティを使って画面全体をぼやかしたら、iOS 7 (Windows Aero ...) とかで使われてる、所謂 「半透明ガラス」 っぽい効果が出せるんじゃね? と思ってやってみました。

実際に iPhone の Safari で表示してみた例が下記の画像です。

「半透明ガラス」 効果の例

ただし、dialog 要素や ::backdrop 疑似要素を使っちゃうと、現時点では Chrome Canary で、さらにフラグを立てないと動作しないっていう、ほとんどの人が試せない状態になってしまうので、今回は div 要素を JavaScript と CSS でレイヤーっぽく表示する方法を採用しています。

これで、CSS filter プロパティに対応している (ベンダプレフィックスは必要だけど) Chrome や Safari であれば動作します。Opera も Opera Next であれば期待通りに動作するはず。

とりあえず、デモページを下記に置いておきます。最新の Chrome か Safari、あるいは Opera Next で確認してみてください。それ以外だと CSS filter プロパティが動作しないのでぼかしが適用されません。「Open Dialog」 を押せば半透明ガラス的なレイヤーが表示されます。

ソースコードの解説

HTML は単純です。初期表示のレイヤーと、ダイアログ表示時に上にかぶせるレイヤーの 2つをそれぞれ、div.backgrounddiv.backdrop として用意しています。

<div class="background">
 <div>
  <button id="show">Open Dialog</button>
 </div>
</div>
 
<div class="backdrop">
 <button id="close">Close</button>
</div>

CSS も特に難しいことはしていませんが、今回はブラウザウィンドウいっぱいにレイアウトしたかったので、下記のように div.background 内の div 要素に背景画像を指定し、ブラウザウィンドウサイズにフィットさせています。

.background div {
  background: url(image.jpg) no-repeat center center fixed;
  background-size: cover;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

で、ダイアログの表示 / 非表示切り替えには jQuery を使用して簡単に。下記のような単純なソースコードで、ボタンクリック時に div.background に対して dialog という class 名を付与しています。

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script>
 $('#show').click(function() {
  $('.background').addClass('dialog');
 });
 $('#close').click(function() {
  $('.background').removeClass('dialog');
 });
</script>

そして、div.background に対して dialog という class 名が付いたときに、下記のスタイルが適用されるように指定します。

.background.dialog {
  -webkit-filter: blur(10px);
  filter: blur(10px);
}
.background.dialog #show {
  display: none;
}
.background.dialog + .backdrop {
  display: block;
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.3);
}

filter プロパティについて

filter プロパティは、Filter Effects 1.0 仕様内で策定が進められている CSS プロパティで、要素に対して様々なエフェクトをかけることができます。

現在の仕様では、下記のようなフィルターが定義されています。

  • grayscale() : グレースケール
  • sepia() : セピア
  • saturate() : 彩度
  • hue-rotate() : 色相(色相環の回転)
  • invert() : 反転
  • opacity() : 透明度
  • brightness() : 明るさ
  • contrast() : コントラスト
  • blur() : ぼかし
  • drop-shadow() : ドロップシャドウ
  • custom() : カスタムエフェクト

わかりやすいところでいうと、filter: opacity(50%); のように指定することで、opacity: 0.5; と指定したのと同じようなエフェクトを適用できます。

今回使用したのは、ぼかしを適用する blur() です。具体的な指定は下記の通り。

.background.dialog {
  -webkit-filter: blur(10px);
  filter: blur(10px);
}

ダイアログが開いた状態で、div.background をぼかします。これに背景色を半透明の白色にした div.backdrop を重ねてやることで、半透明ガラスのような効果を出します。


ということで、あとはデモページのソースコードを見ていただければわかると思いますので、試してみてください。

たいして検証せずに短時間で書いてるのでソースコード的にはあまりきれいじゃないとは思いますが、応用すれば色々とできそうですし、何かしらのヒントになれば幸いです。

dialog 要素や ::backdrop 疑似要素が使えるようになれば

::backdrop 疑似要素が使える環境であれば、dialog という class 名を付ける対象を html 要素にしてしまって、下記のように指定すれば、画面全体をぼかすことができるので楽です。

html.dialog {
  -webkit-filter: blur(10px);
  filter: blur(10px);
}
dialog::backdrop {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.3);
}

ただ、iOS 7 のコントロールセンターように、画面の半分だけに半透明のガラスレイヤーをかぶせた感じとかは、ちょっと再現が難しいというか、CSS では再現する方法が思い浮かびません......

関連エントリー

Recent Entry

全ての記事一覧を見る

Hot Entry

逆引きおすすめエントリー