storefront-theming について
デザイントークンと CSS カスタムプロパティでブランドスタイルを管理する、ストアフロントチーム向けのテーマ設計ガイドです。ダークモードやホワイトラベルのマルチテナント構成に加え、Shopify、WooCommerce、BigCommerce の設定を扱います。
主な機能
- 01階層型トークン体系の構築
- 02CSS カスタムプロパティの利用
- 03ダークモード切り替えの実装
- 04マルチテナントのブランド上書き設定
- 05Shopify、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 | Theme Editor の Color scheme システムを使用し、config/settings_schema.json と assets/base.css を編集してカスタム CSS 変数を追加します | Shopify OS2.0 テーマでは、すべてのブランドカラー、フォント、角丸を Theme Editor の設定として公開し、CSS 変数に自動的に反映します。ビルド手順は不要です |
| WooCommerce | ブロックテーマでは WordPress の Global Styles システム(WordPress 5.9 以降)を使用し、クラシックテーマでは Appearance → Customize → Additional CSS で CSS 変数を設定します | theme.json を使用するブロックテーマは、デザインシステムを標準で全面的にサポートします。クラシックテーマでは CSS カスタムプロパティを手動で追加する必要があります |
| BigCommerce | Storefront → My Themes → Customize でテーマ設定を行います。Cornerstone では、Theme Editor の変数として色、フォント、余白を設定できます。高度なカスタマイズには config.json と SCSS を使用します | Cornerstone は Handlebars テンプレート変数を使って SCSS をコンパイルします。グローバルスタイルシートにカスタム CSS 変数を追加できます |
| カスタム/ヘッドレス | JSON から Style Dictionary を使ってコンパイルする CSS カスタムプロパティで、3 層のトークンシステム(グローバル → セマンティック → コンポーネント)を構築します | トークンの分類、ダークモード、マルチテナントの上書きを完全に制御できます。実装については以下を参照してください |
ステップ 2:プラットフォームでテーマを設定する
Shopify
Theme Editor のカラーシステムを使用する(コード不要):
- 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 カスタムプロパティを生成します
クラシックテーマ — Additional CSS の CSS 変数:
- Appearance → Customize → Additional 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を開きます。ここでは Theme Editor のコントロールが SCSS 変数に対応付けられています:
{
"settings": {
"color-primary": "#2563eb",
"font-size-root": "16px",
"button-radius": "4px"
}
}
- Storefront → My Themes → Customize で、Theme Editor にこれらの設定が反映され、マーチャントが設定できるようになります
Custom / Headless
3 層の 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: Theme Editor がライブのトークンリファレンスとして機能します。デザインチームと Customize URL を共有します
- WooCommerce: CSS 変数名を Storybook インスタンスまたは簡単な HTML リファレンスページに記載します
- BigCommerce: Cornerstone の
config.jsonに利用可能な設定が記載されています。SCSS ファイルにコメントを追加します - Custom: Style Dictionary を使って静的なトークンドキュメントページを生成するか、Storybook に記載します
ベストプラクティス
- コンポーネントの CSS で色をハードコードしないでください — 常にセマンティックトークンを使用します。ブランド変更のたびに
#2563ebを全体検索して置換する必要がある状況は避けられます - セマンティックトークン名には意味を持たせてください —
--color-blue-600ではなく--color-brand-primaryを使います。16 進数の値は変わっても、意味は変わりません - 実際のデバイスでダークモードをテストしてください — macOS/iOS と Windows ではデフォルトのダークモードの動作が異なります。両方でテストしてください
- コントラスト比を検証してください — ブランドカラーを設定したら、WebAIM Contrast Checker を使って WCAG コントラスト比(本文テキストは 4.5:1)を確認します
- ホワイトラベルの CSS 挿入をサニタイズしてください — 16 進数カラー、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