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-unit give 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-box ensures 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);
}
  • .container centers content and limits width (for readability)
  • .stack and .row give 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.

Author

Alex is the resident editor and oversees all of the guides published. His past work and experience include Colorlib, Stack Diary, Hostvix, and working with a number of editorial publications. He has been wrangling code and publishing his findings about it since the early 2000s.