Color Schemes and Design Tokens
Build a flexible color scheme system that allows merchants to create and apply multiple color palettes across sections for dynamic, professional themes.
Modern Shopify themes use color schemes to give merchants flexible control over section colors. Instead of setting colors per-section, merchants define reusable schemes and apply them throughout the store.
What Are Color Schemes?
Color schemes are predefined sets of colors that work together:
- Background and text colors with proper contrast
- Accent colors for buttons and highlights
- Border and shadow colors for depth
Merchants can apply any scheme to any section, creating visual variety while maintaining consistency.
Defining Color Schemes
In settings_schema.json:
{ "name": "Colors", "settings": [ { "type": "header", "content": "Color schemes" }, { "type": "paragraph", "content": "Define up to 5 color schemes that can be applied to any section." }, { "type": "color_scheme_group", "id": "color_schemes", "definition": [ { "type": "color", "id": "background", "label": "Background", "default": "#FFFFFF" }, { "type": "color", "id": "text", "label": "Text", "default": "#1F2937" }, { "type": "color", "id": "text_secondary", "label": "Secondary text", "default": "#6B7280" }, { "type": "color", "id": "button", "label": "Button background", "default": "#3B82F6" }, { "type": "color", "id": "button_text", "label": "Button text", "default": "#FFFFFF" }, { "type": "color", "id": "border", "label": "Border", "default": "#E5E7EB" } ], "role": { "background": { "solid": "background" }, "text": "text", "links": "button", "primary_button": "button", "primary_button_border": "button", "on_primary_button": "button_text", "secondary_button": "background", "secondary_button_border": "button", "on_secondary_button": "button" } } ]}Default Color Schemes
Shopify themes typically include several preset schemes:
{ "type": "color_scheme_group", "id": "color_schemes", "definition": [...], "default": { "scheme_1": { "name": "Light", "settings": { "background": "#FFFFFF", "text": "#1F2937", "text_secondary": "#6B7280", "button": "#1F2937", "button_text": "#FFFFFF", "border": "#E5E7EB" } }, "scheme_2": { "name": "Dark", "settings": { "background": "#1F2937", "text": "#FFFFFF", "text_secondary": "#D1D5DB", "button": "#FFFFFF", "button_text": "#1F2937", "border": "#374151" } }, "scheme_3": { "name": "Accent", "settings": { "background": "#3B82F6", "text": "#FFFFFF", "text_secondary": "#DBEAFE", "button": "#FFFFFF", "button_text": "#3B82F6", "border": "#60A5FA" } }, "scheme_4": { "name": "Soft", "settings": { "background": "#F3F4F6", "text": "#1F2937", "text_secondary": "#6B7280", "button": "#3B82F6", "button_text": "#FFFFFF", "border": "#E5E7EB" } } }}Applying Color Schemes to Sections
Add a scheme selector to any section:
{ "name": "Featured Collection", "settings": [ { "type": "color_scheme", "id": "color_scheme", "label": "Color scheme", "default": "scheme_1" } ]}Generating Color Scheme CSS
Create CSS variables for each scheme:
{# snippets/color-schemes.liquid #}
{%- for scheme in settings.color_schemes -%} {%- assign scheme_classes = scheme.id | prepend: '.color-scheme-' -%}
{{ scheme_classes }} { --color-background: {{ scheme.settings.background }}; --color-text: {{ scheme.settings.text }}; --color-text-secondary: {{ scheme.settings.text_secondary }}; --color-button: {{ scheme.settings.button }}; --color-button-text: {{ scheme.settings.button_text }}; --color-border: {{ scheme.settings.border }};
{# Computed values #} --color-background-rgb: {{ scheme.settings.background | color_to_rgb | remove: 'rgb(' | remove: ')' }}; --color-button-rgb: {{ scheme.settings.button | color_to_rgb | remove: 'rgb(' | remove: ')' }};
background-color: var(--color-background); color: var(--color-text); }{%- endfor -%}Using Color Schemes in Sections
{# sections/featured-collection.liquid #}
{%- assign scheme = section.settings.color_scheme -%}
<section class="featured-collection color-scheme-{{ scheme }}" id="section-{{ section.id }}"> <div class="container"> <h2 class="featured-collection__heading">{{ section.settings.heading }}</h2>
{# Content uses inherited color variables #} <div class="featured-collection__products"> {%- for product in collection.products -%} <div class="product-card"> {# Card inherits scheme colors #} </div> {%- endfor -%} </div>
<a href="{{ collection.url }}" class="button"> View All </a> </div></section>CSS That Uses Scheme Variables
/* Base component styles using scheme variables */.button { background-color: var(--color-button); color: var(--color-button-text); border: none; padding: var(--spacing-sm) var(--spacing-lg); border-radius: var(--button-radius);}
.button--secondary { background-color: transparent; color: var(--color-button); border: 1px solid var(--color-button);}
.product-card { background: var(--color-background); border: 1px solid var(--color-border);}
.product-card__title { color: var(--color-text);}
.product-card__price { color: var(--color-text-secondary);}
/* Links inherit from scheme */a { color: var(--color-button);}
/* Form elements */input, select, textarea { background: var(--color-background); color: var(--color-text); border: 1px solid var(--color-border);}Design Tokens Beyond Colors
Extend the token system for other design properties:
Spacing Tokens
{ "name": "Spacing", "settings": [ { "type": "select", "id": "spacing_scale", "label": "Spacing scale", "options": [ { "value": "compact", "label": "Compact" }, { "value": "normal", "label": "Normal" }, { "value": "relaxed", "label": "Relaxed" } ], "default": "normal" } ]}{%- case settings.spacing_scale -%} {%- when 'compact' -%} :root { --spacing-xs: 2px; --spacing-sm: 4px; --spacing-md: 8px; --spacing-lg: 16px; --spacing-xl: 24px; --spacing-2xl: 32px; } {%- when 'normal' -%} :root { --spacing-xs: 4px; --spacing-sm: 8px; --spacing-md: 16px; --spacing-lg: 24px; --spacing-xl: 32px; --spacing-2xl: 48px; } {%- when 'relaxed' -%} :root { --spacing-xs: 6px; --spacing-sm: 12px; --spacing-md: 24px; --spacing-lg: 36px; --spacing-xl: 48px; --spacing-2xl: 64px; }{%- endcase -%}Shadow Tokens
{ "name": "Shadows", "settings": [ { "type": "select", "id": "shadow_style", "label": "Shadow style", "options": [ { "value": "none", "label": "None" }, { "value": "subtle", "label": "Subtle" }, { "value": "medium", "label": "Medium" }, { "value": "strong", "label": "Strong" } ], "default": "subtle" } ]}{%- case settings.shadow_style -%} {%- when 'none' -%} :root { --shadow-sm: none; --shadow-md: none; --shadow-lg: none; } {%- when 'subtle' -%} :root { --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05); --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.05); --shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.05); } {%- when 'medium' -%} :root { --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.1); --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1); --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.1); } {%- when 'strong' -%} :root { --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.15); --shadow-md: 0 6px 10px rgba(0, 0, 0, 0.15); --shadow-lg: 0 15px 25px rgba(0, 0, 0, 0.15); }{%- endcase -%}Gradient Color Scheme
Add gradient support:
{ "type": "color_background", "id": "background", "label": "Background"}The color_background type allows solid colors or gradients:
{%- if scheme.settings.background.gradient != blank -%} background: {{ scheme.settings.background.gradient }};{%- else -%} background-color: {{ scheme.settings.background }};{%- endif -%}Contrast Checking
Ensure text is readable on any background:
{# Check if background is dark or light #}{%- assign bg_brightness = scheme.settings.background | color_brightness -%}
{%- if bg_brightness < 128 -%} {# Dark background, use light text #} --color-text: #FFFFFF; --color-text-secondary: #D1D5DB;{%- else -%} {# Light background, use dark text #} --color-text: #1F2937; --color-text-secondary: #6B7280;{%- endif -%}Scheme Inheritance
Sections can use the default scheme or override:
{# Get scheme, falling back to default #}{%- if section.settings.color_scheme != blank -%} {%- assign scheme = section.settings.color_scheme -%}{%- else -%} {%- assign scheme = 'scheme_1' -%}{%- endif -%}
<section class="color-scheme-{{ scheme }}">Dark Mode Support
Create a dark mode toggle:
{ "type": "checkbox", "id": "enable_dark_mode", "label": "Enable dark mode toggle", "default": false},{ "type": "color_scheme", "id": "dark_mode_scheme", "label": "Dark mode scheme", "default": "scheme_2"}{%- if settings.enable_dark_mode -%} @media (prefers-color-scheme: dark) { :root { {%- assign dark = settings.color_schemes[settings.dark_mode_scheme].settings -%} --color-background: {{ dark.background }}; --color-text: {{ dark.text }}; --color-button: {{ dark.button }}; {# ... other properties #} } }{%- endif -%}Complete Color Scheme Snippet
{# snippets/color-scheme-styles.liquid #}
<style> {# Generate scheme classes #} {%- for scheme in settings.color_schemes -%} .color-scheme-{{ scheme.id }} { --color-background: {{ scheme.settings.background }}; --color-text: {{ scheme.settings.text }}; --color-text-secondary: {{ scheme.settings.text_secondary }}; --color-button: {{ scheme.settings.button }}; --color-button-text: {{ scheme.settings.button_text }}; --color-border: {{ scheme.settings.border }};
background-color: var(--color-background); color: var(--color-text); } {%- endfor -%}
{# Default scheme for body #} body { {%- assign default_scheme = settings.color_schemes['scheme_1'].settings -%} --color-background: {{ default_scheme.background }}; --color-text: {{ default_scheme.text }}; --color-text-secondary: {{ default_scheme.text_secondary }}; --color-button: {{ default_scheme.button }}; --color-button-text: {{ default_scheme.button_text }}; --color-border: {{ default_scheme.border }};
background-color: var(--color-background); color: var(--color-text); }</style>Practice Exercise
Create a color scheme system with:
- At least 4 preset schemes (light, dark, accent, soft)
- Scheme selector in 3 different sections
- CSS variables that cascade properly
- Buttons that adapt to any scheme
Test by:
- Applying different schemes to adjacent sections
- Verifying contrast is maintained
- Checking buttons, links, and text colors
Key Takeaways
color_scheme_groupdefines reusable palettes- CSS custom properties apply scheme colors
- Scheme selector in section settings
- Class-based application (
color-scheme-{{ id }}) - Contrast checking with
color_brightness - Design tokens extend beyond colors
- Inheritance for consistent defaults
🛠Build Color Scheme Selectors: Our Schema Builder supports color_scheme and color_scheme_group settings, making it easy to add scheme selectors to your section schemas.
What’s Next?
The next lesson covers Metafields and Dynamic Sources for custom content beyond standard fields.
Finished this lesson?
Mark it complete to track your progress.
Discussion
Loading comments...