canvas-styling-conventions
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTechnology stack
技术栈
| Technology | Purpose |
|---|---|
| Tailwind CSS 4.1+ | Styling |
| class-variance-authority (CVA) | Component variants |
| Class name merging |
Only use these dependencies for styling. Do not add third-party CSS libraries or
create new styling utilities.
| 技术 | 用途 |
|---|---|
| Tailwind CSS 4.1+ | 样式设置 |
| class-variance-authority (CVA) | 组件变体 |
| 类名合并 |
仅使用这些依赖项进行样式设置。请勿添加第三方CSS库或创建新的样式工具。
Styling conventions
样式设置规范
- Use Tailwind's theme colors (,
primary-*) defined ingray-*.global.css - Avoid hardcoded color values; use theme tokens instead.
- Follow the existing focus, hover, and active state patterns from examples.
- 使用在中定义的Tailwind主题颜色(
global.css、primary-*)。gray-* - 避免硬编码颜色值;请改用主题令牌。
- 遵循示例中的现有焦点、悬停和激活状态模式。
The cn() utility
cn()工具函数
Use to merge Tailwind classes. It combines for conditional classes
with to resolve conflicting utilities. Import from either
source:
cn()clsxtailwind-mergejsx
import { cn } from "@/lib/utils";
// or
import { cn } from "drupal-canvas";Example usage:
jsx
const Button = ({ variant, className, children }) => (
<button
className={cn(
"rounded px-4 py-2",
variant === "primary" && "bg-primary-600 text-white",
variant === "secondary" && "bg-gray-200 text-gray-800",
className,
)}
>
{children}
</button>
);使用合并Tailwind类。它结合了用于条件类,以及用于解决工具类冲突。可从以下任一来源导入:
cn()clsxtailwind-mergejsx
import { cn } from "@/lib/utils";
// or
import { cn } from "drupal-canvas";示例用法:
jsx
const Button = ({ variant, className, children }) => (
<button
className={cn(
"rounded px-4 py-2",
variant === "primary" && "bg-primary-600 text-white",
variant === "secondary" && "bg-gray-200 text-gray-800",
className,
)}
>
{children}
</button>
);Accept className for style customization
接受className以自定义样式
Every component should accept a prop to allow style overrides. Pass
it to as the last argument so consumer classes take precedence.
classNamecn()jsx
const Card = ({ colorScheme, className, children }) => (
<div className={cn(cardVariants({ colorScheme }), className)}>{children}</div>
);classNameclassNamecomponent.yml每个组件都应接受属性以允许样式覆盖。将其作为最后一个参数传递给,以便使用者的类优先生效。
classNamecn()jsx
const Card = ({ colorScheme, className, children }) => (
<div className={cn(cardVariants({ colorScheme }), className)}>{children}</div>
);classNameclassNamecomponent.ymlTailwind 4 theme variables
Tailwind 4主题变量
Canvas projects use Tailwind CSS 4's directive to define design tokens
in . Variables defined inside automatically become
available as Tailwind utility classes.
@themeglobal.css@theme { }Always check for available design tokens. The block is
the source of truth for colors, fonts, breakpoints, and other design tokens.
global.css@themeCanvas项目使用Tailwind CSS 4的指令在中定义设计令牌。内定义的变量会自动成为可用的Tailwind工具类。
@themeglobal.css@theme { }请务必查看中的可用设计令牌。块是颜色、字体、断点及其他设计令牌的唯一可信来源。
global.css@themeHow theme variables map to utility classes
主题变量如何映射到工具类
When you define a CSS variable in , Tailwind 4 automatically generates
corresponding utility classes based on the variable's namespace prefix:
@themeCSS Variable in | Generated Utility Classes |
|---|---|
| |
| |
| |
| |
The pattern is: becomes .
--{namespace}-{name}{utility}-{name}当您在中定义CSS变量时,Tailwind 4会根据变量的命名空间前缀自动生成对应的工具类:
@theme | 生成的工具类 |
|---|---|
| |
| |
| |
| |
模式为: 变为 。
--{namespace}-{name}{utility}-{name}Examples
示例
Given this definition in :
global.csscss
@theme {
--color-primary-600: #1899cb;
--color-primary-700: #1487b4;
}You can use these colors with any color-accepting utility:
jsx
// Correct
<button className="bg-primary-600 hover:bg-primary-700 text-white">
Click me
</button>
// Wrong
<button className="bg-[#1899cb] text-white hover:bg-[#1487b4]">Click me</button>Arbitrary values (e.g., ) are acceptable for rare, one-off cases
where adding a theme variable would be overkill. However, if a color appears in
multiple places or represents a brand/design system value, add it to
instead.
bg-[#xxx]@theme假设在中有以下定义:
global.csscss
@theme {
--color-primary-600: #1899cb;
--color-primary-700: #1487b4;
}您可以将这些颜色用于任何接受颜色的工具类:
jsx
// 正确
<button className="bg-primary-600 hover:bg-primary-700 text-white">
点击我
</button>
// 错误
<button className="bg-[#1899cb] text-white hover:bg-[#1487b4]">点击我</button>对于罕见的一次性场景,添加主题令牌过于繁琐时,可使用任意值(如)。但如果某颜色出现在多个位置,或代表品牌/设计系统值,请改为将其添加到中。
bg-[#xxx]@themeSemantic aliases
语义别名
Theme variables can reference other variables to create semantic aliases:
css
@theme {
--color-primary-700: #1487b4;
--color-primary-dark: var(--color-primary-700);
}Both and will work. Use semantic aliases when
they better express intent (e.g., for a darker brand variant).
bg-primary-700bg-primary-darkprimary-dark主题变量可以引用其他变量以创建语义别名:
css
@theme {
--color-primary-700: #1487b4;
--color-primary-dark: var(--color-primary-700);
}bg-primary-700bg-primary-darkprimary-darkAdding or updating theme variables
添加或更新主题变量
When a design requires a color, font, or other value not yet defined in the
theme, add it to the block in rather than hardcoding the
value in a component.
@themeglobal.cssWhen to add new theme variables:
- A design introduces a new brand color or shade
- You need a semantic alias for an existing value (e.g., )
--color-accent - The design uses a specific spacing, font, or breakpoint value repeatedly
When to update existing theme variables:
- The brand colors change (update the hex values)
- Design tokens need adjustment across the system
Example - adding a new color:
css
@theme {
/* Existing tokens */
--color-primary-600: #1899cb;
/* New token for a success state */
--color-success: #22c55e;
--color-success-dark: #16a34a;
}After adding, you can immediately use , , etc.
bg-successtext-success-darkKeep the theme organized. Group related tokens together with comments
explaining their purpose. Follow the existing naming conventions in
(e.g., numbered shades like through , semantic names
like ).
global.cssprimary-100primary-900primary-dark当设计需要主题中尚未定义的颜色、字体或其他值时,请将其添加到的块中,而非在组件中硬编码值。
global.css@theme何时添加新主题变量:
- 设计引入了新的品牌颜色或色调
- 您需要为现有值创建语义别名(例如)
--color-accent - 设计重复使用特定的间距、字体或断点值
何时更新现有主题变量:
- 品牌颜色变更(更新十六进制值)
- 设计令牌需要在整个系统中调整
示例 - 添加新颜色:
css
@theme {
/* 现有令牌 */
--color-primary-600: #1899cb;
/* 为成功状态添加的新令牌 */
--color-success: #22c55e;
--color-success-dark: #16a34a;
}添加后,您即可立即使用、等工具类。
bg-successtext-success-dark保持主题的条理性。 将相关令牌分组,并添加注释说明其用途。遵循中的现有命名规范(例如,从到的编号色调,等语义名称)。
global.cssprimary-100primary-900primary-darkColor props must use variants, not color codes
颜色属性必须使用变体,而非颜色代码
Never create props that allow users to pass color codes (hex values, RGB,
HSL, or any raw color strings). Instead, define a small set of human-readable
variants using CVA that map to the design tokens in .
global.cssAlways check for available design tokens. The tokens defined
there (such as , , etc.) are the source of truth for color
values.
global.cssprimary-*gray-*Wrong - allowing raw color values:
yaml
undefined切勿创建允许用户传递颜色代码(十六进制值、RGB、HSL或任何原始颜色字符串)的属性。 相反,请使用CVA定义一组少量的易读变体,映射到中的设计令牌。
global.css请务必查看中的可用设计令牌。 其中定义的令牌(如、等)是颜色值的唯一可信来源。
global.cssprimary-*gray-*错误示例 - 允许原始颜色值:
yaml
undefinedWrong
错误
props:
properties:
backgroundColor:
title: Background Color
type: string
examples:
- "#3b82f6"
```jsx
// Wrong
const Card = ({ backgroundColor }) => (
<div style={{ backgroundColor }}>{/* ... */}</div>
);Correct - using CVA variants with design tokens:
yaml
undefinedprops:
properties:
backgroundColor:
title: 背景颜色
type: string
examples:
- "#3b82f6"
```jsx
// 错误
const Card = ({ backgroundColor }) => (
<div style={{ backgroundColor }}>{/* ... */}</div>
);正确示例 - 使用带设计令牌的CVA变体:
yaml
undefinedCorrect
正确
props:
properties:
colorScheme:
title: Color Scheme
type: string
enum:
- default
- primary
- muted
- dark
meta:enum:
default: Default (White)
primary: Primary (Blue)
muted: Muted (Light Gray)
dark: Dark
examples:
- default
```jsx
// Correct
import { cva } from "class-variance-authority";
const cardVariants = cva("rounded-lg p-6", {
variants: {
colorScheme: {
default: "bg-white text-black",
primary: "bg-primary-600 text-white",
muted: "bg-gray-100 text-gray-700",
dark: "bg-gray-900 text-white",
},
},
defaultVariants: {
colorScheme: "default",
},
});
const Card = ({ colorScheme, children }) => (
<div className={cardVariants({ colorScheme })}>{children}</div>
);This approach ensures:
- Consistent colors across the design system
- Users select from curated, meaningful options (not arbitrary values)
- Easy theme updates by modifying tokens
global.css - Better accessibility through tested color combinations
props:
properties:
colorScheme:
title: 配色方案
type: string
enum:
- default
- primary
- muted
- dark
meta:enum:
default: 默认(白色)
primary: 主色(蓝色)
muted: 柔和色(浅灰)
dark: 深色
examples:
- default
```jsx
// 正确
import { cva } from "class-variance-authority";
const cardVariants = cva("rounded-lg p-6", {
variants: {
colorScheme: {
default: "bg-white text-black",
primary: "bg-primary-600 text-white",
muted: "bg-gray-100 text-gray-700",
dark: "bg-gray-900 text-white",
},
},
defaultVariants: {
colorScheme: "default",
},
});
const Card = ({ colorScheme, children }) => (
<div className={cardVariants({ colorScheme })}>{children}</div>
);这种方法确保:
- 设计系统中的颜色保持一致
- 用户从经过筛选的、有意义的选项中选择(而非任意值)
- 通过修改令牌即可轻松更新主题
global.css - 通过经过测试的颜色组合提升可访问性