Global Theme Settings: Colors, Typography, Spacing
Create a robust settings system for your Shopify theme with global controls for colors, typography, and spacing that cascade throughout the entire theme.
Global theme settings let merchants customize their store’s visual identity without touching code. A well-designed settings system creates a cohesive design while offering meaningful flexibility.
Settings Schema Location
Global settings live in config/settings_schema.json:
[ { "name": "theme_info", "theme_name": "My Theme", "theme_version": "1.0.0", "theme_author": "Your Name", "theme_documentation_url": "https://docs.example.com", "theme_support_url": "https://support.example.com" }, { "name": "Colors", "settings": [ { "type": "color", "id": "color_primary", "label": "Primary color", "default": "#3B82F6" } ] }]Accessing Global Settings
Use settings object anywhere in your theme:
{{ settings.color_primary }}{{ settings.type_base_font }}{{ settings.spacing_grid }}Color Settings
Basic Color Palette
{ "name": "Colors", "settings": [ { "type": "header", "content": "Primary colors" }, { "type": "color", "id": "color_primary", "label": "Primary", "default": "#3B82F6", "info": "Used for buttons, links, and accents" }, { "type": "color", "id": "color_secondary", "label": "Secondary", "default": "#10B981" }, { "type": "header", "content": "Text colors" }, { "type": "color", "id": "color_text", "label": "Text", "default": "#1F2937" }, { "type": "color", "id": "color_text_light", "label": "Secondary text", "default": "#6B7280" }, { "type": "header", "content": "Background colors" }, { "type": "color", "id": "color_background", "label": "Page background", "default": "#FFFFFF" }, { "type": "color", "id": "color_background_secondary", "label": "Secondary background", "default": "#F3F4F6", "info": "Used for cards, callouts, and alternate sections" }, { "type": "header", "content": "UI colors" }, { "type": "color", "id": "color_border", "label": "Borders", "default": "#E5E7EB" }, { "type": "color", "id": "color_success", "label": "Success", "default": "#10B981" }, { "type": "color", "id": "color_error", "label": "Error", "default": "#EF4444" } ]}Applying Colors via CSS Variables
In your main layout or CSS file:
{# snippets/css-variables.liquid #}
{%- style -%}:root { --color-primary: {{ settings.color_primary }}; --color-primary-rgb: {{ settings.color_primary | color_to_rgb | remove: 'rgb(' | remove: ')' }}; --color-secondary: {{ settings.color_secondary }};
--color-text: {{ settings.color_text }}; --color-text-light: {{ settings.color_text_light }};
--color-background: {{ settings.color_background }}; --color-background-secondary: {{ settings.color_background_secondary }};
--color-border: {{ settings.color_border }}; --color-success: {{ settings.color_success }}; --color-error: {{ settings.color_error }};
{# Derived colors with transparency #} --color-primary-10: {{ settings.color_primary | color_modify: 'alpha', 0.1 }}; --color-primary-20: {{ settings.color_primary | color_modify: 'alpha', 0.2 }};}{%- endstyle -%}Typography Settings
Font Selection
{ "name": "Typography", "settings": [ { "type": "header", "content": "Headings" }, { "type": "font_picker", "id": "type_heading_font", "label": "Font", "default": "assistant_n4" }, { "type": "select", "id": "type_heading_weight", "label": "Weight", "options": [ { "value": "400", "label": "Regular" }, { "value": "500", "label": "Medium" }, { "value": "600", "label": "Semibold" }, { "value": "700", "label": "Bold" } ], "default": "700" }, { "type": "select", "id": "type_heading_transform", "label": "Letter case", "options": [ { "value": "none", "label": "Normal" }, { "value": "uppercase", "label": "Uppercase" }, { "value": "capitalize", "label": "Capitalize" } ], "default": "none" }, { "type": "header", "content": "Body text" }, { "type": "font_picker", "id": "type_body_font", "label": "Font", "default": "assistant_n4" }, { "type": "range", "id": "type_body_size", "label": "Base size", "min": 14, "max": 20, "step": 1, "default": 16, "unit": "px" }, { "type": "range", "id": "type_body_line_height", "label": "Line height", "min": 1.2, "max": 2, "step": 0.1, "default": 1.6 } ]}Applying Typography
{# Font face declarations #}{%- style -%}{{ settings.type_heading_font | font_face: font_display: 'swap' }}{{ settings.type_body_font | font_face: font_display: 'swap' }}
:root { --font-heading: {{ settings.type_heading_font.family }}, {{ settings.type_heading_font.fallback_families }}; --font-heading-weight: {{ settings.type_heading_weight }}; --font-heading-style: {{ settings.type_heading_font.style }}; --font-heading-transform: {{ settings.type_heading_transform }};
--font-body: {{ settings.type_body_font.family }}, {{ settings.type_body_font.fallback_families }}; --font-body-weight: {{ settings.type_body_font.weight }}; --font-body-style: {{ settings.type_body_font.style }};
--font-size-base: {{ settings.type_body_size }}px; --line-height-base: {{ settings.type_body_line_height }};}{%- endstyle -%}Using Typography Variables
body { font-family: var(--font-body); font-weight: var(--font-body-weight); font-style: var(--font-body-style); font-size: var(--font-size-base); line-height: var(--line-height-base);}
h1,h2,h3,h4,h5,h6 { font-family: var(--font-heading); font-weight: var(--font-heading-weight); font-style: var(--font-heading-style); text-transform: var(--font-heading-transform);}Spacing Settings
Spacing Scale
{ "name": "Layout", "settings": [ { "type": "header", "content": "Spacing" }, { "type": "range", "id": "spacing_base", "label": "Base spacing unit", "min": 4, "max": 8, "step": 1, "default": 4, "unit": "px", "info": "All spacing is calculated from this value" }, { "type": "range", "id": "spacing_section", "label": "Section spacing", "min": 20, "max": 100, "step": 10, "default": 60, "unit": "px" }, { "type": "header", "content": "Container" }, { "type": "range", "id": "container_width", "label": "Maximum width", "min": 1000, "max": 1600, "step": 40, "default": 1200, "unit": "px" }, { "type": "range", "id": "container_padding", "label": "Horizontal padding", "min": 16, "max": 48, "step": 4, "default": 24, "unit": "px" } ]}Spacing Variables
{%- style -%}:root { {# Base unit #} --spacing-unit: {{ settings.spacing_base }}px;
{# Spacing scale (multiples of base) #} --spacing-xs: calc(var(--spacing-unit) * 1); {# 4px #} --spacing-sm: calc(var(--spacing-unit) * 2); {# 8px #} --spacing-md: calc(var(--spacing-unit) * 4); {# 16px #} --spacing-lg: calc(var(--spacing-unit) * 6); {# 24px #} --spacing-xl: calc(var(--spacing-unit) * 8); {# 32px #} --spacing-2xl: calc(var(--spacing-unit) * 12); {# 48px #} --spacing-3xl: calc(var(--spacing-unit) * 16); {# 64px #}
--spacing-section: {{ settings.spacing_section }}px;
--container-width: {{ settings.container_width }}px; --container-padding: {{ settings.container_padding }}px;}{%- endstyle -%}Border and Radius Settings
{ "name": "Borders", "settings": [ { "type": "range", "id": "border_radius", "label": "Corner radius", "min": 0, "max": 24, "step": 2, "default": 8, "unit": "px" }, { "type": "select", "id": "border_width", "label": "Border width", "options": [ { "value": "1", "label": "Thin" }, { "value": "2", "label": "Medium" }, { "value": "3", "label": "Thick" } ], "default": "1" }, { "type": "select", "id": "button_style", "label": "Button corners", "options": [ { "value": "square", "label": "Square" }, { "value": "rounded", "label": "Rounded" }, { "value": "pill", "label": "Pill" } ], "default": "rounded" } ]}Border Variables
{%- style -%}:root { --border-radius-sm: calc({{ settings.border_radius }}px * 0.5); --border-radius: {{ settings.border_radius }}px; --border-radius-lg: calc({{ settings.border_radius }}px * 2); --border-width: {{ settings.border_width }}px;
{%- case settings.button_style -%} {%- when 'square' -%} --button-radius: 0; {%- when 'rounded' -%} --button-radius: var(--border-radius); {%- when 'pill' -%} --button-radius: 9999px; {%- endcase -%}}{%- endstyle -%}Animation Settings
{ "name": "Animations", "settings": [ { "type": "checkbox", "id": "enable_animations", "label": "Enable animations", "default": true, "info": "Respects user's reduced motion preference" }, { "type": "select", "id": "animation_speed", "label": "Animation speed", "options": [ { "value": "fast", "label": "Fast" }, { "value": "normal", "label": "Normal" }, { "value": "slow", "label": "Slow" } ], "default": "normal" } ]}Animation Variables
{%- style -%}:root { {%- case settings.animation_speed -%} {%- when 'fast' -%} --duration-short: 100ms; --duration-medium: 200ms; --duration-long: 300ms; {%- when 'normal' -%} --duration-short: 150ms; --duration-medium: 300ms; --duration-long: 500ms; {%- when 'slow' -%} --duration-short: 200ms; --duration-medium: 400ms; --duration-long: 700ms; {%- endcase -%}
--ease-default: cubic-bezier(0.4, 0, 0.2, 1); --ease-in: cubic-bezier(0.4, 0, 1, 1); --ease-out: cubic-bezier(0, 0, 0.2, 1);}
{%- unless settings.enable_animations -%}@media (prefers-reduced-motion: no-preference) { :root { --duration-short: 0ms; --duration-medium: 0ms; --duration-long: 0ms; }}{%- endunless -%}
@media (prefers-reduced-motion: reduce) { :root { --duration-short: 0ms; --duration-medium: 0ms; --duration-long: 0ms; }}{%- endstyle -%}Complete CSS Variables Snippet
Organize all variables in one place:
{# snippets/css-variables.liquid #}
{%- style -%}{# Font faces #}{{ settings.type_heading_font | font_face: font_display: 'swap' }}{{ settings.type_body_font | font_face: font_display: 'swap' }}
:root { {# Colors #} --color-primary: {{ settings.color_primary }}; --color-primary-rgb: {{ settings.color_primary | color_to_rgb | remove: 'rgb(' | remove: ')' }}; --color-secondary: {{ settings.color_secondary }}; --color-text: {{ settings.color_text }}; --color-text-light: {{ settings.color_text_light }}; --color-background: {{ settings.color_background }}; --color-background-secondary: {{ settings.color_background_secondary }}; --color-border: {{ settings.color_border }}; --color-success: {{ settings.color_success }}; --color-error: {{ settings.color_error }};
{# Typography #} --font-heading: {{ settings.type_heading_font.family }}, {{ settings.type_heading_font.fallback_families }}; --font-heading-weight: {{ settings.type_heading_weight }}; --font-body: {{ settings.type_body_font.family }}, {{ settings.type_body_font.fallback_families }}; --font-size-base: {{ settings.type_body_size }}px; --line-height-base: {{ settings.type_body_line_height }};
{# Spacing #} --spacing-unit: {{ settings.spacing_base }}px; --spacing-xs: calc(var(--spacing-unit) * 1); --spacing-sm: calc(var(--spacing-unit) * 2); --spacing-md: calc(var(--spacing-unit) * 4); --spacing-lg: calc(var(--spacing-unit) * 6); --spacing-xl: calc(var(--spacing-unit) * 8); --spacing-2xl: calc(var(--spacing-unit) * 12); --spacing-section: {{ settings.spacing_section }}px;
{# Layout #} --container-width: {{ settings.container_width }}px; --container-padding: {{ settings.container_padding }}px;
{# Borders #} --border-radius: {{ settings.border_radius }}px; --border-width: {{ settings.border_width }}px;}{%- endstyle -%}Include in layout:
{# layout/theme.liquid #}<head> {# ... #} {% render 'css-variables' %}</head>Practice Exercise
Create a complete settings schema for:
- Brand colors (primary, secondary, accent)
- Typography (heading and body fonts)
- Layout spacing and container width
- Border radius and button style
Test by:
- Changing colors in theme editor
- Verifying CSS variables update
- Checking all components use variables
Key Takeaways
settings_schema.jsondefines global settings- CSS custom properties cascade settings throughout theme
- Color filters like
color_to_rgbfor advanced use - Font picker with
font_facefilter for loading - Range inputs for numerical settings with units
- Spacing scale based on multipliers
- Reduced motion respect for accessibility
🛠Building Section Schemas? While this lesson covers global theme settings, our Schema Builder helps you create section-level schemas with visual editing and live JSON preview.
What’s Next?
The next lesson covers Color Schemes and Design Tokens for more advanced theming systems.
Finished this lesson?
Mark it complete to track your progress.
Discussion
Loading comments...