Figma MCPのコード品質はFigmaの作り方で決まる話

Figma MCPのコード品質はFigmaの作り方で決まる話

2026/10/09

弊社の自社サイトのトップページデザインを題材に、Figma MCPでWordPressテーマ用のコードを生成する検証を行いました。Figmaのデータをそのまま渡した場合と、Figma側の作りを直した場合とで、出力されるコードがどう変わるかを比べています。

結論から言うと、生成されるコードの質は、AIの性能よりもFigmaデータの作り方に大きく左右されました。
デザイナーと実装者のどちらにも持ち帰っていただける内容になったと思い、記録として残します。

同じような構成を検討されている方の参考になれば幸いです。

背景・目的

Figmaの作り方がコードにどう影響するのかを、デザイナーと実装者の共通認識にするために検証しました。

Figma MCPとは、FigmaのデザインデータをAIエージェントに構造化された情報として渡すための、Figma公式のMCP(Model Context Protocol)サーバーです。スクリーンショットではなく、レイヤー構造やバリアブル、コンポーネントの情報をAIが直接読み取れるのが特徴です。

弊社ではWordPressのオリジナルテーマ開発が多く、デザインから実装への受け渡しで情報が抜け落ちることが課題でした。Figma MCPは話題になっている一方で、「思っていたコードにならない」という声もよく聞きます。そこで、掲載許諾を気にせず使える自社サイトのデザインで、実際の案件に近い条件のまま試してみることにしました。

検証の条件と進め方

検証は「そのまま生成」「Figmaを直して再生成」「WordPressへ変換」の3段階で進めました。

項目内容
題材弊社サイトのトップページ(PC用デザイン、1280×6416px)
接続方法Figma MCPサーバー(リモート)
AIクライアントClaude(claude.ai)
使用したツールget_design_context(デザインからコードを生成)
実装先WordPressのオリジナルテーマ(PHP+CSS)
検証日2026年9月29日
  1. Figmaのフレームをそのまま読み込み、コードを生成する
  2. 複製したデータでFigma側の作りを直し、同じ範囲を再生成する
  3. 生成結果をWordPressのテンプレートパーツとCSSに変換する

元のデザインデータは複製してから検証し、元データには手を加えていません。

1回目:Figmaをそのまま読み込んだ結果

Figmaをそのまま読み込むと、見た目は再現できても、WordPressテーマとしてはほぼ作り直しが必要なコードになりました。なお、Figma MCPの出力は既定でReact+Tailwind CSSの形式です。WordPressで使うには、いずれにしても変換が必要になります。

検証に使ったトップページデザインのヘッダー部分

全要素が固定座標で配置された

症状:ページ全体が position: absolute と、left・top の固定値で組まれていました。幅も1280pxに固定されており、画面幅が変わると崩れる作りです。

原因:FigmaでAuto Layoutを使わず、要素を座標で配置していたためです。Figma MCPはデザインの構造をそのまま写すので、座標で置いたものは座標のまま出力されます。

教訓:生成されるコードのレイアウトは、見た目ではなく、デザインデータの構造を写したものになります。

ボタンの四角と文字がバラバラに出力された

症状:ヘッダーの「お問い合わせ」ボタンが、オレンジの四角と文字の、別々の要素として出力されました。リンクやボタンとしては扱われていません。以下は、実際のコードを単純化したものです。

<div className="absolute bg-[#f19149] h-[44px] left-[914px] rounded-[8px] top-[32px] w-[151px]" />
<p className="absolute font-bold left-[941px] text-[16px] text-white top-[30px]">
  お問い合わせ
</p>

原因:Figma上で、背景の四角形と文字がグループ化もコンポーネント化もされず、たまたま重なって置かれていたためです。

教訓:デザイン上で1つの部品になっていないものは、コード上でも1つの部品になりません。

レイヤー名・画像化した素材・重複レイヤーがそのまま出た

症状:要素名が「グループ 5 1」「レイヤー 5 のコピー」「楕円形 1 のコピー 6-1」など、意味を持たない名前で出力されました。英文のキャッチコピーやイラストのまとまりはPNG画像になっていました。さらに、同じ画像が同じ位置に2枚重なった要素や、画面外に置かれた要素も出力されていました。

原因:作成時の自動命名、画像化(ラスタライズ)した素材、作業中に残った不要なレイヤーが、そのままFigmaに残っていたためです。

教訓:画面に見えていないレイヤーや名前も、コードにはすべて出てきます。デザインの見た目が整っていることと、データが整っていることは別の話です。

アイコン用の変数が行間に割り当てられていた

症状:ナビゲーションやフッターの文字の行間に、アイコンサイズ用と思われる変数が使われていました。

<p className="leading-[var(--sds-size-icon-medium,32px)] text-[16px]">ブログ</p>

原因:行間の値と同じ32pxを持つ変数が、用途の違いに関係なく割り当てられていたと考えられます。

教訓:変数は値ではなく意味で選ぶ必要があります。値がたまたま同じでも、用途の違う変数を割り当てると、コード上で意味の通らない指定になります。

2回目:Figma側を直して再生成した結果

Figma側の作りを直すと、同じ範囲でも、出力は実装で使える形に大きく近づきました。ページ全体を直すと規模が大きいため、「特徴」セクションとヘッダーのボタン部分に絞り、複製したデータに次の修正を加えています。

  • 見出し・カード・テキストをAuto Layoutで組み直す
  • レイヤー名を feature-card__title のような役割がわかる名前にする
  • 色をバリアブル(デザイントークン)として定義し、各要素に紐付ける
  • ボタンをコンポーネント化し、塗り/枠線の2種類をバリアントにする
  • 重複していたレイヤーを削除する

修正前後のFigmaのレイヤーパネルの比較

Auto Layoutでflexとgapの構造になった

固定座標だった配置が、flex・flex-wrap・gap による構造で出力されるようになりました。カードの枚数や文章量が変わっても、レイアウトが追従する形です。

ここで小さくつまずいたのが、カードが2列にならず1列に並んだことです。カード幅549px×2に間隔40pxを足すと、セクションの内幅1100pxを超えていました。座標で置いていたときは見た目だけで成立していた寸法が、Auto Layoutにした途端に破綻したわけです。カード幅を530pxに調整して解決しましたが、Auto Layoutは寸法の矛盾をFigma上で先に教えてくれる、と言い換えることもできます。

レイヤー名がそのままクラス名に使えた

Figmaで付けたレイヤー名は、要素の名前としてコードに出力されます。feature-card、feature-card__title のようにBEMの形式で命名しておくと、その名前をそのままCSSのクラス名に使えました。1回目の「レイヤー 5 のコピー」と比べると、実装者がコードを読むときの負担が大きく違います。

バリアブルとコードシンタックスでCSS変数名が整った

色をバリアブルにすると、直書きだった色がCSS変数として出力されるようになりました。ただし、最初はバリアブル名のスラッシュがそのまま出力され、CSSでは扱いにくい名前になりました。

そこで、バリアブルの「コードシンタックス」に、Web用の名前として var(--color-text-primary) を設定しました。すると、出力もその名前に変わりました。

/* コードシンタックス設定前 */
text-[color:var(--color\/text\/primary,#333)]

/* コードシンタックス設定後 */
text-[color:var(--color-text-primary,#333)]

一方で、見出し下のグラデーション線の色は、バリアブルに紐付けていなかったため直書きのまま残りました。バリアブルには、デザイナー向けの名前とは別に、Web用の名前を設定しておくのがよいと思っています。

コンポーネント化でボタンが引数付きの部品になった

ボタンをコンポーネントにしてテキストをプロパティにすると、文言と種類を受け取る部品として出力されました。1回目の「四角と文字がバラバラ」からは大きな改善です。以下は、実際のコードを単純化したものです。

function Button({ label = "お問い合わせ", type = "primary" }) {
  const isSecondary = type === "secondary";
  // isSecondary に応じて背景色・枠線・文字色を切り替える
}

<Button label="採用情報" type="secondary" />

ここにも小さなハマりどころがありました。2種類のボタンを1つのコンポーネントセットにまとめたところ、2つ目のボタンのラベルまで「お問い合わせ」になりました。テキストのプロパティが1つに統合され、既定値が片方にそろったようです。インスタンス側でラベルを上書きすれば済む話ですが、見落とすとそのままコードにも反映されます。

項目1回目(修正前)2回目(修正後)
配置固定座標の absoluteflex・gap による構造
要素名「グループ 5 1」などfeature-card__title など
色#333 などの直書きvar(--color-text-primary) などのCSS変数
ボタン四角と文字が別要素文言と種類を受け取る部品

Figmaを直しても残った課題

Figmaを直しても、デザインデータに含まれていない情報は、AIが推測で補うことはできませんでした。今回いちばん実感した点です。

見出し・リスト・リンクといったHTMLの構造は出力されない

症状:2回目の出力でも、見出しも本文もすべて <p> と <div> でした。<h2>・<h3>、<ul>・<li>、<a> は1つも出てきません。コンポーネント化したボタンも、<div> のままでした。

原因:Figmaには、見出しレベルやリスト、リンクといった文書構造の概念がないためです。

教訓:見た目の文字の大きさと、文書としての見出しレベルは別の情報です。前者はデザインデータから読み取れますが、後者は誰かが決めなければ存在しません。

代替テキストとリンク先はデザインに存在しない

症状:イラストの代替テキストは alt="" で出力され、ボタンやナビゲーションにはリンク先がありませんでした。

原因:どちらもFigmaのデータに含まれていない情報だからです。

教訓:デザインデータにない情報は、AIにも補えません。必要な場合は、人が決めて、デザインの注釈や実装の指示として渡す必要があります。

誤った設定は複製で広がる

症状:ヘッダーを組み直す際にナビゲーションの文字を複製して流用したところ、1回目で見つかった「行間にアイコン用の変数」という設定まで、そのまま引き継がれました。

原因:複製は、見た目だけでなく、変数の紐付けも含めて丸ごとコピーするためです。

教訓:誤った設定は、複製やコンポーネント化によってそのまま増えていきます。流用する前に、流用元の設定を直しておくことが大切です。

その他、変換時に手を入れた点

  • カード幅が固定値で、スマートフォン表示の指定がない(FigmaにPC用のデザインしかないため)
  • ほぼすべての要素に overflow: clip が付く(Auto Layoutの「コンテンツをクリップ」が既定でオンだったため)
  • 日本語を含む全テキストが Inter 指定になる(Figma上のフォント設定がそのまま出力されるため)
  • 画像がFigmaの一時的なURLで出力される(出力には7日間で失効する旨の案内があった)

WordPressテーマへの落とし込み

最終的なWordPressテーマのコードは、生成結果を下敷きにしつつ、構造と意味づけを人が補う形になりました。生成コードから引き継げたのは、主にクラス名、レイアウトの組み方、色のトークン、部品の分け方です。

項目生成コード変換後
HTMLの構造<p>・<div> のみ<h2>・<h3>・<ul>・<nav>・<a> に変更
代替テキスト空イラストの内容を記述
繰り返し要素カードをベタ書き配列にまとめてループで出力
画像Figmaの一時URLテーマ内の画像パス
レスポンシブ固定幅のみスマートフォン用のブレイクポイントを追加
フォントInter のみ日本語フォントを含むフォントスタック

ボタンは、生成コードの「文言と種類を受け取る部品」という構造をそのまま生かし、PHPの関数にしました。出力する値はすべてエスケープし、ボタンの種類は許可した値だけを受け付けるようにしています。以下は、実際のコードを単純化したものです(PHP 8系を想定。本記事の執筆時点では、実環境での動作は未検証です)。

function sg_the_button( $label, $url, $type = 'primary' ) {
    $allowed_types = array( 'primary', 'secondary' );
    if ( ! in_array( $type, $allowed_types, true ) ) {
        $type = 'primary';
    }
    printf(
        '<a class="button button--%1$s" href="%2$s">%3$s</a>',
        esc_attr( $type ),
        esc_url( $url ),
        esc_html( $label )
    );
}

sg_the_button( 'お問い合わせ', home_url( '/contact/' ), 'primary' );

カードは、生成コードでは3枚分がベタ書きでしたが、表示内容を配列にまとめてループで出力する形にしました。見出しは <h3>、一覧は <ul> に置き換えています。

<ul class="feature-list">
    <?php foreach ( $sg_features as $sg_feature ) : ?>
        <li class="feature-card">
            <img class="feature-card__illust"
                src="<?php echo esc_url( get_theme_file_uri( $sg_feature['image'] ) ); ?>"
                alt="<?php echo esc_attr( $sg_feature['alt'] ); ?>"
                loading="lazy">
            <h3 class="feature-card__title"><?php echo esc_html( $sg_feature['title'] ); ?></h3>
            <p class="feature-card__body"><?php echo esc_html( $sg_feature['body'] ); ?></p>
        </li>
    <?php endforeach; ?>
</ul>

Figma側を直したあとの特徴セクションとヘッダーボタン

今回の検証から、Figma MCPを使う前後で、それぞれが確認しておくとよいことを整理しました。

デザイナーが事前に整えておくこと

  • 関係のある要素はAuto Layoutでまとめる
  • レイヤーに役割がわかる名前を付ける
  • ボタンなど繰り返し使う部品はコンポーネントにする
  • 色や余白はバリアブルにし、Web用のコードシンタックスも設定する
  • 不要なレイヤーや、用途の違う変数の割り当てを残さない

実装者が必ず補うこと

  • 見出しレベル、リスト、リンクといったHTMLの構造
  • 代替テキストとリンク先
  • 投稿一覧などの動的な部分と、繰り返し要素のループ化
  • スマートフォン表示、フォント指定、画像の配置先
  • 出力値のエスケープなど、セキュリティ面の確認

まとめ

  • Figma MCPで生成されるコードの質は、見た目ではなくFigmaデータの構造で決まる
  • Auto Layout・命名・バリアブル・コンポーネント化で、出力は実装で使える形に大きく近づく
  • 見出しレベルやリンク先など、デザインデータに存在しない意味の情報は、AIにも推測できない
  • 誤った設定は、複製やコンポーネント化によってそのまま増えるため、流用元から直す

Figmaを直せば改善する部分と、人が補う部分を分けて考えると、デザイナーと実装者の役割分担がはっきりします。AIに任せる範囲を広げるほど、デザインデータの作り方が実装の品質に直結する、というのが今回の実感です。

おわりに

ここまで読んでいただき、ありがとうございました。
私たちは、できることを誠実にやる会社です。

Web・システム・AIのことで気になることがあれば、
「何から相談すればいいか分からない」段階でも大丈夫です。
お気軽にご相談ください。

▶ お問い合わせ

Claudeでのやり取りから本記事を作成し、加筆・修正しております。

  • #Figma
  • #Figma MCP
  • #WordPress
  • #コーディング
  • #デザインデータ

サニージェム公式note

アーカイブ記事

すべて

contact us お問い合わせ

Contact お問い合わせ・ご相談

「何から相談すればいいかわからない」
そんな段階でも、お気軽にご連絡ください。

Recruit 求人へのご応募

サニージェムの考え方に共感してくれる方と、
ぜひ一緒に働きたいと思っています。