Lesson 28 / Systems

Design Systems

Time
51 min
Type
Reading + Interactive
Level
Intermediate
Use
Studio Support

Create a mini design system with reusable colors, spacing, typography, buttons, cards, forms, navigation, states, and accessibility rules for a consistent project.

Course Role

Studio Support

Best during work sessions, critique, debugging, project planning, or final polish.

Teacher Notes / In-Class Use

Demo Live

  • Walk through the interactive demo before students start changing their own project files.
  • Connect the demo back to the first goal: Explain what a small project design system does

Try In Class

  • Identify three repeated patterns in your project.
  • Have students make one visible change, save, refresh, and explain what changed.

Submit Or Check

  • Ask students to show the work in the browser, not only in the editor.
  • Have students commit their progress with a clear message when the checkpoint is stable.

Watch For

  • Students copying code without checking file paths, spelling, or capitalization.
  • Visual changes that work locally but break when the project is published.

Learning Goals

  • Explain what a small project design system does
  • Define reusable tokens for color, type, spacing, radius, borders, and shadows
  • Build consistent buttons, cards, forms, containers, and navigation patterns
  • Audit a project for one-off styles and refactor them into reusable components

Interactive Demo

How to use this demo.

Use the demo as a small lab. Change one thing, observe the result, then connect it back to your own project.

What To Try

  • Change the accent, radius, and spacing tokens.
  • Watch the card, button, and input update from the same reusable values.

What Changes

  • One token change affects multiple components at once.
  • The generated CSS shows the custom properties behind the visual system.

What To Notice

  • Design systems reduce one-off styling by giving repeated decisions a shared name.
  • Tokens should describe design decisions that repeat across the project.

Apply It

  • Create a small :root token set for colors, spacing, and radius in your own project.

Interactive Demo

Design System Token Lab

Adjust a few reusable values and watch multiple components update together.

Featured

Reusable Card

The card, button, and form field share the same tokens.

:root { --accent: #73d36b; }

This demo uses extra JavaScript for teaching. The code sample shows the pattern to practice. View full demo source.

Design Systems in Student Terms

A small design system is the reusable visual and code rules for your project. It helps the site feel intentional instead of like every page was styled separately.

For class projects, a design system does not need to be huge. Start with shared colors, type, spacing, buttons, cards, forms, navigation, layout containers, and states.

What Belongs in a Mini Design System

PartDecisions To Make
ColorsBackground, text, brand, accent, border, muted text, success, warning, and error colors.
TypographyFont families, heading scale, body size, line height, and font weights.
SpacingReusable spacing values for sections, cards, grids, and form fields.
ComponentsButtons, cards, forms, navigation, badges, and layout containers.
StatesHover, focus, active/current, disabled, loading, error, and success states.
AccessibilityContrast, visible focus, semantic HTML, labels, and keyboard-friendly controls.

Design Tokens

Tokens are named values. They make design decisions easier to reuse and easier to change later.

Use names that describe purpose when possible. --color-brand is more useful than --blue because the brand color may change later.

:root {
  --color-background: #ffffff;
  --color-surface: #f7f7f4;
  --color-text: #111111;
  --color-muted: #5f635f;
  --color-brand: #2f6fed;
  --color-border: #d8ddd8;
  --color-error: #b42318;

  --font-body: system-ui, sans-serif;
  --font-display: Georgia, serif;

  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2rem;

  --radius-sm: 0.25rem;
  --radius-md: 0.5rem;
  --shadow-card: 0 0.75rem 2rem rgb(0 0 0 / 0.08);
}

Naming Guidance

AvoidPreferWhy
--blue--color-brandPurpose survives if the color changes.
--big-space--space-4 or --space-lgA scale keeps spacing consistent.
.big-blue-button.button-primaryRole matters more than appearance.
.left-box.sidebar or .card-asideNames should explain the component or purpose.

Button Component

A button component should include spacing, color, hover, focus, and disabled states. Use a real button for actions and an a element for navigation links.

<a class="button button-primary" href="/projects/">View projects</a>
<button class="button button-secondary" type="button">Save draft</button>

.button {
  align-items: center;
  border-radius: var(--radius-md);
  display: inline-flex;
  font-weight: 800;
  gap: 0.5rem;
  min-block-size: 2.75rem;
  padding: 0.75rem 1rem;
  text-decoration: none;
}

.button-primary {
  background: var(--color-brand);
  color: #ffffff;
}

.button-secondary {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  color: var(--color-text);
}

Card Component

Cards should use consistent padding, border, image ratios, heading size, and link behavior. A card is a repeated content pattern, not just a decorative box.

<article class="card">
  <img class="card-image" src="project.jpg" alt="Homepage design for a restaurant guide">
  <div class="card-body">
    <h2 class="card-title">Restaurant Guide</h2>
    <p>A responsive listing project for local restaurants.</p>
    <a href="/projects/restaurant-guide/">View project</a>
  </div>
</article>

.card {
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
}

.card-image {
  aspect-ratio: 16 / 9;
  object-fit: cover;
  width: 100%;
}

.card-body {
  display: grid;
  gap: var(--space-1);
  padding: var(--space-2);
}

Form Field Component

Form styles should include labels, help text, errors, and focus states. Do not rely on placeholder text as the only label.

<div class="form-field">
  <label for="email">Email address</label>
  <input id="email" name="email" type="email" aria-describedby="email-help">
  <p id="email-help">Use the email address you check most often.</p>
</div>

.form-field {
  display: grid;
  gap: 0.4rem;
}

.form-field input {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font: inherit;
  padding: 0.75rem;
}

Layout Container

A reusable container keeps page content aligned across sections. It is one of the simplest ways to make a site feel consistent.

.container {
  margin-inline: auto;
  max-width: 72rem;
  padding-inline: var(--space-2);
}

.section {
  padding-block: var(--space-4);
}

States Are Part of the System

A component is not complete if it only covers the default state. Include the states users will actually encounter.

StateSystem Decision
HoverHow links and buttons respond to pointer interaction.
FocusVisible keyboard focus style for links, buttons, and form fields.
Active/currentHow current navigation or selected filters are shown.
DisabledHow unavailable actions look without disappearing.
ErrorHow form fields communicate what needs to be fixed.
SuccessHow completed actions are confirmed.
:focus-visible {
  outline: 3px solid var(--color-brand);
  outline-offset: 3px;
}

.button-primary:hover {
  filter: brightness(0.92);
}

.button:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

Accessibility Rules

  • Use semantic HTML before creating custom controls.
  • Keep text and button contrast readable.
  • Include visible focus styles in every interactive component.
  • Use label elements for form controls.
  • Do not make every component a generic div.
  • Test reusable components with keyboard input, not only a mouse.

Before and After Refactor

Design systems often begin by noticing repeated one-off styles and turning them into reusable classes.

/* Before: every card has its own style */
.homepage-card {
  border: 1px solid #ddd;
  padding: 20px;
}

.project-card {
  border: 1px solid #ddd;
  padding: 20px;
}

/* After: shared component plus optional modifier */
.card {
  border: 1px solid var(--color-border);
  padding: var(--space-2);
}

.card-featured {
  box-shadow: var(--shadow-card);
}

Audit Your Project

Before building new styles, inspect what already exists. Your first design system task is often reducing inconsistency.

Audit QuestionWhat To Look For
How many button styles exist?Repeated button CSS that could become .button and modifiers.
Are card paddings consistent?Cards with different spacing values for no clear reason.
Are headings using the same scale?Random font sizes instead of a type system.
Are colors repeated directly?Hex values repeated throughout CSS instead of tokens.
Are focus states consistent?Some components with focus styles and others without.

Mini Style Guide Deliverable

A style guide page or section makes the system visible. It does not need to be fancy; it needs to show the decisions clearly.

  • Color swatches with token names.
  • Heading and body text examples.
  • Primary and secondary buttons, including hover and focus states.
  • A card component with real content.
  • A form field with label, help text, and error state.
  • Navigation or link styles.

Common Mistakes

MistakeFix
Creating a new button style for every pageCreate a shared .button class and modifier classes.
Using colors directly everywhereMove repeated values into custom properties.
Changing spacing one element at a timeUse a spacing scale.
Making components visually consistent but semantically weakUse correct HTML and accessibility behavior.
Building a huge system before the project needs itStart with the patterns your project actually uses.

Checkpoint

Before moving on, make sure these feel true.

  • I can define reusable color, spacing, and type values.
  • I can create consistent button, card, and form styles.
  • I can reduce one-off styling in a project.

Practice

  • Identify three repeated patterns in your project.
  • Create reusable classes for buttons, cards, and form fields.
  • Replace repeated color and spacing values with named custom properties.
  • Add hover, focus, and disabled states to one button component.
  • Create a mini style guide section showing colors, type, buttons, cards, and form fields.
  • Refactor one pair of one-off styles into a shared component class and modifier.

Resources