WebページをFigmaに取り込むとアイコンが消える理由
全部入ったのにアイコンだけ来ていません。空箱か、黒い四角か、小さな長方形。原因は四つあり、どれかによって直せるかどうかが決まります。
ページを Figma に移したのに、アイコンだけ来ていません。矢印や虫めがねや外部リンクの印があった場所に、空の四角があるか、黒い塊があるか、何もありません。
これはひとつのバグではありません。Web でアイコンを描く方法は互いにまったく違う四種類があり、それぞれ違う壊れ方をします。いま見ているのがどれかが分かれば、直せるのかどうか、どう直すのかも決まります。
四種類のアイコンと、それぞれの失敗
1. インライン SVG
いちばん簡単なケースです。アイコンが HTML の中に <svg> 要素として直接書かれ、path もそこにあります。DOM を読む変換ツールなら形をそのまま見て、Figma にベクターとして渡せます。
これが失敗するときは、たいてい変換ツールが何かを潰しています。別の場所で定義されたシンボルを <use> で参照している、CSS の filter がかかっている、currentColor で塗られているのに継承の文脈を離れて色を失った、といったあたりです。
2. SVG スプライト
ひとつのファイルにすべてのアイコンが <symbol> として入っていて、使う場所には参照だけがあります。
<svg class="icon"><use href="/icons.svg#chevron-down" /></svg>
Web では効率的ですが、素朴な変換ツールには見えません。DOM 上のその要素には path が入っていないからです。文字どおり読むと空の <svg> が出てきます。スプライトがサイズだけ合った空箱として届くのはこのためです。
解決するには参照をたどり、スプライトファイルを取得し、id でシンボルを見つけて形を差し込む必要があります。スプライトが別オリジンにある場合は、その取得自体が許可されていなければなりません。
3. アイコンフォント
アイコンがフォントの一文字である場合です。Font Awesome も Material Icons も社内アイコンフォントもこの方式です。クラスのついた要素、::before 疑似要素、Unicode の私用領域のコードポイントを収めた content プロパティ、という組み合わせになります。
.fa-search::before { content: "\f002"; }
ふたつのことが起きます。まずアイコンは疑似要素にいますが、疑似要素は DOM にありません。要素ツリーをいくら歩いても出てきません。そして仮に変換ツールがテキストとして拾えたとしても、Figma にはその文字そのものとして入ります。アイコンフォントが手元になければ、Figma は代替フォントが持っているものを描きます。空の四角か、無関係なグリフです。
取り込んだページが小さな長方形だらけになる、あの典型的な症状の正体がこれです。
4. CSS マスクアイコン
別項目にする価値があります。増えている方式で、しかも成功したように見える形で失敗するからです。要素に中身はまったくなく、背景色とマスクだけがあります。
.icon {
background-color: currentColor;
-webkit-mask-image: url(/icons/search.svg);
mask-size: contain;
}
形はマスク画像にあり、色は要素にあります。背景を読む変換ツールが得るのは、アイコンの色で塗られた長方形です。だからこのケースは「何もない」ではなく、黒や色つきの四角として届きます。色は合っていて形が消えているわけです。
VitePress で作られたドキュメントサイトがこの方式を多用します。私たちが最初にこの問題に出会ったのもそこでした。あるドキュメントサイトのアイコンが全部黒い四角で取り込まれた、という報告がきっかけです。
変換ツールが取りこぼす理由
四つ全部に対応するには四つの別々の処理が要り、そのうち三つは DOM を読む以上の作業を必要とするからです。
- スプライトは参照先のファイルを取得してシンボルを取り出す必要があります。
- アイコンフォントは疑似要素のスタイルを読み、コードポイントを解決し、テキストとして渡すのではなくグリフをベクターとして描く必要があります。
- マスクアイコンはマスク画像を取得し、要素の色を長方形ではなくその結果の形に適用する必要があります。
DOM を歩いて見つけたものを写すだけの変換ツールは、一番目だけ通って残りは静かに失敗します。珍しい挙動ではなく、ありふれた挙動です。
自分がどのケースか見分ける
ページを開いてアイコンを右クリックし、検証します。30秒でどれか分かります。
| 検証ツールに見えるもの | 種類 | よくある壊れ方 |
|---|---|---|
中に <path> のある <svg> | インライン SVG | だいたい問題なし |
<use href="…#id"> のある <svg> | スプライト | 空の四角 |
アイコンのクラスがつき子を持たない <i> や <span> | アイコンフォント | 欠字の長方形 |
計算済みスタイルに mask-image がある要素 | CSS マスク | 色だけの四角 |
Snapture は四つをどう扱うか
四つとも扱います。「アイコンに対応しています」はどのツールも言うので、どう対応するかを具体的に書いておきます。
- インライン SVG はベクターの形のまま通します。ただし入れ子のマスクや filter、
foreignObjectのように Figma のインポーターが処理しきれないほど複雑な SVG はラスタライズします。静かな失敗ではなく、意図した品質の引き下げです。 - スプライト は
<use>の参照をたどってスプライトを取得し、該当シンボルの形を正しい viewBox とともに差し込みます。 - アイコンフォント は疑似要素の計算済み
contentを読んで検出し、グリフを図形として描きます。Figma に文字として渡しません。アイコンフォントが入っているかどうかに結果が左右されません。 - CSS マスクアイコン はマスク画像を取得し、要素自身の色をその形に適用します。塗りつぶされた四角ではなく、本来の色のアイコンとして届きます。
実測ページに載せた計測では、Linear のホームページからベクターノードが215個、Stripe からは153個出ました。その大半がアイコンの処理で、編集できるファイルと穴の空いたファイルの差はここで決まります。
すでに壊れたファイルがあるなら
ラスタライズされた黒い四角を戻す方法はありません。形の情報がそもそもファイルに入っていないからです。自分のケースを処理できるツールで取り込み直すしかありません。
例外はアイコンフォントです。文字として入っていて、アイコンフォントが手元にあるなら、Figma は自分の環境では正しく描きます。ただしそのフォントを持たない人が開くと崩れます。自分だけ正しく見えるファイルを渡すより、取り込み直したほうがいいでしょう。
自分のページで試す 無料キャプチャ5回、全機能つき。カードも会員登録も不要です。English · 한국어 · 日本語 · 简体中文 · 繁體中文 · Español · Português · Français · Deutsch · Русский · Italiano · Bahasa Indonesia