Figma 变量创建指南:从源 Token 数据到语义化变量体系的建模与落地(基于 figma-use Skill 实践)
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
本篇指南聚焦于「如何在 Figma 中基于已有的设计系统源数据(JSON、CSS、主题定义等)创建变量(Variables)」这一核心任务。内容来源于本仓库 figma-use Skill 的 wwds-variables--creating.md 文档,并结合 变量模型文档 与 可运行代码模式 展开。读完本文,你将掌握创建变量前如何诊断源数据结构、何时使用语义化别名、如何预判模式(Modes)拆分、如何设定 Scope 与 Code Syntax,以及用 Figma Plugin API 落地变量创建与绑定的完整实操路径。
创建之前:先理解源数据的真实状态
创建 Figma 变量的第一步不是打开插件写代码,而是先理解源数据的状态。文档原文强调:"When creating Figma variables, you need to start by understanding the state of the source data."这意味着你需要回答几个问题:
- 用户提供的数据是完整的设计 Token 定义,还是一份零散的值清单?
- 数据中是否已经隐含了「原语(primitive)/ 语义(semantic)」两层结构?
- 是否存在多主题(如品牌主题)需要额外层级?
- 数据是按平台(WEB / iOS / Android)分发的,还是单一声明?
如果用户只是要求「根据这些值创建变量」,他们真正想要的往往是一个能体现结构的变量体系,而不是机械地把每个值变成一个变量。是否采用语义化别名(semantic aliasing)指向原语(primitive),将完全取决于你拿到的源数据输入。
代码输入(JSON / CSS)的处理原则:贴合代码,但要拥抱设计语境
当输入是代码形态(JSON、CSS 等)时,你的目标应是:
尽可能贴近现有代码模式(reflect the existing patterns as closely as possible),同时把设计语境当作与代码不同的独立面来对待。
这一点在实践中具体化为两个决策:
- 命名大小写不必照搬代码。代码里可能是 camelCase 或 kebab-case,但在 Figma 中你可以放心使用句子式(sentence case)或首字母大写(capitalized case)来提高可读性——因为 Code Syntax(见下文)可以承载真实的代码形式,名字本身不需要牺牲可读性去模拟代码。
- 尊重代码中的既有模式。如果 CSS 变量已经是
--color-bg-default这类语义命名,那么在 Figma 中也应保持语义化,而不是退化成--color-blue-500这种纯原语命名。
创建前必须识别的三件事:别名结构、模式需求与层级
在创建任何变量之前,理解底层结构至关重要。文档列出了三个必须在动手前想清楚的点:
1. 隐含的别名(Aliasing)结构
如果源数据中存在隐含的「原语 + 语义」两层结构,你必须把它还原出来——先建原语,再让语义变量别名指向原语。如果源数据是单层扁平结构,就创建无别名的扁平变量。拿不准时,向用户确认(ask)。
这条「决策规则」(Decision rule)在 wwds-variables.md 中被完整定义为:
如果源数据有两层(原语 + 语义),先创建全部原语,再创建别名指向它们的语义变量;如果源数据是单层扁平结构,就创建无别名的扁平变量;不确定时,提问。
从 variable-patterns.md 的源码可以看出别名的实现形态——语义变量通过VARIABLE_ALIAS类型的值引用原语变量:
semanticVar.setValueForMode(modeId, { type: 'VARIABLE_ALIAS', id: primitiveVar.id });当原语变量变化时,语义变量在所有模式(Modes)下都会自动同步更新。
2. 预判模式(Modes)需求
你可能需要提前预判 Modes,以决定如何拆分变量集合。文档特别指出:在复杂系统中,尺寸(Sizes)和颜色(Colors)往往有不同的 Mode 需求。例如颜色需要 Light / Dark 模式,而尺寸可能只有一套;语言相关的字符串变量则可能要为每种语言建一个 Mode。因此创建结构时必须把 Mode 的差异纳入考虑。
3. 是否需要扩展集合(Extended Collections)
如果存在品牌化主题等场景,可能需要基于一个集合创建扩展集合,只覆盖其中一部分值——这类似于 CSS 中的继承与覆盖(inheritance and overrides)。复杂的企业级(Enterprise)方案下,多集合 + 扩展集合的布局可能就是正确的最佳实践。
最佳实践的相对性:没有放之四海皆准的答案
如果有人让你「基于最佳实践做决定」,答案取决于环境的复杂程度:
- 一个简单的主题(simple theme)服务于简单需求,就是最佳实践;
- 一个企业级计划的复杂扩展集合布局,同样可能是最佳实践。
关键在于不要脱离环境复杂度生搬硬套模板。这与 wwds.md 中「设计形态与实现形态是同一拼图的两块互补拼片」的理念一致:设计的理想状态是便于实验、迭代与验证,而实现的理想状态是严谨、高效。创建变量时,你要在两者之间找到贴合当前环境的平衡点。
变量模型基础:创建前必须理解的六个概念
在动手前,还需要吃透 wwds-variables.md 中定义的变量模型。Figma 变量与代码库中的 Token 概念高度重叠,但存在差距和 Figma 特有用法:变量是单一值,类型为 number、string、color、boolean。
Collections(集合)与 Extended Collections(扩展集合)
集合可以理解为 Figma 中的「组」。典型例子是名为 "Colors" 的集合,内含 Light / Dark 两个 Mode,每个值有两份定义。扩展集合则允许基于另一集合创建、仅覆盖部分值,适用于品牌色主题等场景。
Modes(模式)
模式可以理解为明暗主题,但用户可以为其定义任何维度——包括尺寸、语言(Figma 中存在字符串变量)。注意:每个集合都至少有一个 Mode。
Aliasing(别名)
别名即让一个变量指向另一个变量。常见做法是让语义变量指向原语变量;有些团队还会加入组件级 Token,形成「原语 → 语义 → 组件」三层结构。
Code Syntax(代码语法)
Code Syntax 是 Figma 中用于代码库翻译上下文的面。你可以在任意变量上分别设置 WEB、iOS、ANDROID 三套代码语法,当该变量在其他位置被引用(Figma Dev Mode 视觉呈现、或通过 MCP 提供设计上下文)时,会以代码形式出现。它应被理解为「实例」级别的文档,例如 CSS 场景写var(--the-thing)而不是--the-thing。
Scope(作用域)
variable.scopes: VariableScope[]指定该变量在 Figma 中可用于哪些属性。创建和使用变量时都重要。永远比不使用或设为ALL_SCOPES更好——越具体越好,但并非所有集合都复杂到需要精确作用域。常用取值:
| Scope 值 | 用途 |
|---|---|
ALL_SCOPES | 不受限制;仅在不需要精确度时使用 |
FILL_COLOR、STROKE_COLOR | 颜色绑定 |
TEXT_CONTENT | 文本图层的字符串变量 |
FONT_SIZE、FONT_WEIGHT、LINE_HEIGHT、LETTER_SPACING | 排版 |
CORNER_RADIUS、WIDTH_HEIGHT、GAP | 布局 / 间距 |
OPACITY | 图层不透明度 |
Grouping(分组命名)
变量名以斜杠(/)分隔,每个斜杠代表一个在 Figma 中可视化呈现的组。做匹配时要注意:代码前缀的一部分可能是集合名而非顶层分组;有时代码中有 Figma 中没有的前缀,这也 OK,但不确定时要问。总可以通过 Code Syntax 校验已有变量。
别忘了文本样式与效果样式
系统可能会要求你同时处理 Token 库中的文本(Text)和效果(Effect)样式,因为它们不在变量能力范围内:
- 阴影无法放进单个变量(缺少复合 Token 类型)。投影属于 效果样式(Effect Styles),但效果中的数值与颜色属性可以绑定到变量。
- 字号阶梯(type ramp)必须用 文本样式(Text Styles),因为排版同样是复合属性,无法放入单个变量,但
fontSize、fontFamily等单属性可以绑定变量。
因此,一个完整的 Token 库落地往往是「变量 + 文本样式 + 效果样式」三者的协同工作。
创建变量的常见坑(Gotchas)
创建阶段最容易踩的坑,文档明确列出如下,务必逐条对照:
createVariableCollection总是创建默认 Mode——集合创建后自带名为 "Mode 1" 的模式,你需要重命名它(或删除后新建),而不是从零开始。- 重复的变量名静默通过——Figma 不会报错,而是创建一个同名变量。创建前必须检查是否已存在。
- 变量别名要求目标在同一文件内——Plugin API 不支持跨文件别名;若要别名指向库变量,必须先导入。
setValueForMode设置别名要求精确形状——必须是{ type: 'VARIABLE_ALIAS', id: '<variableId>' },任何偏差都会静默写入错误值或直接抛错。
落地实操:用 Plugin API 创建变量(可运行代码模式)
下面的代码来自 variable-patterns.md,是 figma-use Skill 中可直接复用/改造的脚本模式。注意在使用use_figmaMCP 执行时,应遵循 SKILL.md 的规则:用return输出数据、代码自动包裹在异步上下文、颜色使用 0–1 范围。
创建集合与模式
const collection = figma.variables.createVariableCollection("MyCollection"); // 新集合默认带 1 个名为 "Mode 1" 的模式——务必重命名 collection.renameMode(collection.modes[0].modeId, "Light"); // 添加额外模式(返回新的 modeId) const darkModeId = collection.addMode("Dark"); const lightModeId = collection.modes[0].modeId;Mode 数量上限与套餐相关:Free = 1 个,Professional = 最多 4 个,Organization/Enterprise = 40+。若需要很多模式,应拆分到多个集合——这与前面「尺寸与颜色可能有不同 Mode 需求」的判断相互印证。
创建四种类型的变量
figma.variables.createVariable(name, collection, resolvedType)的第二个参数接受集合对象或 ID 字符串(推荐对象):
// COLOR —— 值使用 {r, g, b, a},全部 0–1 范围(含 alpha) const colorVar = figma.variables.createVariable("my-color", collection, "COLOR"); colorVar.setValueForMode(modeId, { r: 0.2, g: 0.36, b: 0.96, a: 1 }); // FLOAT —— 用于间距、圆角、尺寸等数值 const floatVar = figma.variables.createVariable("my-spacing", collection, "FLOAT"); floatVar.setValueForMode(modeId, 16); // STRING —— 用于字体族、字体样式名、任意文本值 const stringVar = figma.variables.createVariable("my-font", collection, "STRING"); stringVar.setValueForMode(modeId, "Inter"); // BOOLEAN const boolVar = figma.variables.createVariable("my-flag", collection, "BOOLEAN"); boolVar.setValueForMode(modeId, true);注意:Paint 颜色用{r, g, b}(无 alpha),而 COLOR 变量值用{r, g, b, a}(带 alpha),不要混淆。
创建后必须显式设置 Scope
SKILL.md 的第 16 条规则专门强调:创建变量时永远显式设置variable.scopes,默认的ALL_SCOPES会污染每一个属性选择器,几乎从不是你想要的:
variable.scopes = ["FRAME_FILL", "SHAPE_FILL"]; // 仅填充选择器 variable.scopes = ["TEXT_FILL"]; // 仅文本颜色选择器 variable.scopes = ["GAP"]; // 仅间距选择器 variable.scopes = ["CORNER_RADIUS"]; // 仅圆角选择器 variable.scopes = []; // 从所有选择器中隐藏完整合法取值:ALL_SCOPES、TEXT_CONTENT、CORNER_RADIUS、WIDTH_HEIGHT、GAP、ALL_FILLS、FRAME_FILL、SHAPE_FILL、TEXT_FILL、STROKE_COLOR、STROKE_FLOAT、EFFECT_FLOAT、EFFECT_COLOR、OPACITY、FONT_FAMILY、FONT_STYLE、FONT_WEIGHT、FONT_SIZE、LINE_HEIGHT、LETTER_SPACING、PARAGRAPH_SPACING、PARAGRAPH_INDENT。
创建前始终检查文件已有的 Scope 模式,匹配文件内既有的约定,而不是强加新约定。
设置 Code Syntax
variable.setVariableCodeSyntax('WEB', 'var(--color-bg-default)'); variable.setVariableCodeSyntax('ANDROID', 'colorBgDefault'); variable.setVariableCodeSyntax('iOS', 'Color.bgDefault'); // 读回:variable.codeSyntax → { WEB: '...', ANDROID: '...', iOS: '...' }从 Figma 名称推导 CSS 名称时,斜杠和空格都要替换为连字符:
// 错误 —— CSS 变量名中残留空格 `var(--${figmaName.replace(/\//g, '-').toLowerCase()})` // 正确 —— 替换所有空白与斜杠 `var(--${figmaName.replace(/[\s\/]+/g, '-').toLowerCase()})` // 最佳 —— 直接用源数据中的原始 CSS 变量名,而非推导 `var(${token.cssVar})`创建前先发现已有变量(关键习惯)
在创建新变量之前,始终检查文件中的既有变量。不同文件使用不同的命名约定、Scope 模式和集合结构,匹配已有内容:
// 列出集合及模式信息 (async () => { try { const collections = figma.variables.getLocalVariableCollections(); const results = collections.map(c => ({ name: c.name, id: c.id, varCount: c.variableIds.length, modes: c.modes.map(m => ({ name: m.name, id: m.modeId })) })); figma.closePlugin(JSON.stringify(results)); } catch(e) { figma.closePluginWithFailure(e.toString()); } })()也可以构建 name→variable 查找表,只为文件中没有匹配的 Token 创建新变量(只创建差集 delta):
const varByName = {}; for (const v of figma.variables.getLocalVariables()) { varByName[v.name] = v; } // 按名称绑定到已有变量——无需 hex 值 function bindFill(node, varName) { const v = varByName[varName]; if (!v) throw new Error(`Variable not found: ${varName}`); const paint = figma.variables.setBoundVariableForPaint( { type: 'SOLID', color: { r: 0, g: 0, b: 0 } }, 'color', v ); node.fills = [paint]; }对于需要异步 API 的场景,可使用getLocalVariableCollectionsAsync()+getVariableByIdAsync()获取包含 Code Syntax 与 Scope 的更丰富数据(完整脚本见 variable-patterns.md 的listVariableCollectionsAndVariables函数)。
创建完成后的收尾:绑定与模式应用
创建变量通常是为了绑定到节点属性,此处给出与「创建」直接衔接的关键绑定模式:
- 颜色绑定:
figma.variables.setBoundVariableForPaint(basePaint, "color", colorVar)返回新的paint,必须捕获返回值再赋给node.fills;只有 SOLID paint 支持颜色变量绑定,渐变/图片会抛错。 - 数值绑定:
node.setBoundVariable("paddingTop", spacingVar)等,可用于 padding、gap(itemSpacing/counterAxisSpacing)、圆角(用topLeftRadius等四个单独角,而非cornerRadius)、尺寸(width/height/minWidth/maxWidth)、opacity、strokeWeight。 fontSize、fontWeight、lineHeight不可通过setBoundVariable绑定,需直接在文本节点上设置。- 模式应用:
frame.setExplicitVariableModeForCollection(collection.id, modeId)让该帧下所有绑定子节点解析到指定模式的值;否则所有节点使用集合的默认(第一个)模式——这与「使用时注意 Mode 不匹配」的警告(见 wwds-variables--using.md)直接相关:Figma 的默认模式未必是用户期望的模式。
小结
创建 Figma 变量不是机械的「值 → 变量」映射,而是一次建模决策:
- 先诊断源数据:识别两层结构(原语 + 语义)、隐含别名关系与 Mode 需求;
- 再规划结构:集合、扩展集合、Mode、分组命名(斜杠分隔)与 Scope 的精确设定;
- 然后落地实现:遵循「先发现已有变量、再创建差集」的习惯,用 Plugin API 创建集合/变量、设置别名与 Code Syntax、显式声明 Scope,并留意「默认 Mode 需重命名」「重复名静默通过」「别名跨文件不支持」等常见坑;
- 最后补齐短板:阴影用效果样式、排版用文本样式,二者均可与变量绑定,共同构成完整的 Token 体系。
如需继续深入,可阅读同目录下的 使用变量指南、效果样式文档 与 文本样式文档,或直接查阅 SKILL.md 获取完整执行规则。
【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考