liquid-theme-standards
CSS, JavaScript, and HTML coding standards for Shopify Liquid themes. Covers BEM naming inside stylesheet tags, design tokens, CSS custom properties, Web Components for themes, defensive CSS, and progressive enhancement. Use when writing CSS/JS/HTML in .liquid files or theme asset files.
By benjaminsehl · 2,628 installs
npx skills add benjaminsehl/liquid-skills --skill liquid-theme-standards
Source repository · Upstream listing
CSS, JS & HTML Standards for Shopify Liquid Themes
Core Principles
1. Progressive enhancement — semantic HTML first, CSS second, JS third
2. No external dependencies — native browser APIs only for JavaScript
3. Design tokens — never hardcode colors, spacing, or fonts
4. BEM naming — consistent class naming throughout
5. Defensive CSS — handle edge cases gracefully
CSS in Liquid Themes
Where CSS Lives
Location Liquid? Use For
{% stylesheet %} No Component scoped styles (one per file)
{% style %} Yes Dynamic values needing Liquid (e.g., color settings)
assets/ .css No Shared/global styles
Critical: {% stylesheet %} does NOT process Liquid. Use inline style attributes for dynamic values:
BEM Naming Convention
Rules:
Hyphens separate words: .product card , not .productCard
Single element level only: .block element , never .block el1 el2
Modifier always paired with base class: class="btn btn primary" , never class="btn primary" alone
Start new BEM scope when a child could be standalone
Specificity
Target 0 1 0 (single class) wherever possible
Maximum 0 4 0 for complex parent child cases
Never use IDs as selectors
Never use !important (comment why if absolutely forced to)
Avoid element selectors — use classes
CSS Nesting
Design Tokens
Use CSS custom properties for all values — never hardcode colors, spacing, or fonts. Define a consistent scale and reference it everywhere.
Example scale (adapt to your theme's needs):
Key principles:
Use rem for spacing and typography (respects user font size preferences)
Name tokens semantically: space sm not space 16
Define in :root for global tokens, on component root for scoped tokens
CSS Variable Scoping
Global — in :root for theme wide values
Component scoped — on component root, namespaced:
Override via inline style for section/block settings:
CSS Property Order
1. Layout — position , display , flex direction , grid template columns
2. Box model — width , margin , padding , border
3. Typography — font family , font size , line height , color
4. Visual — background , opacity , border radius
5. Animation — transition , animation
Logical Properties (RTL Support)
Defensive CSS
Modern CSS Features
Performance
Animate only transform and opacity (never layout properties)
Use will change sparingly — remove after animation
Use contain: content for isolated rendering
Use dvh instead of vh on mobile
Reduced Motion
JavaScript in Liquid Themes
Where JS Lives
Location Liquid? Use For
{% javascript %} No Component specific scripts (one per file)
assets/ .js No Shared utilities, Web Components
Web Component Pattern
JavaScript Rules
Rule Do Don't
Loops for (const item of items) items.forEach()
Async async / await .then() chains
Variables const by default let unless reassigning
Conditionals Early returns Nested if/else
URLs new URL() + URLSearchParams String concatenation
Dependencies Native browser APIs External libraries
Private methods methodName() methodName()
Types JSDoc @typedef , @param , @returns Untyped
AbortController for Fetch
Component Communication
Parent → Child: Call public methods
Child → Parent: Dispatch custom events
HTML Standards
Native Elements First
Need Use Not
Expandable <details /<summary Custom accordion with JS
Dialog/modal <dialog Custom overlay div
Tooltip/popup popover attribute Custom positioned div
Search form <search <div class="search"
Form results <output <span class="result"
Progressive Enhancement
Images
loading="lazy" on all below fold images
Always set width and height to prevent layout shift
Descriptive alt text; empty alt="" for decorative images
JSON Template & Config Files
Theme templates ( templates/ .json ), section groups ( sections/ .json ), and config files ( config/settings data.json ) are all JSON. Use jq via the bash tool to make surgical edits — it's safer and more reliable than string based find and replace for structured data.
Common patterns
Prefer jq over edit for any .json file modification — it validates structure, handles escaping, and avoids whitespace/formatting issues.
References
[CSS patterns and examples](references/css patterns.md)
[JavaScript patterns and examples](references/javascript patterns.md)