关于 screenshot-to-code
将 UI 截图转为整洁、响应式且易于访问的代码技能。它会适配现有项目技术栈,并指导实现及与原图的视觉比对。
主要功能
- 01匹配现有项目技术栈
- 02梳理布局、设计令牌和组件
- 03编写语义化、可复用的 UI 代码
- 04适配较小屏幕布局
- 05渲染并与截图比对
适用场景
- 01将截图还原为网页
- 02构建响应式定价区块
- 03在无现有项目时制作屏幕原型
- 04对照参考图检查渲染结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ onewave-ai/ claude-skills --skill screenshot-to-code安装后在 Claude Code 中输入/screenshot-to-code确认已加载。
附带文件references/stack-setup.mdreferences/visual-check.md
详细介绍
截图转代码
将图片中的 UI 重建为简洁、响应式且无障碍的代码,然后将渲染结果与图片进行对比。
工作流
-
选择目标技术栈。 如果用户在项目中操作,请与项目保持一致:读取
package.json,确认使用 React/Next/Vue 以及 Tailwind 版本,并复用现有组件、设计令牌和图标库。仓库已有答案时不要提问。如果没有项目:- 单屏界面或快速原型:使用一个独立的
index.html(通过浏览器构建版引入 Tailwind,参见参考资料/stack-setup.md)。 - 应用或多屏界面:使用 Vite 上的 React + TypeScript + Tailwind v4。
- 用户提到 Next.js、SSR 或路由:使用 Next.js App Router。
- 单屏界面或快速原型:使用一个独立的
-
编码前先写一份简短规格说明。 查看图片并记录:
- 从上到下的布局区域(导航栏、主视觉区、侧边栏、网格、页脚),以及每个区域的网格或弹性布局结构
- 设计令牌:3–6 种十六进制颜色、推测的字体系列和字号比例、间距节奏(通常为 4px 的倍数)、圆角半径、阴影样式
- 重复组件(卡片、列表行、按钮),这些组件应使用带属性的单个组件
- 图片无法体现的内容:悬停和焦点状态、移动端布局、真实数据、首屏以下的内容
根据图片分辨率估算尺寸。如果截图是 2 倍图(例如,宽度为 2880px 的 Retina 截图对应 1440px 的布局),则将像素测量值减半。
-
构建。 使用语义化元素(
header、nav、main、section、button、a),将重复部分提取为组件,并将设计令牌集中在一处(Tailwind v4 的@theme或 CSS 自定义属性),而不是到处散布十六进制颜色。使用图片中的真实文字,不要用 lorem ipsum。对于无法提取的图片和徽标,使用带有描述性alt文本的定尺寸占位符。使用项目已有的图标库(默认:lucide-react),不要手绘 SVG 或使用表情符号。 -
实现响应式布局。 首先针对截图视口构建,然后定义布局如何收缩:多列网格改为堆叠,导航栏改为菜单按钮,并使用
clamp()或响应式工具类缩小字号。如果截图是移动端,则反向处理。 -
渲染并比较。 如果可以运行浏览器(Playwright、无头浏览器或浏览器工具),请在源图片的视口宽度下截取结果,并排比较。参见参考资料/visual-check.md。先修复最大的差异:布局和对齐,然后是间距,再然后是字号和字重,最后是颜色。通常迭代两三次就足够;当剩余差异仅在字体渲染层面时即可停止。
-
交付。 提供文件、运行方式以及简短的假设清单(推测的字体、补充的状态、推断的内容)。注明任何需要真实资源的部分。
技术栈说明
- React 19:使用带 TypeScript 属性类型的函数组件。React 19 已移除
propTypes检查;不要添加它们。向函数组件传递ref时不需要使用forwardRef。 - Tailwind CSS v4:配置位于 CSS 中。使用
@import "tailwindcss";和@theme { --color-brand: #...; },不要使用tailwind.config.js,也不要使用 v3 的@tailwind base/components/utilities指令。自定义令牌会自动成为工具类(bg-brand)。 - Next.js(App Router):页面位于
app/中,组件默认是服务端组件。只有使用状态、效果或事件处理程序的组件才添加"use client"。 - Create React App 已弃用。纯 React 项目请使用 Vite。
各技术栈的设置命令请参见参考资料/stack-setup.md。
完整示例
输入:一张宽 1440px 的定价区域截图——居中标题、三张方案卡片(中间一张突出显示)、功能清单,以及每张卡片上的一个按钮。
规格:
- 区域:标题区块,接着是 3 列卡片网格,最大宽度约 1100px,间距 24px
- 设计令牌:背景色
#0B1220,卡片色#111A2E,强调色#3B82F6,文字色#E5E7EB,弱化色#94A3B8;类似 Inter 的无衬线字体;圆角 12px - 组件:
PlanCard,包含name、price、features[]、highlighted、cta - 未知项:悬停状态、月付/年付切换行为、移动端布局
构建:创建 PricingSection.tsx,将 plans 数组映射为 PlanCard;highlighted 会添加强调色边框和“最受欢迎”标签;使用 grid-cols-1 md:grid-cols-3。勾选图标使用 lucide-react。
比较:首次渲染的卡片高出 40px,原因是按钮内边距过大;标题字重为 600,而截图中是 700。修正两处后重新渲染,并附上假设列表:未实现切换功能,字体按 Inter 处理。
失败模式
- 猜测技术栈,而仓库已定义技术栈;或在 v4 项目中混用 Tailwind v3 配置。
- 使用绝对定位强行匹配像素。 窗口一调整大小就会出问题。使用 flex 和 grid,并接受细微差异。
- 所有内容都塞进一个组件。 任何重复三次的内容都应抽成带 props 的组件。
- 忽略不可见状态。 即使截图看不到,按钮和链接也需要悬停及
focus-visible样式。输入框需要标签。 - 颜色偏差。 从图像的纯色区域取样,而不是从抗锯齿边缘或渐变取样,并检查文字对比度是否符合 WCAG AA(正文文字为 4.5:1)。
- 没看过效果就声称匹配。 如果无法渲染结果,就说明未进行比较。