CSS, JS & HTML Standards for Shopify Liquid Themes
Core Principles
- Progressive enhancement — semantic HTML first, CSS second, JS third
- No external dependencies — native browser APIs only for JavaScript
- Design tokens — never hardcode colors, spacing, or fonts
- BEM naming — consistent class naming throughout
- Defensive CSS — handle edge cases gracefully
CSS in Liquid Themes
Where CSS Lives
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", neverclass="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 0for 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
remfor spacing and typography (respects user font size preferences) - Name tokens semantically:
--space-smnot--space-16 - Define in
:rootfor 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
- Layout —
position,display,flex-direction,grid-template-columns - Box model —
width,margin,padding,border - Typography —
font-family,font-size,line-height,color - Visual —
background,opacity,border-radius - Animation —
transition,animation
Logical Properties (RTL Support)
Defensive CSS
Modern CSS Features
Performance
- Animate only
transformandopacity(never layout properties) - Use
will-changesparingly — remove after animation - Use
contain: contentfor isolated rendering - Use
dvhinstead ofvhon mobile
Reduced Motion
JavaScript in Liquid Themes
Where JS Lives
Web Component Pattern
JavaScript Rules
AbortController for Fetch
Component Communication
Parent → Child: Call public methods
Child → Parent: Dispatch custom events
HTML Standards
Native Elements First
Progressive Enhancement
Images
loading="lazy"on all below-fold images- Always set
widthandheightto prevent layout shift - Descriptive
alttext; emptyalt=""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 [blocked]
- JavaScript patterns and examples [blocked]


