accelint-design-foundation
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAccelint Design Foundation
Accelint 设计基础
Expert knowledge for styling with and — opinionated Tailwind conventions that differ from vanilla implementations.
@accelint/design-foundation@accelint/design-toolkit本指南提供使用和进行样式设置的专业知识——这些自定义Tailwind规范与原生实现有所不同。
@accelint/design-foundation@accelint/design-toolkitNEVER Do When Styling with Design Foundation
使用设计基础架构时的绝对禁忌
- NEVER use numeric spacing classes as first choice - Strongly prefer the semantic scale: ,
p-xxs,gap-m. Numeric classes likem-l,p-4work with a 1:1 relationship (gap-6= 1px, NOT 4px like vanilla Tailwind), but should only be used for rare cases where implementing non-conforming designs. The semantic scale provides design system consistency.p-1 - NEVER use manual theme handling with raw color values - Avoid or
dark:bg-gray-900. Use semantic color classes likeclassName={theme === 'dark' ? 'bg-black' : 'bg-white'}andbg-surface-defaultthat automatically adapt to light/dark themes.fg-primary-bold - NEVER use borders for sizing elements - Use instead of
outlineclasses. Borders add to element dimensions (breaks layouts), while outlines overlay without affecting size. Elements should size consistently based on content and padding only.border - NEVER use arbitrary Tailwind variants - Arbitrary values like break the design system. Use supported React Aria variants or conditional class rendering with
hover:[&>svg]:opacity-50.clsx - NEVER bypass CSS layers when styling components - Use ,
@layer components.l1for cascade hierarchy. Bypassing layers causes specificity wars and makes overrides unpredictable.@layer components.l2 - NEVER use primitive/domain tokens as first choice - Strongly prefer semantic tokens (,
bg-surface-default) in components. The utility classes (fg-primary-bold,bg-*,fg-*,icon-*) provide fallback access tooutline-*anddomain-*tokens for rare cases where designs go beyond the design system, but this should be exceptional. Semantic tokens provide theming flexibility and design system consistency.primitive-* - NEVER use inline Tailwind classes for component styling - Component styles belong in CSS modules, not inline className props. Inline Tailwind should only be used for minor one-off overrides. Using inline classes for all component styling creates unmaintainable code and loses the benefits of CSS modules (scoping, organization, reusability).
- NEVER use multiple @apply directives in a single CSS rule - Group all Tailwind classes into a single statement. Multiple
@applydirectives prevent Tailwind IDE plugins from sorting classes and identifying issues. Write@applynot separate@apply bg-surface-default outline-1 outline-interactive p-m;lines.@apply - NEVER use attribute selectors for variants in CSS modules - Use directive blocks, not attribute selectors like
@variant. Write[data-size="small"]not@variant size-small { @apply p-s; }. The.button[data-size="small"] { @apply p-s; }directive automatically applies styles when the matching data attribute is present.@variant - NEVER use Tailwind's default theme values - The design foundation removes and replaces Tailwind defaults. Relying on default shadows, font sizes, or colors will break. Use only the semantic classes provided by the design system.
- NEVER omit @reference directive in CSS modules - Every CSS module file must include (if custom entrypoint exists) or
@reference '#globals';at the top. Without this, semantic tokens and @variant blocks are undefined, causing build errors.@reference '@accelint/design-foundation/styles'; - NEVER skip PostCSS configuration - The plugin is required in
@accelint/postcss-tailwind-css-modules. Without it, named group selectors (likepostcss.config.mjs) and @variant selectors fail to resolve in CSS modules.group-hover/button: - NEVER import clsx directly from 'clsx' package - Always import from instead:
@accelint/design-foundation/lib/utils. The design foundation re-exports clsx with additional type support and design system integration. Importing directly bypasses these enhancements.import { clsx } from '@accelint/design-foundation/lib/utils';
- 切勿优先使用数字间距类 - 强烈建议使用语义化比例:、
p-xxs、gap-m。像m-l、p-4这类数字类的比例为1:1(gap-6= 1px,而非原生Tailwind中的4px),但仅应在实现非标准化设计的极少数情况下使用。语义化比例可确保设计系统的一致性。p-1 - 切勿使用原始颜色值手动处理主题 - 避免使用或
dark:bg-gray-900这类写法。使用className={theme === 'dark' ? 'bg-black' : 'bg-white'}和bg-surface-default这类语义化颜色类,它们会自动适配亮色/暗色主题。fg-primary-bold - 切勿使用边框来控制元素尺寸 - 使用类替代
outline类。边框会增加元素的尺寸(破坏布局),而轮廓则是叠加在元素之上,不会影响尺寸。元素应仅根据内容和内边距保持一致的尺寸。border - 切勿使用任意Tailwind变体 - 像这类任意值会破坏设计系统。使用受支持的React Aria变体,或结合
hover:[&>svg]:opacity-50进行条件类渲染。clsx - 设置组件样式时切勿绕过CSS层级 - 使用、
@layer components.l1来控制层级优先级。绕过层级会导致特异性冲突,使样式覆盖变得不可预测。@layer components.l2 - 切勿优先使用基础/领域令牌 - 在组件中强烈建议使用语义化令牌(、
bg-surface-default)。工具类(fg-primary-bold、bg-*、fg-*、icon-*)仅在设计超出设计系统的极少数情况下,才提供对outline-*和domain-*令牌的降级支持,但这种情况应非常罕见。语义化令牌可提供主题灵活性和设计系统一致性。primitive-* - 切勿使用内联Tailwind类设置组件样式 - 组件样式应放在CSS模块中,而非内联className属性。内联Tailwind仅应用于微小的一次性覆盖。如果所有组件样式都使用内联类,会导致代码难以维护,同时失去CSS模块的优势(作用域、组织性、可复用性)。
- 切勿在单个CSS规则中使用多个@apply指令 - 将所有Tailwind类整合到单个语句中。多个
@apply指令会导致Tailwind IDE插件无法正常排序类和识别问题。应编写@apply,而非分开的@apply bg-surface-default outline-1 outline-interactive p-m;行。@apply - 切勿在CSS模块中使用属性选择器实现变体 - 使用指令块,而非像
@variant这类属性选择器。应编写[data-size="small"],而非@variant size-small { @apply p-s; }。.button[data-size="small"] { @apply p-s; }指令会在匹配的数据属性存在时自动应用样式。@variant - 切勿使用Tailwind的默认主题值 - 设计基础架构会移除并替换Tailwind的默认值。依赖默认的阴影、字体大小或颜色会导致样式失效。仅使用设计系统中明确定义的内容。
- 切勿在CSS模块中省略@reference指令 - 每个CSS模块文件必须在顶部包含(如果存在自定义入口点)或
@reference '#globals';。没有该指令,语义化令牌和@variant块将未定义,导致构建错误。@reference '@accelint/design-foundation/styles'; - 切勿跳过PostCSS配置 - 项目的中必须包含
postcss.config.mjs插件。没有该插件,命名组选择器(如@accelint/postcss-tailwind-css-modules)和@variant选择器将无法在CSS模块中正常解析。group-hover/button: - 切勿直接从'clsx'包导入clsx - 应始终从导入:
@accelint/design-foundation/lib/utils。设计基础架构会重新导出clsx,并添加额外的类型支持和设计系统集成。直接导入会绕过这些增强功能。import { clsx } from '@accelint/design-foundation/lib/utils';
Before Styling a Component, Ask
设置组件样式前需确认的问题
Apply these tests to ensure styling aligns with the design system:
通过以下检查确保样式符合设计系统要求:
Theme Compatibility
主题兼容性
- Will this work in both light and dark themes? Use semantic color tokens that adapt automatically. Test by toggling between and
@variant light.@variant dark - Am I using raw color values? If yes, replace with semantic tokens. Raw values don't theme.
- 该样式能否在亮色和暗色主题下正常工作? 使用可自动适配的语义化颜色令牌。通过切换和
@variant light进行测试。@variant dark - 我是否在使用原始颜色值? 如果是,替换为语义化令牌。原始值无法适配主题。
Token System
令牌系统
- Am I using the correct token type? Strongly prefer semantic tokens (,
bg-surface-default). Only usefg-primary-boldordomain-*fallbacks for exceptional cases where design goes beyond the system.primitive-* - Is there a semantic token for this? Check the token catalog first. If no semantic token exists and the design genuinely requires it, fallback to or
domain-*is acceptable but rare.primitive-*
- 我是否使用了正确的令牌类型? 强烈建议使用语义化令牌(、
bg-surface-default)。仅在设计超出系统的特殊情况下,才使用fg-primary-bold或domain-*降级方案。primitive-* - 是否存在适用于此场景的语义化令牌? 首先查看令牌目录。如果没有语义化令牌且设计确实需要,可使用或
domain-*作为降级方案,但这种情况应非常罕见。primitive-*
Token Selection Framework
令牌选择框架
When choosing a token, follow this decision tree:
- Identify element purpose - Is this a surface, text, icon, or outline?
- Determine hierarchy - Primary, secondary, or tertiary emphasis?
- Consider state - Default, hover, active, disabled?
- Check status - Info, success, warning, danger?
Example: "I need text color for a primary heading"
→ Purpose: text ()
→ Hierarchy: primary with emphasis ()
→ Result:
fg-*primary-boldfg-primary-boldExample: "I need background for an interactive button in hover state"
→ Purpose: background ()
→ State: interactive hover ()
→ Result:
bg-*interactive-bold-hoverbg-interactive-bold-hover选择令牌时,请遵循以下决策流程:
- 确定元素用途 - 这是表面、文本、图标还是轮廓?
- 确定层级 - 主要、次要还是三级强调?
- 考虑状态 - 默认、悬停、激活、禁用?
- 检查状态类型 - 信息、成功、警告、危险?
示例: "我需要为一级标题设置文本颜色"
→ 用途:文本()
→ 层级:带强调的主要文本()
→ 结果:
fg-*primary-boldfg-primary-bold示例: "我需要为处于悬停状态的交互按钮设置背景色"
→ 用途:背景()
→ 状态:交互悬停()
→ 结果:
bg-*interactive-bold-hoverbg-interactive-bold-hoverSpacing System
间距系统
- Does this spacing value exist in the semantic scale? Use scale. If a value isn't in the scale, question whether it's needed or use the closest semantic value.
xxs/xs/s/m/l/xl/xxl/oversized - Need a non-standard spacing value? Numeric classes (,
p-1) work with 1:1 relationship (p-1 = 1px, NOT 4px), but only use for rare non-conforming design cases. Semantic scale is strongly preferred for consistency.m-12
- 该间距值是否存在于语义化比例中? 使用比例。如果某个值不在比例中,应质疑其必要性,或使用最接近的语义化值。
xxs/xs/s/m/l/xl/xxl/oversized - 是否需要非标准间距值? 数字类(、
p-1)的比例为1:1(p-1 = 1px,而非4px),但仅应在非标准化设计的极少数情况下使用。语义化比例是确保一致性的首选方案。m-12
Variant Usage
变体使用
- Can this be expressed with data attributes? Use with supported variants instead of arbitrary classes.
data-color="info" - Am I overriding Design Toolkit components correctly? Use or
classNameprops, not custom CSS files.classNames
- 能否通过数据属性实现该效果? 使用结合受支持的变体,而非任意类。
data-color="info" - 我是否在正确覆盖Design Toolkit组件? 使用或
className属性,而非自定义CSS文件。classNames
Layout Impact
布局影响
- Will outlines work here or do I need borders? Outlines work for most cases. Borders are only needed when the border must affect layout dimensions.
- 此处使用轮廓是否可行,还是需要边框? 轮廓适用于大多数情况。仅当边框必须影响布局尺寸时才使用边框。
Styling Approach
样式设置方式
- Should this be in CSS modules or inline? Component styles belong in CSS modules (.module.css). Only use inline Tailwind classes for minor one-off overrides or adjustments.
- Is this a reusable component or one-off instance? Reusable components require CSS modules. One-off instances can use inline classes for small tweaks.
- 该样式应放在CSS模块中还是内联? 组件样式应放在CSS模块(.module.css)中。仅在微小的一次性覆盖或调整时使用内联Tailwind类。
- 这是可复用组件还是一次性实例? 可复用组件需要使用CSS模块。一次性实例可使用内联类进行小调整。
Setup Verification
配置验证
- Is PostCSS configured correctly? Check that plugin is in
@accelint/postcss-tailwind-css-modules. Without it, named groups and @variant selectors won't work in CSS modules.postcss.config.mjs - Does every CSS module have @reference? Each file must reference either
.module.css(custom entrypoint) or'#globals'at the top.'@accelint/design-foundation/styles' - Is the CSS entrypoint imported first? Custom globals.css (or design-foundation/styles) must be the first import in the root layout.
- PostCSS配置是否正确? 检查中是否包含
postcss.config.mjs插件。没有该插件,命名组和@variant选择器将无法在CSS模块中正常工作。@accelint/postcss-tailwind-css-modules - 每个CSS模块是否都有@reference? 每个文件必须在顶部引用
.module.css(自定义入口点)或'#globals'。'@accelint/design-foundation/styles' - CSS入口点是否是第一个导入的? 自定义globals.css(或design-foundation/styles)必须是根布局中的第一个导入项。
Setup Requirements
设置要求
CRITICAL: Design foundation requires specific PostCSS and CSS module configuration to work correctly.
重要提示:设计基础架构需要特定的PostCSS和CSS模块配置才能正常工作。
PostCSS Configuration
PostCSS配置
Create or update in project root:
postcss.config.mjsjavascript
export default {
plugins: {
'@tailwindcss/postcss': {},
'@accelint/postcss-tailwind-css-modules': {}, // Required for CSS modules
},
};Why: The plugin fixes named group resolution in CSS module selectors (e.g., ) and @variant selectors. Without it, these selectors fail to resolve correctly in CSS module files.
@accelint/postcss-tailwind-css-modulesgroup-hover/button:在项目根目录创建或更新:
postcss.config.mjsjavascript
export default {
plugins: {
'@tailwindcss/postcss': {},
'@accelint/postcss-tailwind-css-modules': {}, // CSS模块必需
},
};原因: 插件可修复CSS模块选择器中命名组的解析问题(如)以及@variant选择器。没有该插件,这些选择器将无法在CSS模块文件中正确解析。
@accelint/postcss-tailwind-css-modulesgroup-hover/button:Package.json Imports (If Custom CSS Entrypoint Exists)
Package.json导入(如果存在自定义CSS入口点)
If the project implements a custom CSS entrypoint for token/utility configuration:
json
{
"imports": {
"#globals": "./src/styles/globals.css"
}
}Purpose: Allows CSS modules to reference the custom entrypoint via
@reference '#globals';如果项目实现了用于令牌/工具类配置的自定义CSS入口点:
json
{
"imports": {
"#globals": "./src/styles/globals.css"
}
}用途: 允许CSS模块通过引用自定义入口点
@reference '#globals';CSS Module Reference Pattern
CSS模块引用模式
Every CSS module file must include a reference directive:
css
/* If project has custom CSS entrypoint (defined in package.json imports): */
@reference '#globals';
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}css
/* If NO custom CSS entrypoint, reference design-foundation directly: */
@reference '@accelint/design-foundation/styles';
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}Why: The @reference directive imports the design system's tokens, utilities, and variant definitions. Without it, semantic tokens and @variant blocks are undefined.
每个CSS模块文件必须包含引用指令:
css
/* 如果项目有自定义CSS入口点(在package.json imports中定义): */
@reference '#globals';
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}css
/* 如果没有自定义CSS入口点,直接引用design-foundation: */
@reference '@accelint/design-foundation/styles';
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}原因: @reference指令会导入设计系统的令牌、工具类和变体定义。没有该指令,语义化令牌和@variant块将未定义。
Custom CSS Entrypoint (Optional)
自定义CSS入口点(可选)
If implementing custom tokens or utilities, create a CSS entrypoint (e.g., ):
src/styles/globals.csscss
/* Import design foundation base */
@import "@accelint/design-foundation/styles";
/* Add custom token overrides or utilities here */
@theme {
--custom-brand-color: #ff0000;
}Then: Import this file as the first import in your root layout component:
tsx
import './styles/globals.css'; // First import
import { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return <html>{children}</html>;
}如果要实现自定义令牌或工具类,创建一个CSS入口点(如):
src/styles/globals.csscss
/* 导入设计基础架构基础样式 */
@import "@accelint/design-foundation/styles";
/* 在此处添加自定义令牌覆盖或工具类 */
@theme {
--custom-brand-color: #ff0000;
}然后: 在根布局组件中将该文件作为第一个导入项:
tsx
import './styles/globals.css'; // 第一个导入
import { ReactNode } from 'react';
export default function RootLayout({ children }: { children: ReactNode }) {
return <html>{children}</html>;
}How to Use
使用方法
This skill uses progressive disclosure to minimize context usage:
本指南采用渐进式信息披露方式,以最小化上下文使用:
1. Start with Core Patterns (SKILL.md)
1. 从核心模式开始(SKILL.md)
Follow the styling patterns and token usage below for consistent implementation.
遵循以下样式设置模式和令牌使用方法,确保实现一致性。
2. Reference Token Catalog (AGENTS.md)
2. 参考令牌目录(AGENTS.md)
Load AGENTS.md for quick reference of available tokens, spacing scale, and variant patterns.
加载AGENTS.md,快速查阅可用的令牌、间距比例和变体模式。
3. Load Detailed References as Needed
3. 根据需要加载详细参考文档
MANDATORY loading triggers - Load these references in specific scenarios:
Setting up design foundation for the first time:
- MANDATORY: Load references/setup.md (~8.9K) completely when user says "setup design foundation", "configure design foundation", "install design foundation", or encounters build errors like "undefined variable" or "@variant not found"
- Do NOT Load: token-reference.md, variant-system.md, spacing-scale.md, migration-guide.md
Choosing tokens or understanding token hierarchy:
- MANDATORY: Load references/token-reference.md (~6.5K) when uncertain which semantic token to use or when user needs complete token catalog
- Do NOT Load: setup.md (unless build errors), migration-guide.md (unless migrating)
Working with @variant system or component variants:
- MANDATORY: Load references/variant-system.md (~5.8K) when implementing data attribute variants or working with React Aria states
- Do NOT Load: setup.md (unless build errors), migration-guide.md (unless migrating)
Understanding spacing scale or numeric fallbacks:
- MANDATORY: Load references/spacing-scale.md (~8.5K) when confused about semantic vs numeric spacing or need complete spacing catalog
- Do NOT Load: token-reference.md (unless also working with colors), setup.md (unless build errors)
Migrating from vanilla Tailwind:
- MANDATORY: Load references/migration-guide.md (~4.2K) when converting existing Tailwind code to design foundation conventions
- Do NOT Load: Other references unless specific issues arise after migration
Troubleshooting build errors or setup issues:
- MANDATORY: Load references/setup.md completely when encountering errors like "undefined variable", "@variant not found", "group-hover/button: not working"
- Do NOT Load: Other references until setup is confirmed working
强制加载触发条件 - 在特定场景下加载以下参考文档:
首次设置设计基础架构时:
- 强制加载:当用户提及“setup design foundation”“configure design foundation”“install design foundation”,或遇到“undefined variable”“@variant not found”等构建错误时,完整加载references/setup.md(约8.9K)
- 请勿加载:token-reference.md、variant-system.md、spacing-scale.md、migration-guide.md
选择令牌或理解令牌层级时:
- 强制加载:当不确定使用哪个语义化令牌,或用户需要完整令牌目录时,加载references/token-reference.md(约6.5K)
- 请勿加载:setup.md(除非遇到构建错误)、migration-guide.md(除非进行迁移)
使用@variant系统或组件变体时:
- 强制加载:当实现数据属性变体或处理React Aria状态时,加载references/variant-system.md(约5.8K)
- 请勿加载:setup.md(除非遇到构建错误)、migration-guide.md(除非进行迁移)
理解间距比例或数字降级方案时:
- 强制加载:当对语义化与数字间距感到困惑,或需要完整间距目录时,加载references/spacing-scale.md(约8.5K)
- 请勿加载:token-reference.md(除非同时处理颜色)、setup.md(除非遇到构建错误)
从原生Tailwind迁移时:
- 强制加载:当将现有Tailwind代码转换为设计基础架构规范时,加载references/migration-guide.md(约4.2K)
- 请勿加载:其他参考文档,除非迁移后出现特定问题
排查构建错误或设置问题时:
- 强制加载:当遇到“undefined variable”“@variant not found”“group-hover/button: not working”等错误时,完整加载references/setup.md
- 请勿加载:其他参考文档,除非确认设置已正常工作
Styling Patterns
样式设置模式
CSS Modules for Component Styling
使用CSS模块设置组件样式
Default approach: Component styles in CSS modules with @apply directives.
user-card.module.css:
css
@layer components.l1 {
/* ✅ Single @apply per rule - enables IDE plugin support */
.card {
@apply bg-surface-default outline-1 outline-interactive shadow-elevation-raised-muted p-m;
}
.header {
@apply flex items-center justify-between mb-s;
}
.title {
@apply fg-primary-bold text-body-l;
}
.content {
@apply space-y-xs mb-m;
}
.email {
@apply fg-primary-bold text-body-m;
}
.role {
@apply fg-primary-muted text-body-s;
}
.actions {
@apply flex gap-s;
}
}
/* ❌ Wrong - multiple @apply directives break IDE plugins */
/*
.card {
@apply bg-surface-default;
@apply outline-1 outline-interactive;
@apply shadow-elevation-raised-muted;
@apply p-m;
}
*/user-card.tsx:
tsx
import styles from './user-card.module.css';
export function UserCard({ name, email, role }) {
return (
<article className={styles.card}>
<header className={styles.header}>
<h3 className={styles.title}>{name}</h3>
</header>
<div className={styles.content}>
<p className={styles.email}>{email}</p>
<p className={styles.role}>{role}</p>
</div>
</article>
);
}Inline classes only for one-off overrides:
tsx
// ✅ Correct - CSS module + inline override for specific instance
<UserCard className="mb-xl" /> {/* One-off spacing adjustment */}
// ❌ Wrong - all styling inline
<div className="bg-surface-default outline-1 outline-interactive shadow-elevation-raised-muted p-m">
<h3 className="fg-primary-bold text-body-l">{name}</h3>
</div>Conditional classes with clsx:
tsx
// ✅ Correct - import clsx from design foundation
import { clsx } from '@accelint/design-foundation/lib/utils';
import styles from './Button.module.css';
export function Button({ variant, isActive }) {
return (
<button className={clsx(styles.button, isActive && styles.active)}>
Click me
</button>
);
}
// ❌ Wrong - importing directly from clsx package
import clsx from 'clsx';默认方式:通过@apply指令在CSS模块中设置组件样式。
user-card.module.css:
css
@layer components.l1 {
/* ✅ 单个规则对应单个@apply - 支持IDE插件 */
.card {
@apply bg-surface-default outline-1 outline-interactive shadow-elevation-raised-muted p-m;
}
.header {
@apply flex items-center justify-between mb-s;
}
.title {
@apply fg-primary-bold text-body-l;
}
.content {
@apply space-y-xs mb-m;
}
.email {
@apply fg-primary-bold text-body-m;
}
.role {
@apply fg-primary-muted text-body-s;
}
.actions {
@apply flex gap-s;
}
}
/* ❌ 错误 - 多个@apply指令会破坏IDE插件功能 */
/*
.card {
@apply bg-surface-default;
@apply outline-1 outline-interactive;
@apply shadow-elevation-raised-muted;
@apply p-m;
}
*/user-card.tsx:
tsx
import styles from './user-card.module.css';
export function UserCard({ name, email, role }) {
return (
<article className={styles.card}>
<header className={styles.header}>
<h3 className={styles.title}>{name}</h3>
</header>
<div className={styles.content}>
<p className={styles.email}>{email}</p>
<p className={styles.role}>{role}</p>
</div>
</article>
);
}内联类仅用于一次性覆盖:
tsx
// ✅ 正确 - CSS模块 + 针对特定实例的内联覆盖
<UserCard className="mb-xl" /> {/* 一次性间距调整 */}
// ❌ 错误 - 所有样式都使用内联
<div className="bg-surface-default outline-1 outline-interactive shadow-elevation-raised-muted p-m">
<h3 className="fg-primary-bold text-body-l">{name}</h3>
</div>结合clsx实现条件类:
tsx
// ✅ 正确 - 从设计基础架构导入clsx
import { clsx } from '@accelint/design-foundation/lib/utils';
import styles from './Button.module.css';
export function Button({ variant, isActive }) {
return (
<button className={clsx(styles.button, isActive && styles.active)}>
Click me
</button>
);
}
// ❌ 错误 - 直接从clsx包导入
import clsx from 'clsx';Token Categories
令牌分类
Background tokens ():
bg-*- - Primary surface (page/card background)
bg-surface-default - - Raised/elevated surface
bg-surface-raised - - Primary action background
bg-interactive-bold - - Info message backgrounds
bg-info-muted - - Warning message backgrounds
bg-advisory-muted - - Error/danger message backgrounds
bg-critical-muted - - Success message backgrounds
bg-normal-muted
Foreground tokens ():
fg-*- - Primary text (headlines, body text)
fg-primary-bold - - Subtle text (captions, secondary content)
fg-primary-muted - - Text on dark/colored backgrounds
fg-inverse-bold - - Interactive text/links
fg-accent-primary-bold - - Error/danger text
fg-critical-bold
Outline tokens ():
outline-*- - Interactive outlines (buttons, inputs)
outline-interactive - - Static outlines (borders, dividers)
outline-static - - Info state outlines
outline-info-bold - - Warning state outlines
outline-advisory-bold - - Error/danger state outlines
outline-critical-bold
Token fallback pattern:
tsx
// ✅ Preferred - semantic tokens
<div className="bg-surface-default fg-primary-bold">Content</div>
// ⚠️ Acceptable but rare - domain/primitive fallback for edge cases
<div className="bg-domain-brand fg-primitive-blue-500">
{/* Use only when design exceeds system */}
</div>
// ❌ Wrong - using fallbacks when semantic tokens exist
<div className="bg-primitive-neutral-100 fg-primitive-neutral-900">
{/* Should use bg-surface-default fg-primary-bold */}
</div>背景令牌():
bg-*- - 主要表面(页面/卡片背景)
bg-surface-default - - 凸起/悬浮表面
bg-surface-raised - - 主要操作背景
bg-interactive-bold - - 信息提示背景
bg-info-muted - - 警告提示背景
bg-advisory-muted - - 错误/危险提示背景
bg-critical-muted - - 成功提示背景
bg-normal-muted
前景令牌():
fg-*- - 主要文本(标题、正文)
fg-primary-bold - - 次要文本(说明、辅助内容)
fg-primary-muted - - 深色/彩色背景上的文本
fg-inverse-bold - - 交互文本/链接
fg-accent-primary-bold - - 错误/危险文本
fg-critical-bold
轮廓令牌():
outline-*- - 交互元素轮廓(按钮、输入框)
outline-interactive - - 静态轮廓(边框、分隔线)
outline-static - - 信息状态轮廓
outline-info-bold - - 警告状态轮廓
outline-advisory-bold - - 错误/危险状态轮廓
outline-critical-bold
令牌降级模式:
tsx
// ✅ 首选 - 语义化令牌
<div className="bg-surface-default fg-primary-bold">内容</div>
// ⚠️ 可接受但罕见 - 针对边缘情况使用领域/基础令牌降级
<div className="bg-domain-brand fg-primitive-blue-500">
{/* 仅在设计超出系统时使用 */}
</div>
// ❌ 错误 - 当存在语义化令牌时使用降级方案
<div className="bg-primitive-neutral-100 fg-primitive-neutral-900">
{/* 应使用bg-surface-default fg-primary-bold */}
</div>Spacing Scale
间距比例
Eight-step semantic scale: → → → → → → →
xxsxssmlxlxxloversizedThink semantic meaning, not pixels. means "medium for this context", not a specific pixel value.
mCSS module usage:
css
.button {
@apply px-m py-xs; /* ✅ Semantic spacing - preferred */
}
.card {
@apply p-m space-y-s; /* ✅ Semantic scale for consistency */
}
/* ⚠️ Acceptable but rare - numeric fallback for edge cases */
.nonStandardLayout {
@apply p-13; /* 13px exactly - use only for non-conforming designs */
/* Note: p-1 = 1px (not 4px like vanilla Tailwind) */
}Spacing fallback pattern:
- Preferred: Use semantic scale (,
p-m,gap-s)mb-l - Fallback: Numeric classes available with 1:1 relationship (p-1 = 1px, p-12 = 12px)
- When to use numeric: Only for non-conforming designs where semantic scale doesn't fit
八级语义化比例: → → → → → → →
xxsxssmlxlxxloversized关注语义含义,而非像素值。表示“此场景下的中等间距”,而非特定像素值。
mCSS模块使用示例:
css
.button {
@apply px-m py-xs; /* ✅ 语义化间距 - 首选方案 */
}
.card {
@apply p-m space-y-s; /* ✅ 语义化比例确保一致性 */
}
/* ⚠️ 可接受但罕见 - 针对边缘情况使用数字降级 */
.nonStandardLayout {
@apply p-13; /* 精确13px - 仅用于非标准化设计 */
/* 注意:p-1 = 1px(而非原生Tailwind中的4px) */
}间距降级模式:
- 首选:使用语义化比例(、
p-m、gap-s)mb-l - 降级:数字类支持1:1比例(p-1 = 1px,p-12 = 12px)
- 何时使用数字类:仅当语义化比例不适用的非标准化设计时
Outlines vs Borders
轮廓与边框
Prefer outlines - they don't affect element dimensions.
css
/* ✅ Correct - outline doesn't impact layout */
.card {
@apply outline-1 outline-interactive;
}
/* ❌ Wrong - border adds to dimensions */
.card {
@apply border-2 border-gray-300;
}Use borders only when:
- Border must participate in layout (table cells)
- Dimension impact is explicitly desired
优先使用轮廓 - 轮廓不会影响元素尺寸。
css
/* ✅ 正确 - 轮廓不影响布局 */
.card {
@apply outline-1 outline-interactive;
}
/* ❌ 错误 - 边框会增加尺寸 */
.card {
@apply border-2 border-gray-300;
}仅在以下情况使用边框:
- 边框必须参与布局(表格单元格)
- 明确需要尺寸变化的效果
Variant System
变体系统
Use data attributes for component variants:
Button.module.css:
css
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}
@layer components.l2 {
/* ✅ Use @variant blocks for conditional styling */
.button {
@variant color-info {
@apply bg-interactive-bold fg-inverse-bold;
}
@variant color-critical {
@apply outline-2 outline-critical-bold fg-critical-bold;
}
@variant size-large {
@apply px-l py-s;
}
}
}
/* ❌ Wrong - attribute selectors */
/*
.button[data-color="primary"] {
@apply bg-interactive-bold;
}
*/Button.tsx:
tsx
import styles from './Button.module.css';
export function Button({ children, color = 'primary', size = 'medium' }) {
return (
<button
className={styles.button}
data-color={color}
data-size={size}
>
{children}
</button>
);
}Common variants:
- :
data-color,info,success,warningdanger - :
data-size,small,mediumlarge - :
data-state,active,disabledloading
使用数据属性实现组件变体:
Button.module.css:
css
@layer components.l1 {
.button {
@apply px-m py-xs;
}
}
@layer components.l2 {
/* ✅ 使用@variant块实现条件样式 */
.button {
@variant color-info {
@apply bg-interactive-bold fg-inverse-bold;
}
@variant color-critical {
@apply outline-2 outline-critical-bold fg-critical-bold;
}
@variant size-large {
@apply px-l py-s;
}
}
}
/* ❌ 错误 - 使用属性选择器 */
/*
.button[data-color="primary"] {
@apply bg-interactive-bold;
}
*/Button.tsx:
tsx
import styles from './Button.module.css';
export function Button({ children, color = 'primary', size = 'medium' }) {
return (
<button
className={styles.button}
data-color={color}
data-size={size}
>
{children}
</button>
);
}常见变体:
- :
data-color、info、success、warningdanger - :
data-size、small、mediumlarge - :
data-state、active、disabledloading
CSS Layer Hierarchy
CSS层级优先级
Always use layers in CSS modules:
css
/* ✅ Correct - layered for predictable specificity */
@layer components.l1 {
.base-styles { /* Base component styles */ }
}
@layer components.l2 {
.variant-styles { /* Variant styles */ }
}
@layer components.l3 {
.state-styles { /* State styles */ }
}
/* ❌ Wrong - no layers causes specificity issues */
.component {
background: var(--bg-surface-default);
}Layer order: l1 (base) < l2 (variants) < l3 (states)
在CSS模块中始终使用层级:
css
/* ✅ 正确 - 分层确保可预测的特异性 */
@layer components.l1 {
.base-styles { /* 基础组件样式 */ }
}
@layer components.l2 {
.variant-styles { /* 变体样式 */ }
}
@layer components.l3 {
.state-styles { /* 状态样式 */ }
}
/* ❌ 错误 - 无层级会导致特异性问题 */
.component {
background: var(--bg-surface-default);
}层级顺序: l1(基础) < l2(变体) < l3(状态)
Overriding Design Toolkit Components
覆盖Design Toolkit组件
Use className prop for overrides:
tsx
// ✅ Correct - override with inline class
<DesignToolkitButton className="mb-l">
Action
</DesignToolkitButton>
// ✅ Correct - use classNames prop for internal elements
<DesignToolkitButton classNames={{ icon: 'icon-override' }}>
Action
</DesignToolkitButton>使用className属性进行覆盖:
tsx
// ✅ 正确 - 使用内联类进行覆盖
<DesignToolkitButton className="mb-l">
操作
</DesignToolkitButton>
// ✅ 正确 - 使用classNames属性覆盖内部元素
<DesignToolkitButton classNames={{ icon: 'icon-override' }}>
操作
</DesignToolkitButton>Common Issues
常见问题
Issue: "undefined variable --bg-surface-default"
问题:"undefined variable --bg-surface-default"
Cause: Missing @reference directive in CSS module.
Fix: Add or at the top of the CSS module file.
@reference '#globals';@reference '@accelint/design-foundation/styles';css
/* ✅ Correct */
@reference '@accelint/design-foundation/styles';
@layer components.l1 {
.card {
@apply bg-surface-default; /* Now defined */
}
}原因: CSS模块中缺少@reference指令。
解决方法: 在CSS模块文件顶部添加或。
@reference '#globals';@reference '@accelint/design-foundation/styles';css
/* ✅ 正确 */
@reference '@accelint/design-foundation/styles';
@layer components.l1 {
.card {
@apply bg-surface-default; /* 现在已定义 */
}
}Issue: "@variant directive not recognized"
问题:"@variant directive not recognized"
Cause: Missing @reference directive or PostCSS plugin not configured.
Fix 1: Verify @reference directive exists at top of CSS module.
Fix 2: Check includes plugin:
postcss.config.mjs@accelint/postcss-tailwind-css-modulesjavascript
export default {
plugins: {
'@tailwindcss/postcss': {},
'@accelint/postcss-tailwind-css-modules': {}, // Add this
},
};原因: 缺少@reference指令或未配置PostCSS插件。
解决方法1: 验证CSS模块顶部是否存在@reference指令。
解决方法2: 检查是否包含插件:
postcss.config.mjs@accelint/postcss-tailwind-css-modulesjavascript
export default {
plugins: {
'@tailwindcss/postcss': {},
'@accelint/postcss-tailwind-css-modules': {}, // 添加此项
},
};Issue: "group-hover/button: selector not working"
问题:"group-hover/button: selector not working"
Cause: Missing plugin.
@accelint/postcss-tailwind-css-modulesFix: Add plugin to (see above).
postcss.config.mjs原因: 缺少插件。
@accelint/postcss-tailwind-css-modules解决方法: 将插件添加到(见上文)。
postcss.config.mjsIssue: Styles not applying / tokens showing as raw values
问题:样式未生效 / 令牌显示为原始值
Cause: CSS entrypoint not imported or imported too late.
Fix: Ensure globals.css (or ) is the FIRST import in root layout:
@accelint/design-foundation/stylestsx
// ✅ Correct order
import './styles/globals.css'; // First
import './other-styles.css';
import Component from './Component';
// ❌ Wrong order
import Component from './Component';
import './styles/globals.css'; // Too late原因: CSS入口点未导入,或导入顺序过晚。
解决方法: 确保globals.css(或)是根布局中的第一个导入项:
@accelint/design-foundation/stylestsx
// ✅ 正确顺序
import './styles/globals.css'; // 第一个
import './other-styles.css';
import Component from './Component';
// ❌ 错误顺序
import Component from './Component';
import './styles/globals.css'; // 过晚Issue: "Cannot find module '#globals'"
问题:"Cannot find module '#globals'"
Cause: Missing package.json imports field or path incorrect.
Fix: Add imports to package.json:
json
{
"imports": {
"#globals": "./src/styles/globals.css"
}
}Or change @reference to direct path:
css
@reference './styles/globals.css';Or use design-foundation directly:
css
@reference '@accelint/design-foundation/styles';原因: 缺少package.json imports字段,或路径错误。
解决方法: 在package.json中添加imports:
json
{
"imports": {
"#globals": "./src/styles/globals.css"
}
}或 将@reference改为直接路径:
css
@reference './styles/globals.css';或 直接使用design-foundation:
css
@reference '@accelint/design-foundation/styles';Important Notes
重要说明
- Tailwind defaults are removed - The design foundation resets Tailwind's default theme. Don't rely on any default values for colors, spacing, shadows, or typography. Only use what's explicitly defined in the design system.
- Semantic tokens are CSS variables - All semantic tokens compile to CSS custom properties like . They can be used in custom CSS when utilities aren't sufficient, but prefer utilities.
var(--bg-surface-default) - Token fallback chain exists - Utility classes (,
bg-*,fg-*,icon-*) check semantic tokens first, then fall back tooutline-*anddomain-*tokens. This fallback is intentional for rare cases where designs exceed the design system, but semantic tokens should be the default choice for consistency and theming.primitive-* - Spacing scale is semantic, not pixel-mapped - Don't think "m = 16px". Think "m = medium spacing for this context". The scale adapts to different contexts (button padding vs section margin). Numeric classes work with 1:1 relationship (p-1 = 1px, NOT 4px), but are fallbacks for non-conforming designs only.
- Theme variants use @ directives - The and
@theme staticsyntax is custom. Don't confuse with standard CSS media queries. Themes are applied via class/attribute on root element.@variant light/dark - Design Toolkit components are React Aria - They use React Aria for accessibility. Don't fight the React Aria state management or variants. Work with and
classNameprops.classNames - Setup is NOT optional - The PostCSS plugin and @reference directives are required, not conveniences. Missing setup causes cryptic build errors ("undefined variable", "@variant not found"). Always verify setup before debugging styling issues.
- Tailwind默认值已被移除 - 设计基础架构会重置Tailwind的默认主题。不要依赖任何默认的颜色、间距、阴影或排版值。仅使用设计系统中明确定义的内容。
- 语义化令牌是CSS变量 - 所有语义化令牌都会编译为CSS自定义属性,如。当工具类无法满足需求时,可在自定义CSS中使用它们,但优先使用工具类。
var(--bg-surface-default) - 令牌存在降级链 - 工具类(、
bg-*、fg-*、icon-*)会先检查语义化令牌,然后降级到outline-*和domain-*令牌。这种降级是为设计超出系统的极少数情况设计的,但语义化令牌应始终是默认选择,以确保一致性和主题兼容性。primitive-* - 间距比例是语义化的,而非像素映射 - 不要认为“m = 16px”。应认为“m = 此场景下的中等间距”。比例会适配不同场景(按钮内边距 vs 区块外边距)。数字类支持1:1比例(p-1 = 1px,而非4px),但仅作为非标准化设计的降级方案。
- 主题变体使用@指令 - 和
@theme static语法是自定义的。不要与标准CSS媒体查询混淆。主题通过根元素上的类/属性应用。@variant light/dark - Design Toolkit组件基于React Aria - 它们使用React Aria实现无障碍功能。不要修改React Aria的状态管理或变体。应使用和
className属性进行扩展。classNames - 设置并非可选 - PostCSS插件和@reference指令是必需的,而非便利功能。缺少设置会导致难以理解的构建错误(“undefined variable”“@variant not found”)。在排查样式问题前,始终先验证设置是否正确。