最近、私はSVGフィルターで多くの実験を行い、CSS実装の上記の問題を解決するために使用できることに気付きました。 デモ用に作成したスティッキーメニューをご覧ください。
コードペン
SVGフィルター101
SVGフィルターは非常に強力なものです。 しかし、これは非常に広範なトピックなので、問題を解決するために最も必要なものについてのみ説明します。
名前にもかかわらず、これらのフィルターをCSSを使用してDOM要素に適用できます。これはほとんどのブラウザーで機能します 。
フィルターを記述するための古典的な構文:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <defs> <filter id="name-your-filter-here"> ... <!-- insert filters here --> ... </filter> ... </defs> </svg>
DOM要素へのフィルターの適用:
.selector { filter: url('#name-of-your-filter-here'); /* you can also load filters from external SVGs this way: */ filter: url('filters.svg#name-of-your-other-filter-here'); }
フィルタプロパティにベンダープレフィックスが必要な場合があります。
要素には、ぼかし、色変換、シェーディングの機能を実行する1つ以上のフィルタープリミティブが含まれます。 これらのプリミティブの完全なリストはこちらです。
いくつかの例を見てみましょう。
コードペン
<filter id="blur"> <feGaussianBlur in="SourceGraphic" stdDeviation="3" /> </filter>
この単純なフィルターは、要素に対して3ピクセルのぼかしを実行します。 in =属性"SourceGraphic"に注意することが重要です。 inは、フィルターが正確に適用されるものを定義します。 SourceGraphic値は、元のアイテムを返します。 したがって、元のグラフィックに対してぼかしが発生する必要があることを示します。 すべてが非常に簡単です。
もう少し複雑な例を見てみましょう:ドロップシャドウ。 フィルターチェーンがどのように連携するかを明確に示しています。
コードペン
<filter id="drop-shadow"> <feGaussianBlur in="SourceGraphic" stdDeviation="7" result="shadow" /> <feOffset in="shadow" dx="3" dy="4" result="shadow" /> <feColorMatrix in="shadow" mode="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.6 0" result="shadow" /> <feBlend in="SourceGraphic" in2="shadow" /> </filter>
結果と属性を見てください。 結果では 、フィルターを使用して結果の名前が示されます。フィルターを使用すると、元のグラフィックオブジェクトとは対照的に、この結果をフィルター処理できます。 つまり、この例では、要素をぼかし、具体的にぼかしたオブジェクトを暗くしてから、ぼかしたオブジェクトと暗くなったオブジェクトの位置を変更しました。
<feBlend>タグに注意してください 。 スコープを示す2つの属性が含まれています。値SourceGraphicのinと値shadowのin2です。
SVGフィルターの基本原理を理解したので、スティッキーエフェクトを作成する方法を理解しましょう。
修正済み
基本的なテクニックはここで説明されます 。 考えは、要素を同時にぼかしてコントラストをつけることだということを思い出させてください。 そして、すべてが魔法のように機能します。
コードペン
ただし、まだ次のものがあります。
- 異なる色で作業する際の問題。
- ぼかしは、コンテンツを含む要素全体に対して行われます。
- 不透明度を使用できない。
これだけでは、実際のプロジェクトでこのトリックを適用することはできません。
SVGフィルターを使用すると、CSSでは不可能だった機能を実装できます。色を変更せずに、アルファチャネルのコントラストのみを上げることができます。 SourceGraphicを使用すると、コンテンツを変更せずに要素自体にのみぼかしを適用できます。また、アルファチャネルで作業するため、透明にするだけでなく、透明な背景が必要です。
メインコード:
<filter id="goo"> <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" /> <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="goo" /> <feBlend in="SourceGraphic" in2="goo" /> </filter>
私たちがやったことについて簡単に:
- 最初に、10ピクセルをぼかし、この結果に名前を割り当てます。
- 次に、結果として、カラーマトリックスフィルターを適用して、アルファチャネルのコントラストを上げます。
- その後、元のグラフィックオブジェクトをこのエフェクトに挿入しました。
カラーマトリックスについて
カラーマトリックスフィルターを使用したことがない場合は、その仕組みを説明する必要があります。 4行5列のテーブルを想像してください。 次のようになります。
| R | G | B | A | + ---|------------------- R | 1 | 0 | 0 | 0 | 0 ---|------------------- G | 0 | 1 | 0 | 0 | 0 ---|------------------- B | 0 | 0 | 1 | 0 | 0 ---|------------------- A | 0 | 0 | 0 | 1 | 0 ---|-------------------
各行はチャネル(赤、緑、青、およびアルファ)であり、チャネルの値を設定するために使用されます。 最初の4列もチャネルです。 セル内の数字は、行のチャネルの列のチャネル乗数です。 たとえば、行Rと列Gの0.5は、現在の値Green * 0.5を赤チャネルに追加します。 最後の列はチャネルではなく、加算または減算に使用されます。 ここに示されている数値に255を掛けて、対応するチャネルに割り当てます。
説明するには長い時間がかかりますが、実際には、フィルターの使用は非常に簡単です。 この場合、アルファチャネル値を変更するだけで、マトリックスは次のようになります。
| R | G | B | A | + ---|------------------- R | 1 | 0 | 0 | 0 | 0 ---|------------------- G | 0 | 1 | 0 | 0 | 0 ---|------------------- B | 0 | 0 | 1 | 0 | 0 ---|------------------- A | 0 | 0 | 0 |18 |-7 ---|-------------------
RGBチャンネルは変更されません。 アルファチャネル値に18を乗算し、7 * 255を減算して、透明度のみのコントラストを効果的に高めます。 すべての値は、ニーズに合わせてカスタマイズできます。
この行列をfeColorMatrixフィルターに適用するには、すべての値を特定の順序で書き込む必要があります。
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7"
デモ
その結果、私たちが考えた効果が働きます。 例:
コードペン
必要なものをすべてカスタマイズしたり、影を追加したり、各要素の色を変更したりできます。すべて自由に使用できます。
まとめると
- フィルタは、要素自体ではなく、要素を含むコンテナに適用する必要があります。
- 引っ張り効果のため、コンテナは内容物よりもわずかに大きい領域でなければなりません。 そうしないと、エッジで同様の欠陥が発生する可能性があります。
- たとえば、このフィルターを四角形に適用するには、もう少し洗練された方法を使用する必要があります。 スティッキー効果の上に元のオブジェクトを描画する代わりに、境界を超えるすべてのものを隠すために、 atop属性を持つfeCompositeフィルターを適用する必要があります。
<filter id="fancy-goo"> <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" /> <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" /> <feComposite in="SourceGraphic" in2="goo" operator="atop"/> </filter>
コードペン
このアプローチは、スティッキーエフェクトを作成するためだけでなく、たとえば複数の長方形の角を丸くするなどの単純な場合にも使用できます。
- このフィルターは、ボリュームは軽いですが、広い領域に適用すると非常にリソースを消費します。 だから注意してください。
サポート
SVGフィルターは優れたサポートを提供していますが、すべてのブラウザーがDOM要素、特にSafariへのアプリケーションをサポートしているわけではありません。 ただし、少なくともFirefoxとChromeでは、Androidバージョンでも動作します。 ただし、サポートされていない場合、フィルターは画像を著しく損ないます。 使用する必要がある場合は、DOM要素の代わりにSVG要素に使用します。