Frontend Engineer Hub

CSS and Design-System Implementation for Frontend Engineers (2026)

In short

Modern CSS in 2026 is a different language than 2015. Cascade layers (@layer) let you order specificity by intent rather than by selector arms-race. Container queries make components self-aware of their layout context. CSS variables at the design-token tier enable theming, dark mode, and design-system extension without preprocessors. The senior bar in 2026: you can hand-write modern CSS without reaching for utility frameworks; you understand the design-token pipeline (Figma tokens → Style Dictionary → CSS variables); you know when CSS Modules / vanilla-extract / Tailwind / unstyled-with-css-variables fits which problem.

Key takeaways

  • Cascade layers (@layer) are the modern way to manage CSS specificity. They let you order specificity by intent; design-system base layer, component layer, utility layer, override layer; rather than by selector specificity arms-race.
  • Container queries (@container) make components self-aware of their parent's size, not the viewport's size. This is the modern primitive for true component-driven responsive design. MDN's container-query reference (developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries) is the canonical reference.
  • CSS variables (custom properties) at the design-token tier enable theming, dark mode, and design-system extension without preprocessors. The pipeline: Figma design tokens → Style Dictionary (or similar tool) → CSS variables → component styles consume them.
  • Modern layout in 2026 is grid + flexbox + container queries. Flexbox for one-dimensional layout (rows or columns); CSS grid for two-dimensional layout (full-page layouts, card grids); container queries for component-level responsive behavior. Josh W. Comeau's CSS for JavaScript Developers (joshwcomeau.com/courses/css-for-js) is canonical.
  • Design-system implementation choices: CSS Modules (scoped-by-default, simple), vanilla-extract (typed CSS-in-TS at build time), Tailwind (utility-first, fast for prototyping), styled-components / emotion (runtime CSS-in-JS, increasingly out of favor). The 2026 lean is build-time over runtime.
  • The senior bar includes prefers-reduced-motion respect (a real accessibility requirement, not a nice-to-have), prefers-color-scheme handling for system dark mode, and forced-colors mode handling for high-contrast users. MDN covers each.
  • Logical properties (margin-inline, padding-block, inset) enable RTL support without separate stylesheets. Senior frontend engineers default to logical properties on global / shared CSS.

Cascade layers: ordering specificity by intent

Cascade layers (the @layer at-rule, broadly supported in 2024+) are the modern way to manage CSS specificity. Instead of fighting specificity with !important or selector-specificity-arms-race, you declare layers and order them by intent.

/* main.css; top-level style sheet */

/* Order layers from least-specific to most-specific intent.
 * Later layers always win over earlier layers regardless of selector
 * specificity. */
@layer reset, base, design-system, component, utility, override;

/* Reset layer; lightest possible specificity */
@layer reset {
  *,
  *::before,
  *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
  }
}

/* Base layer; typography, root colors, page-wide defaults */
@layer base {
  :root {
    --color-text: oklch(0.2 0 0);
    --color-bg: oklch(1 0 0);
    --font-sans: system-ui, sans-serif;
  }

  body {
    color: var(--color-text);
    background-color: var(--color-bg);
    font-family: var(--font-sans);
    line-height: 1.5;
  }
}

/* Design-system layer; primitive components */
@layer design-system {
  .button {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding-block: 0.5rem;
    padding-inline: 1rem;
    border-radius: 0.5rem;
    font-weight: 600;
  }

  .button[data-variant="primary"] {
    background-color: var(--color-accent);
    color: var(--color-on-accent);
  }
}

/* Component layer; feature-specific styles */
@layer component {
  .checkout-form .button {
    /* Even though .checkout-form .button is more specific by selector,
     * cascade-layer order is what wins. component layer beats
     * design-system layer regardless of selector specificity. */
    width: 100%;
  }
}

/* Utility layer; single-purpose utilities */
@layer utility {
  .visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
  }
}

The senior+ pattern: declare layers at the project root, place imported styles into named layers (@import "./design-system.css" layer(design-system)), and trust the layer-order to resolve specificity conflicts. The result is CSS that scales across hundreds of contributors without specificity wars.

MDN's cascade-layers reference (developer.mozilla.org/en-US/docs/Web/CSS/@layer) is the canonical reference; Josh W. Comeau's writing on cascade layers covers the practical patterns.

Container queries: component-driven responsive design

Container queries (the @container at-rule, broadly supported since 2023) let components respond to their parent's size rather than the viewport's size. The pattern enables true component-driven responsive design.

/* The component declares itself a container by setting container-type.
 * "inline-size" makes container queries query the inline (horizontal)
 * dimension. */
.product-card {
  container-type: inline-size;
  container-name: product-card;
}

/* Default styles; narrow layout */
.product-card-content {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}

.product-card-image {
  width: 100%;
  aspect-ratio: 4 / 3;
}

/* When the container is wider than 480px, switch to two-column layout */
@container product-card (inline-size > 480px) {
  .product-card-content {
    grid-template-columns: 200px 1fr;
  }

  .product-card-image {
    aspect-ratio: 1 / 1;
  }
}

/* When the container is wider than 720px, switch to three-column layout */
@container product-card (inline-size > 720px) {
  .product-card-content {
    grid-template-columns: 280px 1fr 200px;
  }
}

The benefit: a product card on a sidebar (300px wide) renders in single-column mode; the same product card on a full-width grid (800px wide) renders in two-column mode automatically; without any JavaScript or media queries. The component is self-aware.

The contrast with viewport media queries: a viewport media query (@media) targets the browser viewport. A container query targets the component's parent container. The two coexist but solve different problems. Senior+ frontend engineers reach for container queries for component-level responsiveness and viewport queries for page-level layout.

MDN's container-query reference (developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries) is the canonical reference.

Design tokens: the Figma to CSS variables pipeline

Design tokens are the named, structured values that define a design system's visual language; colors, typography scale, spacing scale, border radii, shadows. The modern pipeline: design tokens defined in Figma (or a design-token-tool) → Style Dictionary (or similar) transforms them to CSS variables → component styles consume them.

/* tokens.css; generated from Figma via Style Dictionary */

:root {
  /* Color palette (raw tokens) */
  --color-blue-500: oklch(0.65 0.18 245);
  --color-blue-600: oklch(0.58 0.18 245);
  --color-blue-700: oklch(0.52 0.18 245);

  --color-gray-50: oklch(0.98 0 0);
  --color-gray-100: oklch(0.96 0 0);
  --color-gray-900: oklch(0.18 0 0);
  --color-gray-950: oklch(0.10 0 0);

  /* Semantic tokens; alias raw tokens by intent */
  --color-bg-base: var(--color-gray-50);
  --color-bg-surface: var(--color-gray-100);
  --color-text-primary: var(--color-gray-900);
  --color-accent: var(--color-blue-600);
  --color-accent-hover: var(--color-blue-700);
  --color-on-accent: var(--color-gray-50);

  /* Spacing scale */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;

  /* Typography scale */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
}

/* Dark mode overrides; flip the semantic layer, raw tokens stay */
@media (prefers-color-scheme: dark) {
  :root {
    --color-bg-base: var(--color-gray-950);
    --color-bg-surface: var(--color-gray-900);
    --color-text-primary: var(--color-gray-50);
    --color-on-accent: var(--color-gray-50);
  }
}

/* Components consume the semantic tokens; never the raw palette */
.card {
  background-color: var(--color-bg-surface);
  color: var(--color-text-primary);
  padding: var(--space-6);
  border-radius: 0.75rem;
}

The two-tier pattern: raw tokens (the actual color value) and semantic tokens (the named intent; bg-base, accent, on-accent). Components consume only semantic tokens; theming and dark mode swap the semantic layer while leaving raw tokens stable. Adding a new theme is changing semantic-token assignments, not rewriting components.

Style Dictionary (styledictionary.com) is the dominant tool for transforming design tokens from a source format (Figma JSON, Tokens Studio JSON) to CSS variables, JavaScript constants, iOS / Android assets. Modern Figma plugins like Tokens Studio sync directly to a GitHub repo where Style Dictionary runs in CI.

Modern layout: grid + flexbox + container queries

Modern CSS layout in 2026 is three primary primitives:

  • Flexbox for one-dimensional layout (a row of items, a column of items). Use when you want items to line up along a single axis.
  • CSS Grid for two-dimensional layout (full-page layouts, card grids, design-system templating). Use when you want explicit row + column control.
  • Container queries for component-driven responsive behavior layered on top of grid / flexbox.

A canonical layout; a dashboard with a sidebar, a header, a main content area, and a footer:

.dashboard {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: 64px 1fr 48px;
  grid-template-areas:
    "sidebar header"
    "sidebar main"
    "sidebar footer";
  min-height: 100vh;
}

.dashboard-header { grid-area: header; }
.dashboard-sidebar { grid-area: sidebar; }
.dashboard-main { grid-area: main; padding: var(--space-6); overflow: auto; }
.dashboard-footer { grid-area: footer; }

/* Mobile; collapse to single column with sidebar as drawer */
@media (max-width: 768px) {
  .dashboard {
    grid-template-columns: 1fr;
    grid-template-rows: 64px 1fr 48px;
    grid-template-areas:
      "header"
      "main"
      "footer";
  }

  .dashboard-sidebar {
    /* Becomes a drawer; show / hide via JS or a checkbox hack */
    position: fixed;
    inset: 0 auto 0 0;
    width: 240px;
    transform: translateX(-100%);
    transition: transform 0.2s;
  }

  .dashboard-sidebar[data-open="true"] {
    transform: translateX(0);
  }
}

/* Card grid inside main; auto-fit to as many columns as fit */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-6);
}

/* Flexbox for the card itself; image on left, content on right */
.card {
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
}

What this layout gets right: grid-template-areas for the page-level layout (more readable than column / row indices); auto-fit grid for responsive card grids; logical properties (inset) for RTL support; flexbox for the one-dimensional card layout.

Josh W. Comeau's CSS for JavaScript Developers (joshwcomeau.com/courses/css-for-js) is the canonical course; the MDN CSS reference (developer.mozilla.org/en-US/docs/Web/CSS) is the canonical specification reference.

Frequently asked questions

Should I use Tailwind or vanilla CSS?
Both work; the codebase consistency and team preference matters more. Tailwind (utility-first) is fast for prototyping and consistent at scale; vanilla CSS with cascade layers is more flexible and produces smaller HTML. The 2026 SaaS-tier reality: Vercel uses Tailwind heavily on marketing surfaces; Linear uses custom CSS Modules; Stripe uses internal-design-system CSS; Figma uses internal CSS-in-JS. The senior frontend bar: be conversant in both, articulate the trade-offs.
Is CSS-in-JS still recommended in 2026?
Runtime CSS-in-JS (styled-components, emotion) has fallen out of favor at SaaS-tier; the runtime cost on Server Components rendering is real, and the bundling story is awkward in App Router. Build-time CSS-in-JS (vanilla-extract, panda-css) is the modern alternative for teams that want typed CSS without the runtime cost. Most new SaaS-tier projects in 2026 use either Tailwind, CSS Modules, or vanilla-extract.
Should I learn Sass / Less in 2026?
Rarely necessary. Modern CSS has CSS variables, calc(), nesting (broadly supported in 2024+), and most of what Sass / Less provided historically. Sass is still used in legacy codebases; new projects rarely add it. The Microsoft-and-Bootstrap world is one exception where Sass is still common.
How do I handle dark mode?
Three approaches. (1) Pure CSS via @media (prefers-color-scheme: dark) and CSS variable overrides; simplest, no JS needed, respects user OS preference automatically. (2) JS-toggleable via a [data-theme='dark'] attribute on the html / body element; supports user override of OS preference. (3) Both, layered; default to OS preference, allow user override via cookie. Most production sites use approach (3).
Should I use logical properties?
Yes for any global / shared CSS. Logical properties (margin-inline, padding-block, inset, border-inline-start) automatically adapt to RTL languages. The cost is zero (CSS variables are unaffected); the benefit is real for any product that supports international users. Modern CSS lints (stylelint with logical-properties plugin) flag physical-property usage.
What's the role of CSS Houdini in 2026?
Limited but growing. The Properties and Values API (@property at-rule per MDN) reached Baseline 2024 and is the most-used part of Houdini in production; it lets you type-check CSS variables. The CSS Painting API (Paint Worklet) is experimental / limited availability per MDN; the CSS Layout API (Layout Worklet) is not production-ready (only partial Chrome Canary support per MDN).
How important is print-stylesheet support in 2026?
Niche. Most consumer products skip print-specific CSS entirely. B2B / enterprise / fintech products with print-receipt or print-document use cases need print stylesheets (@media print). The 2026 senior bar: know that @media print exists and how to test it, not necessarily ship it on every project.

Sources

  1. MDN; Web/CSS reference. Canonical CSS specification reference.
  2. Josh W. Comeau; CSS for JavaScript Developers. Canonical practical CSS course.
  3. MDN; Cascade layers (@layer). Canonical for the modern specificity-management pattern.
  4. MDN; Container queries. Canonical for component-driven responsive design.
  5. Style Dictionary; the canonical design-token transformation tool.
  6. Smashing Magazine; CSS deep-dives. Practical articles at senior+ depth.
  7. Josh W. Comeau; joshwcomeau.com. CSS deep-dives and modern-layout writing.

About the author. Blake Crosley founded ResumeGeni and writes about frontend engineering, hiring technology, and ATS optimization. More writing at blakecrosley.com.