Codeskill

Learn to code, step by step

Mini project: themeable component stylesheet set

This mini project builds a small set of themeable components – button, card, and alert – using tokens, CSS custom properties, and a light/dark switch. It pulls together folder structure, maps, and theming from earlier tutorials.

What you are building

  • Folder layout: abstracts/, base/, components/, themes/, main.scss.
  • Token maps for colour and spacing.
  • CSS variables emitted for light and dark themes.
  • Three components styled only with var(--color-*) and spacing tokens.
  • Optional data-theme toggle (HTML + a few lines of JS).

Starter structure

scss/
  abstracts/
    _variables.scss
    _mixins.scss
    _functions.scss
  base/
    _reset.scss
    _typography.scss
  components/
    _button.scss
    _card.scss
    _alert.scss
  themes/
    _light.scss
    _dark.scss
  main.scss
css/
  main.css
index.html

Theme partial example

// themes/_light.scss
$theme-light: (
  'bg': #ffffff,
  'text': #1a1a1a,
  'brand': #2563eb,
  'danger': #dc2626,
  'success': #16a34a,
);

:root,
[data-theme='light'] {
  @each $key, $value in $theme-light {
    --color-#{$key}: #{$value};
  }
  color-scheme: light;
}

Button component

// components/_button.scss
.button {
  display: inline-flex;
  align-items: center;
  padding: var(--space-sm, 0.75rem) var(--space-md, 1rem);
  border: 1px solid transparent;
  border-radius: 0.375rem;
  font: inherit;
  cursor: pointer;
}

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

.button--ghost {
  background: transparent;
  color: var(--color-brand);
  border-color: var(--color-brand);
}

HTML smoke test

Add buttons, a card, an alert, and a theme toggle to index.html. Use classes button, button--primary, button--ghost, card, card__title, card__body, alert alert--danger, and id="theme-toggle" on the toggle button.

Wire the toggle to flip data-theme on <html>. Compile with watch mode and check both themes in the browser.

Acceptance checks

  • No raw hex in component partials – only in theme/token files.
  • Light and dark both readable (contrast sanity check).
  • Compiled CSS one file; source map works in DevTools.
  • Lint passes with your Stylelint config.

Stretch goals

  • Add a second brand theme class.
  • Generate spacing utilities from a map with @each.
  • Document tokens in a short README.
PreviousSharing SCSS across projects