关于 card-design
card-design 是面向界面设计与前端实现的卡片设计技能,指导从设计上下文出发构建卡片、布局并检查渲染结果。
主要功能
- 01读取设计上下文并映射设计令牌
- 02提供卡片结构与基础样式
- 03涵盖网格、瀑布流和横向布局
- 04包含悬停、展开及骨架屏模式
- 05提供响应式与可访问性检查清单
适用场景
- 01为产品、评价或博客内容设计卡片
- 02把卡片组织成适配不同屏幕的布局
- 03检查卡片交互、键盘访问与移动端显示
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ arnavpuri/ designskills --skill card-design安装后在 Claude Code 中输入/card-design确认已加载。
详细介绍
卡片设计
开始之前:加载设计上下文
- 阅读
.agents/design-context.md(由design-context技能编写)。如果文件不存在,请在tailwind.config.*或:rootCSS 变量中查找设计令牌。如果都没有,则使用默认值(主色#2563EB、辅助色#7C3AED、强调色#F59E0B、Tailwind 灰色中性色、标题和正文使用 Inter、极简风格),并告知用户使用了默认值——建议运行design-context。 - 将设计令牌映射到 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 为基准的间距比例。 - **Tailwind:**通过
primary、primary-light、primary-dark、secondary、accent、neutral-*、font-heading、font-body暴露相同变量(v3 使用theme.extend,v4 使用@theme)。以下示例中的indigo-*/gray-*类是这些设计令牌的占位符。 - **Figma:**如果用户提供 Figma URL,请使用 Figma MCP(
get_design_context、get_screenshot)获取设计并与之匹配;对于该设计,Figma 设计优先于上下文文件。 - 每张卡片都使用上下文中的
--radius和阴影样式;询问卡片中要放什么内容,以及它引导用户执行什么单一操作。
1. 卡片结构
每张卡片最多包含五个区域,并非所有区域都是必需的。
+---------------------------+
| [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>
瀑布流布局(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">
渐变边框显现
两层背景:表面层裁切到内边距框,渐变层置于透明边框后方并裁切到边框框。
.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>
骨架屏规则
- 与真实卡片的布局完全一致(高度、宽度和间距相同)。
- 在容器上(而非单个元素上)使用
motion-safe:animate-pulse。 - 文本占位符使用
rounded-full,图片使用rounded-lg。 - 加载时显示 3–6 张骨架屏卡片,并与预期网格一致。
- 从骨架屏过渡到真实内容时,不要造成布局偏移。
验证:渲染并检查
不要交付未经检查的代码。生成代码后:
- 分别在移动端和桌面端宽度下截图,例如
npx playwright screenshot --full-page --viewport-size=390,844 file://$PWD/index.html mobile.png,然后使用--viewport-size=1440,900再截一次(或使用开发服务器 URL)。 - 打开两张图片并检查:没有水平滚动或文本裁切、重叠;层级一目了然;已应用品牌设计令牌;图片以正确的宽高比加载。
- 按一次 Tab 键浏览:每个交互元素都显示清晰可见的焦点环,且顺序合理。
- 检查网格中的长短内容卡片(高度一致,行数截断生效),并确认仅在悬停时显示的内容也能通过键盘和触摸操作访问。
- 修复发现的问题,并重新截图,然后再报告完成。
卡片设计检查清单
- 卡片有清晰的视觉边界(边框、阴影或背景对比)
- 内容层级:媒体 > 标题 > 描述 > 操作
- 悬停效果能提供反馈(抬升、发光或边框变化)
- 交互式卡片使用真正的
<a>或<button>(而不是在<div>上设置tabindex),并带有focus-visible焦点环 - 仅在悬停时显示的内容(操作、翻转面)也会在聚焦时和触屏设备上显示
- 悬停动效遵循
prefers-reduced-motion;卡片图片设有宽度、高度和loading="lazy" - 必要时使用
line-clamp截断文本 - 网格布局具有响应式(桌面端 3 列、平板端 2 列、移动端 1 列)
- 加载骨架屏与卡片布局一致
- 图片具有恰当的
alt文本,并使用object-cover - 卡片链接应包裹整张卡片;如果卡片还包含其他按钮,则使用扩展链接模式(在标题链接上设置
::after { inset: 0 })——切勿在<a>内嵌套交互元素 - 在 390px 和 1440px 下渲染并截图(参见 Verify)
- 所有卡片的边框圆角、内边距和间距保持一致
评论
支持 Markdown