CSSフィルタことはじめ

#CSSフィルタサンプル作成
　今更ながらですが、CSSフィルタに興味があり、サンプル作成がてら調べてみました。作成したサンプルは下記になります。

<img src="https://qiita-image-store.s3.amazonaws.com/0/51038/d74c10df-aa5b-7608-b7c6-fd3e551fb2d1.png" alt="CSSフィルタデモ" width="300px" height="350px" />

わりと簡単に作成でき、かなり効果があるエフェクトをかけられるのは、正直びっくりしました。

例えば、セピアにしてみたいなと思ったら、下記のようにfilterプロパティにエフェクト関数を指定するだけみたいです。

```html:CSSフィルタ
filter:sepia(100%);
```

セピア100%の画像はこんな感じになります。
<img src="https://qiita-image-store.s3.amazonaws.com/0/51038/d027fe49-b318-178c-ad8a-238f23779e65.png" alt="CSSフィルタデモ" width="300px" height="350px" />

#対応ブラウザ
　最近、対応するブラウザが増えてきてはいますが、ベンダープレフィックスなしでは動作しないみたいです。私も念のため、PC、スマホに搭載されるブラザで確認してみましたが、やはりベンダープレフィックスは必要みたいです。
ベンダープレフィックスを付ける場合は下記のようになります。

```html:CSSフィルタ
-webkit-filter:sepia(100%);   // for Google Chrome and Safari
-moz-filter:sepia(100%);      // for Firefox
-o-filter:sepia(100%);        // for Oper
-ms-filter:sepia(100%);       // for Internet Explorer
```

但し、ベンダープレフィックスを付けても動作しないブラウザがあるので、ご注意下さい。
CSSフィルタに対応しているブラウザとそのバージョンは下記の通りとなります。

|ブラウザ|バージョン|
|:---|:---|
|Chrome|27以降|
|Safari|6.1以降|
|Opera|23以降|
|iOS Safari|6.1以降|
|Android Browser|4.4以降|
|Blackberry Browser|10以降|

因みに、``opera``は、``-webkit-``のベンダープレフィックスをサポートしているので、専用のベンダープレフィックスを付けなくても動作します。一応確認済みになります。

ブラウザ毎のCSSフィルタの対応状況は[caniuse](http://caniuse.com/#feat=css-filters)を参考にしてみて下さい。

#パフォーマンス
　それと、サンプルを作成していて気になったのは、パフォーマンスですね。
今回のサンプルを用いて、PC、スマホ搭載のブラザで確認してみましたが、体感的に、遅いという感じは受けませんでした。この辺は、エフェクト関数を組み合わせてアニメーションとかを作成した場合は、もしかしたらパフォーマンスの差が出てくるのではと思ってます。また、時間がある時にでも検証してみたいと思ってます。CSSフィルタのパフォーマンスに関してまとめている[html5rocks](http://www.html5rocks.com/en/tutorials/filters/understanding-css/)を参考にしてみて下さい。
こちらのサイトの検証結果だと、エフェクト関数毎のパフォーマンスは下記のようになっているみたいです。

|エフェクト関数|パフォーマンス|
|:---|:---|
|blur|slow unless accelerated|
|grayscale|very fast|
|sepia|very fast|
|saturate|very fast|
|hue-rotate|fast|
|invert|very fast|
|opacity|can be slow|
|brightness|fast|
|contrast|fast|
|drop-shadow|can be slow|
|url()|Varies, fast to slow|

# まとめ
fiterプロパティについて簡単にまとめましたので、ご参考にして下さい。
今回参考にさせて頂いたサイトは、下記の通り。
　[Filter Effects Module Level 1-W3C](http://www.w3.org/TR/filter-effects/)
　[filter-MDN](https://developer.mozilla.org/ja/docs/Web/CSS/filter)
　[Understanding CSS Filter Effects-html5rocks](http://www.html5rocks.com/en/tutorials/filters/understanding-css/)

|エフェクト関数|処理|値|対応ブラウザ|
|:---|:---|:---|:---|
|blur|ぼかし|0px(初期値)～10px|webkit|
|grayscale|モノクロ|0%(初期値)～100%|webkit|
|sepia|セピア|0%(初期値)～100%|webkit|
|saturate|彩度|0%～100%(初期値)|webkit|
|hue-rotate|色相回転|0deg(初期値)～360deg|webkit|
|invert|階調反転|0%(初期値)～100%|webkit|
|opacity|透過度|0%～100%(初期値)|webkit|
|brightness|明るさ|0%～100%(初期値)|webkit|
|contrast|コントラスト|0%～100%(初期値)|webkit|
|drop-shadow|影|CSS3のdrop-shadowと同様|webkit|
|url()|カスタム用|[詳細](http://webos-goodies.jp/archives/how_to_use_css_shaders.html)|webkit,mozilla|

# サンプルコード
　最後に、今回作成したサンプルのソースを開示しますので、興味ある方がいましたら、実際に動かして、filterプロパティのエフェクトを実感してみて下さい。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">

<style>
@charset "UTF-8";
body {
	font-family: "メイリオ",meiryo;
}

.floatcontainer:after{
	content: "."; 
	display: block; 
	height: 0; 
	font-size:0;	
	clear: both; 
	visibility:hidden;
}
.floatcontainer {
	display: inline-block;
}

/* Hides from IE Mac */
* html .floatcontainer {height: 1%;}
.floatcontainer {
	display:block;
}
/* End Hack */ 
.social_buttons {
	list-style: none;
}
.social_buttons li {
	float: left;
}
.field label {
	display: inline-block;
	width: 200px;
}
#sample {
	background-color: #9933FF;
	width: 65%;
	padding: 8px;
}
fieldset {
	border: none;
}
#wrapper{
	width:640px;
	margin: auto 0;
	text-align:center;
}
fieldset {
	border: none;
}
</style>
<script src="http://code.jquery.com/jquery.min.js"></script>
<script>
$(function() {
  $('input[type="range"]').change(function() {
    var range = this;
    var fx = range.id;
    var unit = range.dataset.unit || 'px';
    var value = range.value + unit;
    $('#sample').css('filter', fx + '(' + value + ')');         // 標準CSS3向け
    $('#sample').css('-webkit-filter', fx + '(' + value + ')'); // Google Chrome,Safari向け
    $('#sample').css('-moz-filter', fx + '(' + value + ')');    // Firefox向け
    $('#sample').css('-o-filter', fx + '(' + value + ')');      // Oper向け
    $('#sample').css('-ms-filter', fx + '(' + value + ')');     // Internet Explorer向け
    showCurrentValue(this, value);
  }).each(function() {
    var range = this;
    var unit = range.dataset.unit || 'px';
    var value = range.value + unit;
    showCurrentValue(this, value);
  });
  
  function showCurrentValue(range, value) {
    var $range = $(range);
    var result = $range.siblings('.current-value');
    result.text('[' + value + ']');
  }
});
</script>

</head>
<body>

<div id="wrapper">
<div id="sample">
  <img src="sample.jpg" alt="サンプル" height="320px">
</div>
</div>
<fieldset>
  <div class="field">
    <label for="blur">blur:ぼかし</label>
    <input type="range" id="blur" value="0" min="0" max="10" data-unit="px">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="grayscale">grayscale:モノクロ</label>
    <input type="range" id="grayscale" value="0" min="0" max="100" data-unit="%">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="sepia">sepia:セピア</label>
    <input type="range" id="sepia" value="0" min="0" max="100" data-unit="%">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="saturate">saturate:彩度</label>
    <input type="range" id="saturate" value="100" min="0" max="100" data-unit="%">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="hue-rotate">hue-rotate:色相回転</label>
    <input type="range" id="hue-rotate" value="0" min="0" max="360" data-unit="deg">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="invert">invert:階調反転</label>
    <input type="range" id="invert" value="0" min="0" max="100" data-unit="%">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="opacity">opacity:透過度</label>
    <input type="range" id="opacity" value="100" min="0" max="100" data-unit="%">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="brightness">brightness:明るさ</label>
    <input type="range" id="brightness" value="100" min="0" max="100" data-unit="%">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="contrast">contrast:コントラスト</label>
    <input type="range" id="contrast" value="100" min="0" max="100" data-unit="%">
    <span class="current-value"></span>
  </div>
  <div class="field">
    <label for="drop-shadow">drop-shadow:影</label>
    <input type="range" id="drop-shadow" value="0" min="0" max="10" data-unit="px 0px 10px #000">
    <span class="current-value"></span>
  </div>
</fieldset>
</body>
</html>
```