关于 storefront-theming
面向店面开发团队的主题架构技能指南,介绍用设计令牌和 CSS 自定义属性管理品牌样式。内容涵盖深色模式、白标多租户主题及 Shopify、WooCommerce 和 BigCommerce 的配置方式。
主要功能
- 01设计分层令牌体系
- 02使用 CSS 自定义属性
- 03实现深色模式切换
- 04配置多租户品牌覆盖
- 05管理 Shopify、WooCommerce 和 BigCommerce 主题
适用场景
- 01用单一代码库支持多个品牌店面
- 02为店面实现深色模式
- 03集中调整全站品牌样式
- 04向团队交接可维护的设计系统
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ finsilabs/ awesome-ecommerce-skills --skill storefront-theming安装后在 Claude Code 中输入/storefront-theming确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
tile.jsonevals/dark-mode-implementation/criteria.jsontask.mdevals/multi-tenant-theme-injection/criteria.jsontask.mdevals/token-taxonomy-and-build-pipeline/criteria.jsontask.md详细介绍
店面主题定制
概述
使用设计令牌和 CSS 自定义属性构建主题系统,让店面无需修改组件代码即可换用多个品牌的外观。涵盖令牌分类(颜色、排版、间距、圆角)、深色模式的运行时主题切换,以及由各租户提供自定义令牌覆盖项的白标多租户架构。
何时使用此技能
- 构建一个基于单一代码库、支持多个品牌店面的平台时
- 为店面实现深色模式时
- 品牌重塑需要在数千个组件实例中更改颜色,而不必逐一查找和替换时
- 将设计系统交接给需要维护品牌一致性的团队时
核心说明
步骤 1:确定商家的平台并选择合适的方案
| 平台 | 推荐方案 | 原因 |
|---|---|---|
| Shopify | 使用主题编辑器的 Color scheme 系统,并编辑 config/settings_schema.json 和 assets/base.css 来添加自定义 CSS 变量 | Shopify OS2.0 主题会将所有品牌颜色、字体和边框圆角作为主题编辑器设置公开,并自动写入 CSS 变量;无需构建步骤 |
| WooCommerce | 使用 WordPress Global Styles 系统(WordPress 5.9+)搭配区块主题,或为经典主题在 外观 → 自定义 → 额外 CSS 中配置 CSS 变量 | 使用 theme.json 的区块主题原生支持完整的设计令牌系统;经典主题则需要手动添加 CSS 自定义属性 |
| BigCommerce | 在 Storefront → My Themes → Customize 中配置主题设置——Cornerstone 会将颜色、字体和间距作为主题编辑器变量公开;高级自定义可通过 config.json 和 SCSS 实现 | Cornerstone 使用 Handlebars 模板变量编译 SCSS;可以将自定义 CSS 变量添加到全局样式表 |
| 自定义 / 无头架构 | 使用 CSS 自定义属性构建三级令牌系统(全局 → 语义 → 组件),并通过 Style Dictionary 从 JSON 编译 | 可全面控制令牌分类、深色模式和多租户覆盖项;请参阅下方实现 |
步骤 2:在平台上配置主题
Shopify
使用主题编辑器的颜色系统(无需编写代码):
- 前往 Online Store → Themes → Customize
- 点击左侧面板中的 Theme settings(油漆桶图标)
- 在 Colors 下配置品牌的:
- 主色、次色和强调色
- 背景颜色
- 文本颜色
- 按钮颜色和文本
- 在 Typography 下设置字体系列和字号
- 在 Buttons and inputs 下配置按钮和表单字段的边框圆角
- 所有更改都会写入主题中每个组件都会使用的 CSS 自定义属性——无需更改组件
添加自定义 CSS 变量(供扩展主题的开发者使用):
- 前往 Online Store → Themes → Edit code
- 打开
assets/base.css(Dawn)或等效文件 - 在
:root块中添加自定义变量,并引用主题的设置变量:
:root {
--color-button: {{ settings.color_button.red }}, {{ settings.color_button.green }}, {{ settings.color_button.blue }};
--font-body-family: {{ settings.type_body_font.family }}, sans-serif;
}
- 在版块/组件 Liquid 文件中,使用
var(--color-button)来引用由商家控制的设置
WooCommerce
使用 theme.json 的区块主题(WordPress 5.9+):
如果你正在使用区块主题(例如 Storefront Blocks 或自定义区块主题)构建新店面:
- 打开主题根目录中的
theme.json - 将设计令牌添加到
settings.color.palette和settings.typography部分:
{
"settings": {
"color": {
"palette": [
{ "slug": "brand-primary", "color": "#2563eb", "name": "Brand Primary" },
{ "slug": "brand-secondary", "color": "#3b82f6", "name": "Brand Secondary" }
]
},
"custom": {
"spacing": { "xs": "0.5rem", "sm": "1rem", "md": "1.5rem" }
}
}
}
- WordPress 会自动在 Global Styles 面板中公开这些设置,并生成类似
--wp--preset--color--brand-primary的 CSS 自定义属性
经典主题——在额外 CSS 中使用 CSS 变量:
- 前往 外观 → 自定义 → 额外 CSS
- 定义品牌变量:
:root {
--color-primary: #2563eb;
--color-price-sale: #dc2626;
--font-size-base: 1rem;
--border-radius-button: 0.375rem;
}
- 在子主题的 CSS 中使用这些变量,而不要使用硬编码值
BigCommerce
Cornerstone 主题变量(基于 SCSS):
- 前往 Storefront → My Themes → Edit Theme Files(需要复制一份主题)
- 打开
assets/scss/settings/global/— Cornerstone 按类别(颜色、排版、间距)组织变量 - 修改
_color.scss以更新品牌配色 - 打开主题根目录中的
config.json— 该文件将主题编辑器控件映射到 SCSS 变量:
{
"settings": {
"color-primary": "#2563eb",
"font-size-root": "16px",
"button-radius": "4px"
}
}
- 在 Storefront → My Themes → Customize 中,主题编辑器会显示这些设置,供商家配置
自定义 / 无头架构
三级 CSS 自定义属性系统:
/* 1. Global tokens — the complete palette (never used directly in components) */
:root {
--blue-600: #2563eb;
--blue-500: #3b82f6;
--red-500: #ef4444;
--green-600: #16a34a;
--gray-50: #f8fafc;
--gray-900: #0f172a;
--space-4: 1rem;
--space-6: 1.5rem;
--radius-md: 0.375rem;
}
/* 2. Semantic tokens — meaningful aliases (components consume these) */
:root {
--color-brand-primary: var(--blue-600);
--color-brand-secondary: var(--blue-500);
--color-surface: var(--gray-50);
--color-on-surface: var(--gray-900);
--color-price: var(--gray-900);
--color-price-sale: var(--red-500);
--color-success: var(--green-600);
}
/* 3. Dark mode overrides */
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--color-surface: var(--gray-900);
--color-on-surface: var(--gray-50);
}
}
[data-theme="dark"] {
--color-surface: var(--gray-900);
--color-on-surface: var(--gray-50);
}
/* Components only use semantic tokens */
.btn-primary {
background: var(--color-brand-primary);
border-radius: var(--radius-md);
min-height: 44px;
}
.price--sale { color: var(--color-price-sale); }
深色模式切换(在 localStorage 中保存偏好设置):
export function ThemeToggle() {
const [theme, setTheme] = useState(() => localStorage.getItem('theme') ?? 'system');
function applyTheme(newTheme) {
setTheme(newTheme);
localStorage.setItem('theme', newTheme);
if (newTheme === 'system') document.documentElement.removeAttribute('data-theme');
else document.documentElement.setAttribute('data-theme', newTheme);
}
return (
<button onClick={() => applyTheme(theme === 'dark' ? 'light' : 'dark')}
aria-label={`Switch to ${theme === 'dark' ? 'light' : 'dark'} mode`}>
{theme === 'dark' ? 'Light mode' : 'Dark mode'}
</button>
);
}
防止深色模式闪烁(在渲染前应用):
<script>
(function() {
var theme = localStorage.getItem('theme');
if (theme === 'dark' || (!theme && matchMedia('(prefers-color-scheme: dark)').matches))
document.documentElement.setAttribute('data-theme', 'dark');
})();
</script>
多租户白标(在服务端注入各租户的覆盖值):
// In your server response, inject tenant CSS overrides in <head>
// so they're applied before the page renders (no flash)
const tenantTheme = await getTenantTheme(req.hostname);
const cssOverrides = tenantTheme
? `:root { ${Object.entries(tenantTheme)
.map(([k, v]) => `--${k}: ${sanitizeCssValue(v)};`)
.join(' ')} }`
: '';
// Sanitize to allow only safe CSS value patterns
function sanitizeCssValue(value) {
if (/^#[0-9a-fA-F]{3,8}$/.test(value)) return value; // hex color
if (/^\d+(\.\d+)?(px|rem|em|%)$/.test(value)) return value; // length
if (/^[a-zA-Z0-9\s,'"]+$/.test(value)) return value; // font names
return ''; // reject everything else (prevents CSS injection)
}
步骤 3:为团队构建令牌参考文档
无论使用哪种平台,都要记录令牌,确保设计师和开发者保持同步:
- Shopify: 主题编辑器可作为实时令牌参考 — 将 Customize URL 分享给设计团队
- WooCommerce: 在 Storybook 实例或简单的 HTML 参考页面中记录 CSS 变量名称
- BigCommerce: Cornerstone 的
config.json会记录可用设置;在 SCSS 文件中添加注释 - 自定义: 使用 Style Dictionary 生成静态令牌文档页面,或在 Storybook 中记录
最佳实践
- 切勿在组件 CSS 中硬编码颜色 — 始终使用语义化令牌;避免因品牌重塑而需要全局查找并替换
#2563eb - 语义化令牌名称应体现含义 — 使用
--color-brand-primary,而非--color-blue-600;十六进制值会改变,但含义不变 - 使用真实设备测试深色模式 — macOS/iOS 和 Windows 的默认深色模式行为不同;两者都要测试
- 验证对比度 — 设置品牌颜色后,使用 WebAIM Contrast Checker 验证 WCAG 对比度(正文文本为 4.5:1)
- 清理白标 CSS 注入内容 — 只允许十六进制颜色、rem/px 长度值和字体名称;拒绝任意字符串,以防止 CSS 注入攻击
常见问题
| 问题 | 解决方案 |
|---|---|
| 深色模式导致无样式内容闪烁 | 在样式表加载前,于 <head> 脚本中同步应用 data-theme 属性 |
| 首次渲染时未应用租户主题覆盖 | 在服务端将租户 CSS 注入内联 <style> 标签;不要在 useEffect 中应用 |
| Figma 与代码中的设计令牌不同步 | 使用 Figma 插件 Tokens Studio,直接导出到 CSS 变量 / theme.json 文件 |
| 白标 CSS 导致 XSS | 清理租户令牌值,仅允许有效的 CSS 颜色、长度和 font-family 格式 |
| 品牌重塑需要修改许多文件 | 如果你发现自己要替换多个组件文件中的颜色,说明你跳过了语义化令牌层 — 请先重构为语义化令牌 |
相关技能
- @responsive-storefront
- @accessibility-commerce
- @mega-menu-builder
- @product-page-design
评论
支持 Markdown