SYP Start Your Path

Variables & Advanced CSS

CSS Variables

CSS variables (formally "custom properties") let you define a value once and reuse it everywhere — perfect for a site's color palette, spacing scale, or font sizes.

:root {
  --gdw-red: #C41230;
  --gdw-gold: #F5A623;
  --gdw-dark: #1A1A2E;
  --spacing: 16px;
  --radius: 8px;
}

.card {
  background: var(--gdw-dark);
  color: white;
  padding: var(--spacing);
  border-radius: var(--radius);
  border: 2px solid var(--gdw-gold);
}

/* Provide a fallback in case the variable isn't defined */
.box {
  color: var(--text-color, black);
}

:root refers to the top-level <html> element, so variables defined there are available everywhere on the page. Variables can also be scoped to just one component by defining them on a specific class instead.

Unlike Sass/Less variables, CSS variables are live in the browser — they can be changed at runtime with JavaScript and the whole page updates instantly, which makes them ideal for features like theme switchers:

document.documentElement.style.setProperty('--gdw-red', '#e0143a');

CSS Functions

/* calc() — mix units and do math */
.box {
  width: calc(100% - 40px);
  height: calc(100vh - 70px); /* full height minus a fixed header */
}

/* min() / max() — pick the smaller/larger of two values */
.box {
  width: min(90%, 600px); /* never wider than 600px, but shrinks on small screens */
  font-size: max(16px, 1.2vw);
}

/* clamp(min, preferred, max) — fluid values with hard limits, no media query needed */
h1 {
  font-size: clamp(1.5rem, 4vw, 3rem);
}

Box-sizing

Recall from the box model chapter that padding and border add to an element's total size by default. box-sizing: border-box changes that, so the width/height you set already includes padding and border — much easier to reason about.

/* Applied globally, this is one of the most common resets in real projects */
*, *::before, *::after {
  box-sizing: border-box;
}

.box {
  width: 300px;     /* with border-box, this 300px INCLUDES padding + border */
  padding: 20px;
  border: 5px solid black;
  /* total rendered width is exactly 300px, not 350px */
}

Units Explained

.px    { width: 200px; }  /* fixed pixels — same size everywhere */
.pct   { width: 50%; }    /* relative to the parent element */
.em    { font-size: 1.5em; }  /* relative to the PARENT's font-size */
.rem   { font-size: 1.5rem; } /* relative to the ROOT (html) font-size — predictable, most common choice */
.vw    { width: 100vw; }  /* 1% of the viewport (browser window) width */
.vh    { height: 100vh; } /* 1% of the viewport height */
.vmin  { font-size: 5vmin; } /* 1% of whichever is smaller, viewport width or height */

Rule of thumb: use rem for font sizes and spacing (scales predictably and respects the user's browser font-size setting), % or fr for layout widths, and px for things that genuinely shouldn't scale, like a 1px border.