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.