mcpField
C
card-design

card-design

github.com/arnavpuriデザイン・UI17112 回インストール4 週間前に更新
リポジトリ

card-design について

card-designは、カード型UIを作るデザイナーやフロントエンド開発者向けのスキルです。デザイントークンの設定からレイアウト、描画後の確認まで扱います。

主な機能

  1. 01デザインコンテキストをトークンに反映
  2. 02カードの構成と基本スタイルを定義
  3. 03グリッド、組積、横スクロールに対応
  4. 04ホバー、展開、スケルトンのパターン
  5. 05レスポンシブ性とアクセシビリティの確認

活用シーン

  1. 01商品、推薦文、ブログのカード設計
  2. 02画面サイズに応じたカード配置
  3. 03操作性、キーボード対応、モバイル表示の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/arnavpuri/designskills --skill card-design

インストール後、Claude Code で/card-designを入力して読み込まれたか確認します。

詳細

カードデザイン

始める前に:デザインコンテキストを読み込む

  1. .agents/design-context.md を読みます(design-context スキルによって作成されます)。ファイルがない場合は、tailwind.config.* または :root の CSS 変数にトークンがないか確認します。何も見つからない場合は、デフォルト値(Primary #2563EB、Secondary #7C3AED、Accent #F59E0B、Tailwind のグレー系ニュートラルカラー、見出しと本文には Inter、スタイルは Minimal)を使い、デフォルト値を使用したことをユーザーに伝えて、design-context の実行を提案します。
  2. トークンを一度だけ CSS 変数に割り当て、以後は変数のみを使用します:--color-primary、--color-primary-light、--color-primary-dark、--color-secondary、--color-accent、--color-neutral-50…--color-neutral-900、--color-success/-warning/-error、--font-heading、--font-body、--font-mono、--radius、および 4px を基準としたスペーシングスケール。
  3. Tailwind: 同じ変数を primary、primary-light、primary-dark、secondary、accent、neutral-*、font-heading、font-body として公開します(v3 では theme.extend、v4 では @theme)。以下の例にある indigo-*/gray-* クラスは、これらのトークンのプレースホルダーです。
  4. Figma: ユーザーから Figma の URL が提供された場合は、Figma MCP(get_design_context、get_screenshot)で取得してデザインに反映します。そのデザインでは、コンテキストファイルよりも Figma の内容を優先します。
  5. すべてのカードにコンテキストの --radius と影のスタイルを適用します。カードに入れるコンテンツと、カードから誘導する単一のアクションを確認します。

1. カードの構成

各カードは最大 5 つの領域で構成されます。すべてが必須ではありません。

+---------------------------+
|        [Media]            |  Image, video, or illustration
+---------------------------+
|  [Header]                 |  Title, subtitle, avatar, badge
|                           |
|  [Body]                   |  Description, content, data
|                           |
|  [Actions]                |  Buttons, links, icons
|  [Metadata]               |  Date, author, tags, stats
+---------------------------+
基本のカードスタイル
.card {
  background: var(--color-surface, #fff);
  border-radius: var(--radius, 1rem);
  border: 1px solid var(--color-neutral-200, oklch(92% 0 0));
  overflow: hidden;
  transition: box-shadow 200ms ease, transform 200ms ease, border-color 200ms ease;
}
Tailwind の基本カード
<div class="bg-white rounded-2xl border border-gray-200 overflow-hidden
  shadow-sm hover:shadow-md transition-shadow">
  
</div>

2. カードグリッドのレイアウト

均等グリッド
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
  
</div>
フィーチャーカード+グリッド
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
  
  <div class="lg:col-span-2 lg:row-span-2">
    
  </div>
  
  <div></div>
  <div></div>
</div>
Masonry レイアウト(CSS)
.masonry {
  columns: 3;
  column-gap: 1.5rem;
}
.masonry > * {
  break-inside: avoid;
  margin-bottom: 1.5rem;
}

/* Responsive */
@media (max-width: 1024px) { .masonry { columns: 2; } }
@media (max-width: 640px) { .masonry { columns: 1; } }
横スクロール(モバイル)

<div class="flex gap-4 overflow-x-auto snap-x snap-mandatory scroll-px-4 pb-4 -mx-4 px-4"
  tabindex="0" role="region" aria-label="Featured products">
  <div class="snap-start shrink-0 w-72"></div>
  <div class="snap-start shrink-0 w-72"></div>
  <div class="snap-start shrink-0 w-72"></div>
</div>

3. ホバーエフェクト

持ち上がるエフェクト(控えめでプロフェッショナル)
<div class="bg-white rounded-2xl border border-gray-200 p-6
  hover:-translate-y-1 hover:shadow-lg transition-all duration-200">
グローエフェクト
<div class="bg-white rounded-2xl border border-gray-200 p-6
  hover:border-indigo-300 hover:shadow-[0_0_24px_-4px_rgba(99,102,241,0.25)]
  transition-all duration-300">
グラデーションボーダーの表示

背景を 2 層にします。サーフェスはパディングボックスでクリップし、グラデーションは透明なボーダーの背後に置いてボーダーボックスまで広げます。

.card-gradient-border {
  border: 1px solid transparent;
  border-radius: var(--radius, 1rem);
  background:
    linear-gradient(var(--color-surface, #fff), var(--color-surface, #fff)) padding-box,
    linear-gradient(var(--color-neutral-200, #e5e7eb), var(--color-neutral-200, #e5e7eb)) border-box;
}
.card-gradient-border:hover,
.card-gradient-border:focus-within {
  background:
    linear-gradient(var(--color-surface, #fff), var(--color-surface, #fff)) padding-box,
    linear-gradient(135deg, var(--color-primary), var(--color-accent)) border-box;
}
コンテンツのスライドアップ
<div class="group relative bg-white rounded-2xl overflow-hidden border border-gray-200">
  <img src="/image.jpg" alt="" class="w-full h-48 object-cover" />
  <div class="p-6">
    <h3 class="font-bold text-gray-900">Card Title</h3>
    <p class="mt-2 text-gray-600 text-sm">Description text here.</p>
  </div>
  
  <div class="absolute bottom-0 inset-x-0 p-4 bg-gradient-to-t from-white via-white
    translate-y-full group-hover:translate-y-0 group-focus-within:translate-y-0
    [@media(hover:none)]:translate-y-0 motion-safe:transition-transform duration-300">
    <button type="button" class="w-full bg-indigo-600 text-white py-2 rounded-lg font-medium">
      View details
    </button>
  </div>
</div>
ホバー時の画像ズーム
<div class="group rounded-2xl overflow-hidden border border-gray-200">
  <div class="overflow-hidden">
    <img src="/image.jpg" alt="" width="600" height="400" loading="lazy"
      class="w-full h-48 object-cover motion-safe:transition-transform duration-500
        motion-safe:group-hover:scale-110" />
  </div>
</div>

4. 商品カード

<div class="group bg-white rounded-2xl border border-gray-200 overflow-hidden
  hover:shadow-lg transition-all duration-200">
  
  <div class="relative overflow-hidden">
    <img src="/product.jpg" alt="Product name" width="600" height="448" loading="lazy"
      class="w-full h-56 object-cover motion-safe:group-hover:scale-105 transition-transform duration-500" />
    
    <span class="absolute top-3 left-3 bg-red-600 text-white text-xs font-bold
      px-2.5 py-1 rounded-full">-20%</span>
    
    <button type="button" aria-label="Add to wishlist" aria-pressed="false"
      class="absolute top-3 right-3 w-11 h-11 bg-white/90 backdrop-blur rounded-full
      flex items-center justify-center text-gray-600 hover:text-red-600
      opacity-0 group-hover:opacity-100 focus-visible:opacity-100
      [@media(hover:none)]:opacity-100 transition-opacity">
      <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
          d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
      </svg>
    </button>
  </div>

  
  <div class="p-4">
    
    <span class="text-xs font-medium text-indigo-600 uppercase tracking-wide">Electronics</span>
    
    <h3 class="mt-1 font-semibold text-gray-900 line-clamp-2">
      Wireless Noise-Cancelling Headphones Pro Max
    </h3>
    
    <div class="mt-2 flex items-center gap-1.5">
      <div class="flex text-amber-400" role="img" aria-label="Rated 4.5 out of 5">
        
        <svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20"><path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/></svg>
        
      </div>
      <span class="text-sm text-gray-500">(128<span class="sr-only"> reviews</span>)</span>
    </div>
    
    <div class="mt-3 flex items-baseline gap-2">
      <span class="text-xl font-bold text-gray-900"><span class="sr-only">Sale price </span>$249</span>
      <del class="text-sm text-gray-500"><span class="sr-only">Original price </span>$319</del>
    </div>
  </div>

  
  <div class="px-4 pb-4">
    <button type="button" class="w-full bg-gray-950 text-white py-2.5 rounded-xl font-medium
      hover:bg-gray-800 active:bg-gray-900 transition-colors">
      Add to cart
    </button>
  </div>
</div>

5. 特徴/メリットカード

<div class="bg-white rounded-2xl border border-gray-200 p-6
  hover:border-indigo-200 hover:shadow-md transition-all duration-200">
  
  <div class="w-12 h-12 rounded-xl bg-indigo-50 text-indigo-600
    flex items-center justify-center">
    <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        d="M13 10V3L4 14h7v7l9-11h-7z"/>
    </svg>
  </div>
  
  <h3 class="mt-4 text-lg font-semibold text-gray-900">Lightning Fast</h3>
  <p class="mt-2 text-gray-600 text-sm leading-relaxed">
    Built on edge infrastructure for sub-100ms response times worldwide.
    Your users won't wait.
  </p>
  
  <a href="#" class="mt-4 inline-flex items-center gap-1 text-sm font-medium
    text-indigo-600 hover:text-indigo-500 transition-colors">
    Learn more
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        d="M17 8l4 4m0 0l-4 4m4-4H3"/>
    </svg>
  </a>
</div>

6. お客様の声カード

<div class="bg-white rounded-2xl border border-gray-200 p-6">
  
  <div class="flex gap-0.5 text-amber-400 mb-4" role="img" aria-label="Rated 5 out of 5">
    <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"><path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"/></svg>
    
  </div>
  
  <blockquote class="text-gray-700 leading-relaxed">
    "This tool saved our team 20 hours per week. The onboarding was seamless
    and we saw results from day one. Can't imagine going back."
  </blockquote>
  
  <div class="mt-6 flex items-center gap-3">
    <img src="/avatar.jpg" alt="" class="w-10 h-10 rounded-full" />
    <div>
      <div class="font-semibold text-gray-900 text-sm">Alex Rivera</div>
      <div class="text-gray-500 text-sm">VP Engineering, Acme Inc</div>
    </div>
  </div>
</div>

7. ブログ記事カード

<a href="/blog/post-slug" class="group block bg-white rounded-2xl border border-gray-200
  overflow-hidden hover:shadow-lg transition-shadow duration-200
  focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">
  
  <div class="overflow-hidden">
    <img src="/blog-cover.jpg" alt="" width="600" height="384" loading="lazy"
      class="w-full h-48 object-cover motion-safe:group-hover:scale-105 transition-transform duration-500" />
  </div>
  
  <div class="p-5">
    
    <div class="flex items-center gap-2 text-sm text-gray-500 mb-3">
      <span class="bg-indigo-50 text-indigo-700 px-2 py-0.5 rounded-full text-xs font-medium">
        Engineering
      </span>
      <span>5 min read</span>
    </div>
    
    <h3 class="font-bold text-gray-900 text-lg group-hover:text-indigo-600
      transition-colors line-clamp-2">
      How We Reduced Our Build Times by 80%
    </h3>
    
    <p class="mt-2 text-gray-600 text-sm line-clamp-3 leading-relaxed">
      A deep dive into our migration to incremental builds and how it
      transformed our developer experience across 12 teams.
    </p>
    
    <div class="mt-4 flex items-center gap-2">
      <img src="/avatar.jpg" alt="" class="w-6 h-6 rounded-full" />
      <span class="text-sm text-gray-600">Sarah Kim</span>
      <time datetime="2026-03-15" class="text-sm text-gray-500">Mar 15, 2026</time>
    </div>
  </div>
</a>

8. インタラクティブカード

展開可能なカード
<details class="group bg-white rounded-2xl border border-gray-200 overflow-hidden">
  <summary class="flex items-center justify-between p-6 cursor-pointer
    list-none hover:bg-gray-50 transition-colors">
    <div>
      <h3 class="font-semibold text-gray-900">Card Title</h3>
      <p class="text-sm text-gray-500 mt-1">Click to expand</p>
    </div>
    <svg class="w-5 h-5 text-gray-400 group-open:rotate-180 transition-transform"
      fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        d="M19 9l-7 7-7-7"/>
    </svg>
  </summary>
  <div class="px-6 pb-6 text-gray-600 text-sm leading-relaxed">
    Expanded content appears here. This can contain additional details,
    images, or nested components.
  </div>
</details>
裏返せるカード

控えめに使用してください。隠れたコンテンツは見落とされやすいためです。裏返し操作はキーボードフォーカスでも実行できるようにし、動きを抑える設定では、シンプルな切り替え(3D なし)にしてください。裏面に重要なコンテンツを載せる場合は、展開可能なカードを優先してください。

<div class="group [perspective:1000px] h-64 w-full">
  <div class="relative h-full w-full motion-safe:transition-transform duration-500
    [transform-style:preserve-3d] group-hover:[transform:rotateY(180deg)]
    group-focus-within:[transform:rotateY(180deg)]">
    
    <div class="absolute inset-0 bg-white rounded-2xl border border-gray-200
      p-6 flex flex-col items-center justify-center [backface-visibility:hidden]">
      <div class="w-16 h-16 rounded-2xl bg-indigo-100 text-indigo-600
        flex items-center justify-center text-2xl mb-4">
        <svg class="w-8 h-8" aria-hidden="true"></svg>
      </div>
      <h3 class="font-bold text-gray-900">Feature Name</h3>
      <p class="mt-2 text-sm text-gray-500 text-center">Hover or focus to learn more</p>
    </div>
    
    <div class="absolute inset-0 bg-indigo-600 rounded-2xl p-6
      flex flex-col items-center justify-center text-white text-center
      [backface-visibility:hidden] [transform:rotateY(180deg)]">
      <p class="text-sm leading-relaxed">
        Detailed description of this feature. Includes specific benefits
        and use cases for your team.
      </p>
      
      <a href="#" class="mt-4 bg-white text-indigo-700 px-4 py-2 rounded-lg
        font-medium text-sm">Learn more about Feature Name</a>
    </div>
  </div>
</div>

9. スケルトンローディング状態


<div class="bg-white rounded-2xl border border-gray-200 overflow-hidden motion-safe:animate-pulse"
  aria-hidden="true">
  
  <div class="h-48 bg-gray-200"></div>
  
  <div class="p-5 space-y-3">
    <div class="h-3 bg-gray-200 rounded-full w-1/4"></div>
    <div class="h-5 bg-gray-200 rounded-full w-3/4"></div>
    <div class="space-y-2">
      <div class="h-3 bg-gray-200 rounded-full w-full"></div>
      <div class="h-3 bg-gray-200 rounded-full w-5/6"></div>
    </div>
    <div class="flex items-center gap-2 pt-2">
      <div class="w-6 h-6 bg-gray-200 rounded-full"></div>
      <div class="h-3 bg-gray-200 rounded-full w-20"></div>
    </div>
  </div>
</div>
スケルトンのルール
  1. 実際のカードと正確に同じレイアウト(高さ、幅、間隔)にします。
  2. 個々の要素ではなくコンテナに motion-safe:animate-pulse を使用します。
  3. テキストのプレースホルダーには rounded-full、画像には rounded-lg を使用します。
  4. 読み込み中は、想定されるグリッドに合わせて 3~6 枚のスケルトンカードを表示します。
  5. レイアウトシフトを起こさずに、スケルトンから実際のコンテンツに切り替えます。

検証:レンダリングして確認する

確認していないコードを納品してはいけません。生成後、次の手順を実行します。

  1. モバイルとデスクトップの幅でスクリーンショットを撮影します。例:npx playwright screenshot --full-page --viewport-size=390,844 file://$PWD/index.html mobile.png を実行し、続けて --viewport-size=1440,900 でも撮影します(または開発サーバーの URL を指定します)。
  2. 両方の画像を開き、横スクロールやテキストの切り抜き・重なりがないこと、階層がひと目で分かること、ブランドのトークンが適用されていること、画像が適切なアスペクト比で読み込まれていることを確認します。
  3. Tab キーで一度移動し、すべてのインタラクティブ要素に論理的な順序で視認可能なフォーカスリングが表示されることを確認します。
  4. コンテンツの長さが異なるカードをグリッドで確認し、高さが揃うこと、行数制限が機能すること、ホバー時のみ表示されるコンテンツにキーボードとタッチでアクセスできることを確かめます。
  5. 問題を修正し、完了を報告する前にもう一度スクリーンショットを撮影します。

カードデザインチェックリスト

  • カードの視覚的な境界が明確である(枠線、影、または背景のコントラスト)
  • コンテンツの階層が適切である:メディア > タイトル > 説明 > アクション
  • ホバー効果でフィードバックが得られる(浮き上がり、光彩、または枠線の変化)
  • インタラクティブなカードでは、<div> に tabindex を設定するのではなく、実際の <a> または <button> を使用し、focus-visible のリングを付ける
  • ホバー時のみ表示されるコンテンツ(アクション、裏面)も、フォーカス時やタッチデバイスで表示される
  • ホバー時の動きは prefers-reduced-motion に従う。カード画像には幅と高さを設定し、loading="lazy" を指定する
  • 必要に応じて、line-clamp でテキストを省略する
  • グリッドがレスポンシブである(デスクトップは3列、タブレットは2列、モバイルは1列)
  • ローディング用スケルトンがカードのレイアウトに合っている
  • 画像に適切な alt テキストと object-cover が設定されている
  • カードのリンクでカード全体を囲むか、カード内に別のボタンも含まれる場合は、ストレッチリンクパターン(タイトルのリンクに ::after { inset: 0 } を指定)を使用する。<a> 内にインタラクティブ要素をネストしない
  • 390px と 1440px でレンダリングし、スクリーンショットを撮影している(Verify を参照)
  • すべてのカードで角丸、パディング、間隔が統一されている

コメント