SVGスプライト最適化ツール

複数のSVGを最適化してシンボルスプライト・CSSにまとめる

このツールは大画面(PC)でのご利用をおすすめします。

    SVGスプライト最適化ツールについて

    このツールは複数のSVGアイコンを受け取り、2つの処理をします。まず各ファイルからXML宣言、コメント、メタデータ、Inkscape・Sodipodi・Sketchの編集用属性を消し、空白を詰め、小数の桁を切り詰めて軽くします。次にその結果を、symbolベースのスプライト1枚か、data URIを入れたCSSクラス群にまとめます。

    SVGOのようにパスを計算し直すのではなく、決まったルールでテキストを取り除く方式です。結果は予測しやすい反面、どのルールが何を壊しうるかを知っておくことが大切です。

    symbolとuseでスプライトになる仕組み

    symbol要素はそれ自体は描画されないテンプレートです。各symbolにidとviewBoxを付けて1つのSVGに集めておけば、ページのどこからでもuse要素のhrefで「#icon-home」のようなidを指して複製を描けます。アイコンごとにHTTPリクエストを送る必要がなく、同じアイコンを何度使ってもパスデータは1回分で済みます。

    idはファイル名から作ります。小文字にして英数字以外をハイフンに置き換え、「icon-」を付け、数字で始まる場合はさらに接頭辞を付けます。元にviewBoxがなければwidth・heightから作り、それもなければ0 0 24 24とみなします。useが別ファイル(sprite.svg#id)を指す場合、ブラウザは同一オリジンのファイルしか許さないため、CDNなど別ドメインに置いたスプライトは参照できません。その場合はスプライトをHTML本文にインラインで入れてください。

    複数ファイルのidがぶつかる問題

    デザインツールから書き出したSVGには、グラデーションやクリップパスに「paint0_linear」「clip0」「a」といったidがよく付いています。こうしたファイルを1つのスプライトにまとめると同じidが何度も現れ、ブラウザは文書内の最初のものだけを参照するため、2つ目のアイコンが1つ目のグラデーションで塗られる不具合が起きます。

    このツールはsymbolごとに内部idの前に「icon-home__」のようなsymbolのidとアンダースコア2つを付け、url(#…)、href="#…"、アニメーションのbegin・endの参照も合わせて書き換えます。そのファイル内で定義されていないidへの参照には手を付けません。

    消してよいもの、消してはいけないもの

    コメント、XML宣言、metadataブロック、編集ソフト専用の属性は描画に影響しないので安全に消せます。一方viewBoxはサイズを変えたときに比率を保つ基準なので消してはいけません。SVGOもviewBoxの削除とtitleの削除を既定設定(preset-default)から外しており、このツールもviewBoxは残します。

    titleとdescは削除しません。metadataブロックと違い、スクリーンリーダーがアイコンの名前として読み上げるアクセシビリティ情報だからです。スプライトでも各symbolの中にそのまま残ります。ただしuseで呼び出したアイコンのtitleを読まないブラウザーとスクリーンリーダーの組み合わせもあるので、意味のあるアイコンならHTML側でもaria-labelや非表示テキストで名前を付けておくと安全です。

    空白の圧縮はタグ間の空白をすべて取り除きます。図形だけのアイコンには影響しませんが、textやtspanで文字を入れたSVGは単語間のスペースが消えることがあります。文字を含むSVGは結果を目で確認してください。

    小数の精度はviewBoxの大きさで選ぶ

    精度スライダー(0〜4、既定2)は文書内のすべての小数を丸めます。誤差は座標単位で生じるので、見た目への影響はviewBoxの大きさ次第です。24×24のアイコンで小数第2位なら最大0.005単位、24pxで描けば0.005pxで、まったく見えません。0にすると最大0.5単位の誤差が出て、24pxのアイコンでは線が半ピクセル揺れることがあります。

    逆に「0 0 1 1」のようなごく小さな座標系で描かれたSVGは、小数第2位の丸めだけでも形が目に見えて崩れます。プレビューで曲線が角ばって見えたら精度を上げてください。

    symbolスプライトとCSSスプライト、どちらを使うか

    symbolスプライトはインラインSVGとして描かれるので、fill="currentColor"で作ったアイコンは周囲の文字色に追従し、CSSで色や線幅を変えられます。CSSスプライトはアイコンをbackground-imageのdata URIとして埋め込みますが、この形で読み込まれたSVGは別文書扱いになり、ページのCSSやcurrentColorを受け取りません。色が固定のロゴやイラスト向きです。

    data URIはbase64ではなくURLエンコードを使います。base64は元より約3分の1長くなりgzipで縮みにくいのに対し、URLエンコードしたSVGはテキスト構造が残るため転送時の圧縮が効きやすくなります。

    例

    線画アイコンをスプライトにまとめるとき

    入力
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> … </svg> 形式のアイコン3つ
    結果
    <symbol id="icon-home" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> … </symbol>

    viewBoxと一緒に、ルートsvgのfill・stroke・stroke-widthなどの表現属性もsymbolに移ります。symbol内のpathがこの値を継承するので、Feather・Lucideのような線画アイコンが黒い塗りつぶしにならず元の線のまま描かれ、strokeがcurrentColorなので周囲の文字色に追従します。

    精度2でパス座標を短くする

    入力
    d="M12.34567 7.89123 L3.10000 4.50000"
    結果
    d="M12.35 7.89 L3.1 4.5"

    各数値を小数第2位で丸め、末尾の0を消します。整数(例:24)はそのままです。

    同じ名前のファイルが2つ

    入力
    home.svg、Home.svg
    結果
    icon-home、icon-home-2

    idが重なると-2、-3を付けて一意にします。ファイル名を整理しておくとHTMLでidを探しやすくなります。

    使い方

    1. SVGファイルを複数ドラッグ&ドロップします。
    2. 小数の精度を決め、ファイルごとの削減量を確認します。
    3. symbolスプライトかCSSスプライトの結果をコピーまたはダウンロードします。

    よくある質問

    スプライトにしたらアイコンが黒く塗りつぶされました。

    ルートsvgのfill="none"やstrokeなどの属性はsymbolに引き継がれるので、通常は元の見た目のままです。それでも黒くなる場合は、元のファイルが線の設定をsvg内のstyleブロックや外部CSSのクラスで指定している可能性が高いです。その場合は使う側のsvg要素にCSSでfillとstrokeを指定してください。

    useで外部のsprite.svgを参照したのに何も表示されません。

    外部ファイルの参照は同一オリジンでしか動きません。別ドメインに置いている、またはfile://で開いている場合は、スプライトをHTMLにインラインで入れてください。パスと#idの綴りも確認を。

    CSSスプライトのアイコンの色を変えられません。

    background-imageで読み込んだSVGはページのCSSやcurrentColorを受け取りません。色を変えたいならsymbolスプライトを使ってください。

    SVGOの代わりに使えますか?

    メタデータの整理とスプライト作成には十分ですが、パス命令の再計算や図形の統合といった最適化はしません。1バイトでも削りたいなら、先にSVGOで最適化してからここでまとめてください。

    出典

    基準日:

    プライバシーとデータの扱い