Many of us lean on frameworks, utility libraries, or large resets. But for many sites, you don’t need that heavy machinery. A concise baseline:
- boosts performance (less to download / parse)
- reduces toolchain friction
- is easier to reason about
- gives you room to expand with intention
Let’s build that baseline for 2025, using modern CSS features.
Foundation: fluid typography + theming
html {
color-scheme: light dark;
--body-font: system-ui, sans-serif;
--base-size: 1rem;
--scale-min: 1rem;
--scale-max: 1.25rem;
--spacing-unit: 1rem;
}
body {
font-family: var(--body-font);
font-size: clamp(var(--scale-min), 1vw + 1rem, var(--scale-max));
line-height: 1.5;
margin: 0;
padding: 0;
background: canvas;
color: canvastext;
}Here’s what’s going on:
- Fluid font-size via
clamp()— the browser picks a value between a min and max depending on viewport width. (No need for breakpoints just for font size.) - Theming variables — values like
--spacing-unitgive you a single knob to adjust spacing or other scale-based values across your site color-scheme+canvas/canvastext— delegates basic colors (background, text) to the browser’s built-in choices (light vs dark)
Responsive assets & box model
*, *::before, *::after {
box-sizing: border-box;
}
img, svg, video, picture {
max-width: 100%;
height: auto;
display: block;
}- A universal
box-sizing: border-boxensures padding/border don’t bloat element width unexpectedly. - Making images/videos/SVGs responsive by default avoids overflow issues in responsive layouts.
Links, focus, and accessibility tweaks
a:not([class]) {
text-decoration-thickness: max(0.08em, 1px);
text-underline-offset: 0.15em;
}
:focus {
outline: 2px solid Highlight;
outline-offset: 2px;
}- This gives a nicer default underline to links that aren’t specifically styled.
- A visible focus outline is crucial for keyboard users.
Layout utility primitives
I like including just a few helpers—but minimal ones:
.container {
max-width: min(75ch, 100% - 2 * var(--spacing-unit));
margin-inline: auto;
padding-inline: var(--spacing-unit);
}
.stack {
display: flex;
flex-direction: column;
gap: var(--spacing-unit);
}
.row {
display: flex;
flex-wrap: wrap;
gap: var(--spacing-unit);
}.containercenters content and limits width (for readability).stackand.rowgive basic layout tools without needing a utility framework
If you use components, you can rely on these primitives and augment as needed.
CodePen demo
See the Pen Untitled by Alex Ivanovs (@stackdiary) on CodePen.
What’s next — extend intentionally
Once you have the baseline, here are common ways to build on it:
- Buttons, cards, forms — style them with CSS variables so they integrate smoothly
- Container queries — make components adapt to their container, not just viewport
- Component-level CSS variables — allow each component to have adjustable settings
- Animations / transitions — for micro-interactions
- Dark / custom themes — override CSS variables or use
prefers-color-scheme+ toggle
Final thoughts
This minimal CSS is not “complete” — no baseline handles every UI case. But it gives you a solid skeleton: responsive typography, layout primitives, theming hooks, basic asset handling, and accessibility support.
From there, you can pick and choose which components or utilities to layer in, knowing the foundation is clean, modern, and future-friendly.