Skip to main content
UnitCraftCSS tools for devs

Published 2026-03-12 · Updated undefined · 4 min read

By Akash Yadav · Frontend Engineer

Modern CSS Units Guide for 2026 (REM, Viewport, Containers, and Fluid Type)

A practical map of the units that matter in modern frontends: REM, viewport sizing, dynamic viewport units (dvh), container queries, and clamp() for fluid typography.

Why unit choice matters

CSS units are not interchangeable. Choosing the wrong one introduces layout fragility, accessibility regressions, and maintenance debt that compounds over time. In 2026, frontend teams have more unit options than ever—but that abundance makes intentional choices more important, not less.

A rough mental model: absolute units (px, pt) describe physical measurements; relative units (rem, em, %) describe proportional relationships; viewport units (vw, vh, dvh) describe fractions of the browser canvas; container units (cqw, cqh) describe fractions of the nearest named container. Each category solves a distinct class of problem.

REM and accessible scaling

REM relates every value to the root (html) font size. That mirrors how users change text scaling at the OS or browser level, so your interfaces stay proportionate without breakpoint overrides.

When teams hard-code pixels for type, they fight user defaults:

/* Fragile: ignores user preferences */
body { font-size: 16px; }
h1   { font-size: 32px; }

/* Resilient: honours root scaling */
body { font-size: 1rem; }
h1   { font-size: 2rem; }

For spacing tokens, the same rule applies. A card with padding: 24px cannot respond to a user who has bumped their browser default to 20px. A card with padding: 1.5rem automatically gives them 30px of breathing room.

When you receive pixel comps from design, use the PX to REM tool to convert values against the project's root size. Document the assumed root so future team members can reproduce the math.

Viewport and dvh realities

Viewport units map layout to the browser canvas, which makes them ideal for hero sections, sticky headers, and full-bleed overlays. The classic 100vh pattern breaks on mobile because of collapsing browser chrome:

/* Breaks on iOS Safari — chrome collapses and 100vh clips content */
.hero { height: 100vh; }

/* Safer: use dvh for the visible area */
.hero { height: 100dvh; }

/* With clamp fallback for very old browsers */
.hero {
  height: 100vh;
  height: 100dvh;
}

The dynamic viewport units family:

UnitMeaning
dvh / dvwDynamically tracks visible viewport (changes as chrome appears/disappears)
svh / svwSmallest viewport (chrome fully visible — conservative)
lvh / lvwLargest viewport (chrome fully hidden — generous)

For most full-screen hero sections, dvh is the right choice. For content that must never be clipped, svh is the safe bet.

Use UnitCraft's PX to VW helper when you need numeric equivalence to a design width, and pair the result with clamp() so fluid values never collapse below readable minimums.

Container query units

Component-based architectures benefit enormously from @container and cqw/cqh because sizing tracks the card or widget, not the whole viewport. A sidebar panel component that renders at 260px in a three-column layout and 480px in a single-column layout can now size its internal type and spacing correctly in both contexts—without duplication.

/* Define the container */
.card-wrapper {
  container-type: inline-size;
  container-name: card;
}

/* Size internals relative to the card, not the viewport */
.card-title {
  font-size: clamp(1rem, 4cqw, 1.5rem);
}

.card-body {
  padding: clamp(0.75rem, 3cqw, 1.5rem);
}

Try the PX to CQW converter when you need to express a pixel measurement as a percentage of a known container width.

Unit comparison table

Property concernBest unitWhy
Typography (body, headings)remRespects root font-size changes and user preferences
Component spacing (padding, gap)remScales with type tokens for visual harmony
Viewport-width layout tracks% or frFlows with the available space
Full-screen backgrounds / heroesdvh / dvwAvoids iOS chrome clipping
Fluid headlinesclamp() with vwSmooth interpolation across breakpoints
Component-internal sizingcqw / cqhTracks container, not viewport
Borders, focus rings, 1px linespxPrecise sub-pixel rendering
Print stylespt or cmMaps to physical paper dimensions

Browser compatibility

UnitChromeFirefoxSafariNotes
rem4+3.6+4+Universal — safe everywhere
vw / vh20+19+6+Universal — safe everywhere
dvh / dvw108+116+15.4+Good modern support; use vh fallback
cqw / cqh105+110+16+Full support in 2026
svh / lvh108+116+15.4+Same as dvh family

Progressive enhancement for dvh looks like two declarations, with the modern unit second:

.full-screen {
  min-height: 100vh;  /* fallback */
  min-height: 100dvh; /* modern override */
}

UnitCraft tooling loop

  1. Establish root size — document html { font-size } in your design system README or token file. Most projects use 16px.
  2. Convert comps — run pixel values through PX to REM or PX to EM as appropriate for the context.
  3. Generate fluid scales — use Fluid typography to produce clamp() strings for headlines and display copy.
  4. Validate container math — use PX to CQW when building components that use container units.
  5. Check Tailwind alignment — use Tailwind spacing converter to map REM values to the nearest utility class.
  6. Audit contrast — run color pairs through WCAG contrast checker to verify AA/AAA compliance.

For a deeper dive into choosing units per concern, read Best CSS units for responsive design.

Key takeaways

  • REM is the right default for typography and spacing tokens — use it unless you have a specific reason not to.
  • Avoid bare 100vh on mobile — use 100dvh with a 100vh fallback for full-screen layouts.
  • Container units are production-ready in 2026 and belong in any component-driven architecture.
  • px is still legitimate for hairlines, focus rings, and borders where sub-pixel precision matters.
  • clamp() bridges the gap between fixed-unit and fluid-unit thinking — it is not a replacement for units, but a smart combinator.

Frequently asked questions

Should everything be REM?
REM is a strong default for typography and spacing tokens, but vw/vh/vmin, cqw/cqh, %, and occasional px still belong in a mature system. Use the right unit for the right job.
What are dynamic viewport units (dvh, svh, lvh)?
Dynamic viewport units (dvh/dvw) reflect the current visible viewport as browser chrome appears or disappears. svh/svw are the smallest possible viewport (chrome fully visible), and lvh/lvw are the largest (chrome fully hidden). They solve the classic 100vh mobile scrollbar bug.
When should I use container query units (cqw, cqh)?
Use container units when a component's internal sizing should respond to its own container width rather than the global viewport. This is ideal for reusable card components, sidebar widgets, and design system atoms.
Are container query units widely supported in 2026?
Yes. Container queries and container units (cqw, cqh, cqi, cqb) have full support in Chrome 105+, Firefox 110+, and Safari 16+, giving them excellent global browser coverage in 2026.
What is the difference between vw and dvw?
vw is based on the initial containing block and does not respond to browser chrome changes. dvw dynamically tracks the visible viewport width, making it more accurate for full-screen mobile layouts.
Can I mix REM and container units in the same component?
Absolutely. A common pattern is to use REM for font-size and padding while using cqw for widths and fluid margins within a component. Just ensure the container has a defined size context via `container-type`.