SVG は Web サイトのアイコンに最適な形式です。 それについては疑いがない. 画面のピクセル密度に関係なく、シャープなアイコンを表示できます。ホバー時に SVG のスタイルを変更でき、CSS や JavaScript を使用してアイコンをアニメーション化することもできます。
ページに SVG を含める方法は多数あり、それぞれの手法には独自の長所と短所があります。 ここ数年、私は Sass 関数を使用してアイコンを CSS に直接インポートし、HTML マークアップを台無しにする必要がないようにしています。
アイコンのすべてのソース コードを含む Sass リストがあります。 次に、各アイコンは Sass 関数を使用してデータ URI にエンコードされ、 カスタムプロパティ ページのルートにあります。
TL; DR
ここで用意したのは、CSS で直接 SVG アイコン ライブラリを作成する Sass 関数です。
SVG ソース コードは Sass 関数を使用してコンパイルされ、データ URI にエンコードされ、アイコンが CSS カスタム プロパティに格納されます。 その後、CSS 内の任意の場所で、外部画像であるかのように任意のアイコンを使用できます。
これは、私の個人サイトのコードから直接引用した例です。
.c-filters__summary h2:after {
content: var(--svg-down-arrow);
position: relative;
top: 2px;
margin-left: auto;
animation: closeSummary .25s ease-out;
}
デモ
サス構造
/* All the icons source codes */
$svg-icons: (
burger: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0...'
);
/* Sass function to encode the icons */
@function svg($name) {
@return url('data:image/svg+xml, #{$encodedSVG} ');
}
/* Store each icon into a custom property */
:root {
@each $name, $code in $svg-icons {
--svg-#{$name}: #{svg($name)};
}
}
/* Append a burger icon in my button */
.menu::after {
content: var(--svg-burger);
}
この手法には長所と短所の両方があるため、プロジェクトにこのソリューションを実装する前にそれらを考慮してください。
メリット
- SVG ファイルに対する HTTP リクエストはありません。
- すべてのアイコンが XNUMX つの場所に保存されます。
- アイコンを更新する必要がある場合、各 HTML テンプレート ファイルを確認する必要はありません。
- アイコンは CSS とともにキャッシュされます。
- アイコンのソース コードを手動で編集できます。
- 余分なマークアップを追加して HTML を汚染することはありません。
- CSS を使用して、アイコンの色や外観を変更することもできます。
デメリット
- CSS を使用して SVG の特定の部分をアニメーション化または更新することはできません。
- アイコンが多いほど、CSS コンパイル済みファイルは重くなります。
私はロゴやイラストではなく、主にアイコンにこのテクニックを使用しています。 エンコードされた SVG は常に元のファイルよりも重くなります。 タグまたはCSSで
url(path/to/file.svg)
.
SVG をデータ URI にエンコードする
SVG をデータ URI としてエンコードすることは新しいことではありません。 実際には クリス・コイヤーさんが投稿しました 10 年以上前に、この手法の使用方法と、使用すべき (または使用すべきでない) 理由を説明しています。
データ URI を使用して CSS で SVG を使用するには、次の XNUMX つの方法があります。
- 外部画像として (使用
background-image,
ボーダー画像,
リストスタイル画像、…) - 疑似要素のコンテンツとして (例:
::before
or::after
)
これら XNUMX つの方法の使用方法を示す基本的な例を次に示します。
この特定の実装の主な問題は、新しいアイコンが必要になるたびに SVG を手動で変換する必要があり、CSS にこの長い文字列の読み取り不可能なコードがあるのはあまり快適ではないことです。
ここでサスが助けに来ます!
Sass 関数の使用
Sass を使用することで、SVG のソース コードをコードベースに直接コピーし、Sass がそれらを適切にエンコードしてブラウザー エラーを回避することで、作業を簡素化できます。
このソリューションは、主に Threespot Media によって開発され、で利用可能な既存の機能に触発されています 彼らのリポジトリ.
このテクニックの XNUMX つのステップは次のとおりです。
- すべての SVG アイコンをリストした変数を作成します。
- データ URI でスキップする必要があるすべての文字をリストします。
- SVG をデータ URI 形式にエンコードする関数を実装します。
- コードで関数を使用します。
1. アイコン一覧
/**
* Add all the icons of your project in this Sass list
*/
$svg-icons: (
burger: ''
);
2. エスケープ文字一覧
/**
* Characters to escape from SVGs
* This list allows you to have inline CSS in your SVG code as well
*/
$fs-escape-chars: (
' ': '%20',
''': '%22',
'"': '%27',
'#': '%23',
'/': '%2F',
':': '%3A',
'(': '%28',
')': '%29',
'%': '%25',
'': '%3E',
'': '%5C',
'^': '%5E',
'{': '%7B',
'|': '%7C',
'}': '%7D',
);
3. エンコード機能
/**
* You can call this function by using `svg(nameOfTheSVG)`
*/
@function svg($name) {
// Check if icon exists
@if not map-has-key($svg-icons, $name) {
@error 'icon “#{$name}” does not exists in $svg-icons map';
@return false;
}
// Get icon data
$icon-map: map-get($svg-icons, $name);
$escaped-string: '';
$unquote-icon: unquote($icon-map);
// Loop through each character in string
@for $i from 1 through str-length($unquote-icon) {
$char: str-slice($unquote-icon, $i, $i);
// Check if character is in symbol map
$char-lookup: map-get($fs-escape-chars, $char);
// If it is, use escaped version
@if $char-lookup != null {
$char: $char-lookup;
}
// Append character to escaped string
$escaped-string: $escaped-string + $char;
}
// Return inline SVG data
@return url('data:image/svg+xml, #{$escaped-string} ');
}
4. ページに SVG を追加する
button {
&::after {
/* Import inline SVG */
content: svg(burger);
}
}
これらの手順に従っている場合、Sass はコードを適切にコンパイルし、次のように出力します。
button::after {
content: url("data:image/svg+xml, %3Csvg%20xmlns=%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox=%270%200%2024.8%2018.92%27%20width=%2724.8%27%20height=%2718.92%27%3E%3Cpath%20d=%27M23.8,9.46H1m22.8,8.46H1M23.8,1H1%27%20fill=%27none%27%20stroke=%27%23000%27%20stroke-linecap=%27round%27%20stroke-width=%272%27%2F%3E%3C%2Fsvg%3E ");
}
カスタムプロパティ
現在実装されている Sass svg()
機能は素晴らしいです。 しかし、その最大の欠点は、コード内の複数の場所で必要なアイコンが重複し、コンパイルされた CSS ファイルの重量が大幅に増加する可能性があることです!
これを避けるために、すべてのアイコンを CSS変数 エンコードされた URI を毎回出力する代わりに、変数への参照を使用します。
以前と同じコードを保持しますが、今回は最初に Sass リストのすべてのアイコンを Web ページのルートに出力します。
/**
* Convert all icons into custom properties
* They will be available to any HTML tag since they are attached to the :root
*/
:root {
@each $name, $code in $svg-icons {
--svg-#{$name}: #{svg($name)};
}
}
今、呼び出す代わりに svg()
アイコンが必要になるたびに、関数で作成された変数を使用する必要があります --svg
接頭辞。
button::after {
/* Import inline SVG */
content: var(--svg-burger);
}
SVG の最適化
この手法では、使用している SVG のソース コードを最適化することはできません。 不要なコードを残さないようにしてください。 そうしないと、それらもエンコードされ、CSS ファイルのサイズが大きくなります。
あなたがチェックすることができます この素晴らしいリスト SVG を適切に最適化する方法に関するツールと情報。 私のお気に入りのツールはジェイク・アーチボルドのものです SVGOMG — ファイルをそこにドラッグして、出力されたコードをコピーするだけです。
おまけ: ホバー時のアイコンの更新
この手法では、SVG の特定の部分を CSS で選択することはできません。 たとえば、 fill
ユーザーがボタンをホバーしたときのアイコンの色。 ただし、CSS を使用してアイコンの外観を変更できるいくつかのトリックがあります。
たとえば、黒いアイコンをホバーすると白くしたい場合は、 invert()
CSS フィルター。 で遊ぶこともできます hue-rotate()
フィルタ。
それでおしまい!
この小さなヘルパー関数が、皆さんのプロジェクトで便利に使えることを願っています。 このアプローチについてどう思うか教えてください — どうすればこれを改善できるか、または別の方法で取り組むことができるか知りたいです!