Design system¶
A design system is a set of reusable decisions — colors, spacing, typography, component patterns — that keep your site consistent. CSS gives you the tools to build one, and the Style panel lets you apply it visually.
Two things to remember:
- Classes are your building blocks. A well-named class can be reused across any element, any page.
- CSS variables are your source of truth. Change a variable once, and every element using it updates.
Starting with CSS variables¶
Before styling anything, define your core values. Open the CSS Variables panel in the left sidebar and create variables for:
Colors:
- --color-primary — your brand color
- --color-secondary — accent color
- --color-text — default text color
- --color-background — page background
- --color-surface — card/section backgrounds
- --color-border — subtle borders
Spacing:
- --space-xs — 4px
- --space-sm — 8px
- --space-md — 16px
- --space-lg — 32px
- --space-xl — 64px
Typography:
- --font-heading — heading font family
- --font-body — body text font family
- --font-size-base — base text size (e.g., 16px)
- --font-size-lg — large text
- --font-size-sm — small text
Now every style you write references these variables instead of hard-coded values. Need to tweak the brand color? Change --color-primary once. See CSS variables for the full guide.
Naming classes with BEM¶
BEM (Block, Element, Modifier) gives you a predictable naming convention:
- Block — a standalone component:
.card,.nav,.hero - Element — a part of a block:
.card__title,.card__image,.card__body - Modifier — a variation:
.card--featured,.card--compact
In the Style panel, type your class name in the selector field. BEM names are long but self-documenting — .card__title--large tells you exactly what it styles and where.
Why BEM?
- No naming collisions — .card__title won't accidentally style a title somewhere else
- Easy to find — search for .card and you find everything related to cards
- Works with Symbols — a Symbol with BEM classes stays consistent across instances
Building reusable component classes¶
A design system is not just variables — it's patterns. Here's how to build a reusable card component:
- Add a Div to the canvas — this is the card block
- Inside it: an Image (
.card__image), a Heading (.card__title), a Paragraph (.card__body) - Select the outer Div, add class
.card - Style
.card: - Background-color:
var(--color-surface) - Border-radius:
8px - Padding:
var(--space-md) - Display:
flex, Flex-direction:column, Row-gap:var(--space-sm) - Style
.card__title: Font-familyvar(--font-heading), Font-sizevar(--font-size-lg) - Style
.card__body: Colorvar(--color-text)
Now duplicate the card across pages. Every instance uses the same classes, the same variables. Change --color-surface and all cards update.
Utility classes for common patterns¶
Beyond components, create small utility classes for repeated patterns:
.text-center— Text-align:center.visually-hidden— accessible hiding (for screen readers).container— max-width with auto margins for centered page content.flex-row— Display:flex, default row direction.flex-col— Display:flex, Flex-direction:column.gap-md— Column-gap and Row-gap:var(--space-md)
Apply multiple classes to one element: select it, type the first class, then add another in the selector field. The element inherits styles from all its classes.
Combining Symbols and classes¶
Symbols handle structure (shared header, footer, nav). Classes handle styling. Together they form your design system:
- Header Symbol with classes
.site-header,.site-header__logo,.site-header__nav - Footer Symbol with classes
.site-footer,.site-footer__links - Card pattern — not a Symbol (content differs per instance), but all share
.cardclasses
Rule of thumb: if the structure and content are identical across pages, use a Symbol. If only the styling is shared, use classes.
Keeping things consistent across breakpoints¶
Your design system should work at every screen size. Two strategies:
-
Variables that adapt. Define
--space-lgas32pxon desktop, then override it to16pxat the mobile breakpoint. Every element usingvar(--space-lg)adapts automatically. See breakpoints. -
Component classes that flex. A
.cardgrid that uses Flex-wrap with fixed-width cards adapts without any breakpoint-specific styles — cards just wrap to fewer columns. See Flexbox.
Practical example: design system for an agency site¶
Let's set up a system for the full site tutorial:
1. Define variables:
- Colors: --color-primary: #2563eb, --color-text: #1e293b, --color-background: #ffffff, --color-surface: #f8fafc
- Spacing: xs through xl (4px to 64px scale)
- Fonts: --font-heading: 'Inter', sans-serif, --font-body: 'Inter', sans-serif
2. Create component classes:
- .site-header — flex row, space-between, centered, padding var(--space-md)
- .hero — flex column, centered, padding var(--space-xl), background var(--color-primary), white text
- .card — surface background, rounded corners, flex column, gap
- .section — padding var(--space-xl) top and bottom, max-width container
3. Convert shared elements to Symbols: - Header → Symbol (reused on every page) - Footer → Symbol
4. Test at every breakpoint: - Desktop: 3-column card grid, full hero - Tablet: 2-column cards, smaller hero padding - Mobile: 1-column cards, stacked nav
Common mistakes¶
- Hard-coding colors and sizes. Every value should reference a CSS variable. If you type
#2563ebdirectly, you'll have to find and replace it everywhere later. - Naming classes after appearance.
.blue-boxbreaks when you rebrand. Name classes after purpose:.card,.highlight,.alert. - Too many one-off classes. If you have
.hero-title-special-homepage, you're not reusing enough. Compose from existing classes instead. - Forgetting to test across breakpoints. A system that only works on desktop isn't a system.
- Mixing Symbols and classes for the wrong use case. Symbols sync structure. Classes sync style. Don't make everything a Symbol.
Learn more¶
- BEM methodology — the full naming convention guide
- MDN: CSS custom properties — variable reference
- Symbols — reusable synced components
- CSS variables — creating and managing custom properties
- Flexbox — layout patterns for design systems
- Responsive design — adapting your system to all screen sizes
- Full site tutorial — applying a design system step by step
Quiz¶
Q1: You want to change your brand color across the entire site. What's the fastest way?
- A) Find and replace the hex code in every class
- B) Change the
--color-primaryCSS variable - C) Edit each element individually in the Style panel
Answer
B) Change the --color-primary CSS variable — every element using var(--color-primary) updates automatically. That's the whole point of defining variables first.
Q2: You have a card component used on 3 pages. The content is different on each page but the styling is the same. Should you use a Symbol?
- A) Yes, Symbols keep styling consistent
- B) No, use shared CSS classes instead
- C) Use both a Symbol and classes
Answer
B) No, use shared CSS classes instead — Symbols sync structure and content. Since the content differs per page, classes are the right tool for shared styling.
Q3: What does the BEM class name .card__title--large tell you?
- A) A card with a large title that is a separate component
- B) The title element inside a card block, with a "large" variation
- C) A title that is larger than a card
Answer
B) The title element inside a card block, with a "large" variation — card is the block, __title is the element, --large is the modifier.
Q4: Your spacing feels inconsistent across the site. What should you do?
- A) Define spacing CSS variables (--space-sm, --space-md, etc.) and use them everywhere
- B) Set the same pixel value on every element
- C) Use the browser's default spacing
Answer
A) Define spacing CSS variables and use them everywhere — a spacing scale ensures consistency. When you need to adjust, change the variable once.
Q5: You want your card grid to automatically show fewer columns on mobile without writing breakpoint-specific styles. How?
- A) Use CSS Grid with auto-fit
- B) Use Flexbox with Flex-wrap and fixed-width cards
- C) Create separate layouts for each breakpoint
Answer
B) Use Flexbox with Flex-wrap and fixed-width cards — cards wrap to the next row when there isn't enough space. No breakpoints needed for this basic responsive behavior.