SVGをCSS用の安全なデータURIへ変換
SVGのコードを貼り付けると、data:image/svg+xml,で始まるデータURIができ、CSSのurl()や画像の参照先にそのまま使えます。#0a7のような色は%230a7になるため、どの文字もスタイルシートを壊しません。ブラウザで無料で使えます。
- 無料
- ブラウザで動作
- 登録不要
- データは端末の外に出ません
無料で実行
処理はブラウザ内で完結します。ファイルは送信されません。無料でご利用いただけます。
生のSVGマークアップを、CSSのurl()値や画像URLを受け付ける場所で使用できるデータURIへ変換します。最初に入力が正しい形式のXMLであることを検査し、次に文書をUTF-8として符号化して、URLやCSSの解析を変える可能性がある文字をすべてエスケープします。結果はSVGのメディアタイプから始まり、base64層を追加しません。そのため、スタイルと一緒に内容を確認し、コピーし、キャッシュし、バージョン管理しやすい形式です。
SVGデータURIで厳密なエスケープが必要な理由
SVGはテキストですが、そのままCSSの<code>url()</code>トークンへ貼り付ける方法は安全ではありません。<code>#0a7</code>のような色はURLフラグメントとして解釈され、空白はトークンを分割し、引用符や括弧はCSS値を途中で閉じる可能性があります。
この変換ではSVGをUTF-8バイトとして符号化し、URLで予約されていない文字だけを読める状態で残します。ハッシュ、山括弧、引用符、アポストロフィ、丸括弧、空白、改行など、それ以外はすべてパーセントエスケープになります。そのため、引用符なし、単一引用符、二重引用符のどの<code>url(...)</code>でも値が崩れません。
先頭は<code>data:image/svg+xml,</code>で、その後に符号化済みマークアップが続きます。base64を使わないため、一般的な英数字は確認できます。ブラウザーが内容を正しく識別できるよう、接頭辞を含む文字列全体をコピーしてください。
変換前にXML構造を検査します
壊れたマークアップを符号化すると、エスケープ自体は正しくても、ブラウザーが画像を解析するときに失敗する値ができてしまいます。この誤解を招く結果を防ぐため、まずXML文書を検査します。
SVGルート要素が1つだけ存在すること、開始タグと終了タグが一致して正しく入れ子になっていること、属性値が引用符で囲まれていること、同じ要素内で属性名が重複しないこと、コメントとCDATAセクションが閉じていること、実体参照が有効であることを確認します。ルート外のテキストや2つ目のルートは拒否します。
XML宣言、処理命令、コメント、CDATA、文書型宣言は、構造上正しい位置なら受け付けます。
CSSとHTMLで結果を使用する方法
返されたURIは、画像URLが必要な場所で使用できます。CSSでは、背景画像、マスクソース、リストマーカー、生成コンテンツなどに適しています。読みやすくするため単一引用符または二重引用符で囲めますが、厳密なエスケープにより引用符なしの<code>url()</code>トークンも保護されます。
HTMLでは、通常どおり属性値を引用符で囲み、画像の<code>src</code>属性へ設定できます。ビルドシステムが宣言を抽出または再利用しない場合、データURIは出現するたびに同じバイトを複製します。そのため、大きなイラストより小さなアイコンや装飾に向いています。
変換は決定的で、同じ入力からは常に同じ出力が得られます。フォント、画像、スタイルの取得、パスの最適化、実行可能なSVG内容の無害化は行いません。信頼できないマークアップは、埋め込み先のセキュリティ規則に従って扱ってください。
活用例
小さなアイコンをCSSへ埋め込む
バージョン管理されたSVG素材を、追加の通信なしで安全な背景画像へ変換できます。
テーマ別スタイルを生成する
ビルド時にSVGの各種版を符号化し、決定的なURIをデザイントークンやコンポーネントのスタイルへ配置できます。
生成されたSVGを検査する
テンプレートが出力した壊れたXMLを、符号化済み画像文字列の公開前に拒否できます。
よくある質問
base64ではなくパーセント符号化を使う理由は何ですか?
SVGはもともとテキストです。パーセント符号化ならbase64層が不要で、予約されていない文字を読める状態に保ち、標準準拠の画像URIを作成できます。
結果をCSSのurl()へ直接貼り付けられますか?
はい。 SVG内の引用符、括弧、空白、ハッシュなど、解析に影響する文字は符号化されます。
SVGの最適化や無害化も行いますか?
いいえ。 XML構造を検査して元のマークアップを符号化しますが、メタデータ、スクリプト、外部参照、冗長なパスは削除しません。
SVGが受け付けられないのはなぜですか?
コードが整形式ではないためです。タグが閉じていない、入れ子が正しくない、属性に引用符がないか重複している、コメントが閉じていない、実体参照が不正、svgの外に文字や2つ目の要素がある、といった場合です。
データURIを使わないほうがよいのはどんなときですか?
画像が大きい場合や、多くの場所で使う場合です。データURIは使う場所ごとに中身がすべて複製されるため、大きなイラストより、小さなアイコンやバッジ、装飾に向いています。
関連ツール
開発者向け — APIアクセス
このページの機能はすべてAPIからも利用できます。自社システムに組み込みたいチーム向けのセクションです。それ以外の方は上のツールをそのままお使いください。
エンドポイント
Bearerトークンで認証し、POST1回でタスクをキューに登録します。結果はWebhookまたは署名付きリンクで受け取れます。
お使いのスタックから呼び出す
curl -X POST https://api.kit.forhosting.com/web/svg-to-data-uri \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#0a7\" d=\"M2 2h20v20H2z\"/></svg>"}'const res = await fetch("https://api.kit.forhosting.com/web/svg-to-data-uri", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#0a7\" d=\"M2 2h20v20H2z\"/></svg>"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/web/svg-to-data-uri",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#0a7\" d=\"M2 2h20v20H2z\"/></svg>"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/web/svg-to-data-uri", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"svg":"<svg xmlns=\\"http://www.w3.org/2000/svg\\" viewBox=\\"0 0 24 24\\"><path fill=\\"#0a7\\" d=\\"M2 2h20v20H2z\\"/></svg>"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#0a7\" d=\"M2 2h20v20H2z\"/></svg>"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/web/svg-to-data-uri", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)リクエスト例
{
"svg": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"#0a7\" d=\"M2 2h20v20H2z\"/></svg>"
}レスポンス例
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "web.svg_to_data_uri",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}非同期APIです。task_idは即時に返ります。ポーリングは1秒あたり1リクエストまでです。
料金
単価はすべて公開しています。トークン換算や独自クレジットはありません。失敗したタスクは課金されません。
制限
timeout_sec | 30 |
max_crawl_pages | 25 |
エラー
| HTTP | コード | 意味 |
|---|---|---|
401 | unauthorized | APIキーが無効か、指定されていません。Authorizationヘッダーを確認してください。 |
402 | insufficient_balance | 残高が不足しています。チャージ後に再度お試しください。 |
404 | unknown_type | 指定されたタスクタイプは存在しません。タイプ名を確認してください。 |
429 | rate_limited | リクエストが多すぎます。しばらく待ってから再度お試しください。 |
技術的な注記
変換前にXML構造を検査します
検査に失敗した場合は、データURIではなく問題を説明する<code>invalid_input</code>エラーを返します。これはXML構文の検査であり、すべてのSVG要素、属性、描画、アニメーション、外部参照が全ブラウザーで動くことを保証するものではありません。
技術的な質問
APIによる変換料金はいくらですか?
APIリクエスト1回につき$0.002です。ブラウザー版はこのページ上でローカル実行できます。
XMLの形式が正しくない場合はどうなりますか?
変換を中止し、問題を説明するinvalid_inputエラーを返します。途中までのURIは返しません。