Difference Between em, rem and vw in CSS (With Examples)

Choosing the right CSS unit can quietly make or break your layout. It affects readability, responsiveness, and how maintainable your code is over time. If you’ve ever wondered when to use em, rem, or vw, you’re not alone.

Instead of just definitions, let’s walk through how these units actually behave in real projects—and which one you should rely on most of the time.


Featured Image Ideas

Use any of these as your blog’s featured image (good for WordPress SEO + CTR):

  • CSS Units Comparison Diagram (em vs rem vs vw)

  • Responsive Typography Illustration (clamp in action)

  • Viewport vs Root vs Parent Visual Explanation

Alt text suggestion: Difference between em rem vw css units diagram


Understanding the Core Difference

At a high level, all three units are relative, but they are relative to different things:

  • em → relative to the parent element

  • rem → relative to the root (html)

  • vw → relative to the viewport width (screen size)

That single difference changes everything in how they behave.


em: Flexible but Can Get Tricky

The em unit scales based on its parent’s font size. This makes it powerful for components, but also easy to misuse.

.parent {
font-size: 20px;
}

.child {
font-size: 2em; /* 40px */
}

Now imagine nesting:

.child {
  font-size: 2em; /* 40px */
}

.grandchild {
  font-size: 2em; /* 80px */
}

This compounding effect is where things can go out of control in complex layouts.

Where em works well:

It shines inside self-contained components where you want elements to scale relative to each other—like buttons, cards, or modals.


rem: The Reliable Default

If you want consistency across your entire project, rem is your best friend.

It always refers back to the root (html) font size:

html {
  font-size: 16px;
}

h1 {
  font-size: 2.5rem; /* 40px */
}

No matter where the element sits in the DOM, the value stays predictable.

This is why most modern CSS systems prefer rem for typography and spacing.


vw: Built for Responsiveness

vw is tied directly to the screen width.

.container {
  width: 90vw;
}

This means your layout automatically adapts:

  • Larger screen → bigger layout

  • Smaller screen → smaller layout

It’s perfect for fluid designs, but using it alone for text can cause issues—text may become too small on mobile or too large on wide screens.


A Practical Base Setup

Here’s a clean starting point that works for most websites:

html {
  font-size: 16px;
}

body {
  font-size: 1rem;
}

h1 {
  font-size: 2.5rem;
}

.container {
  width: 90vw;
}

This gives you consistency + responsiveness without complexity.


Modern Best Practice: Using clamp()

One of the most practical techniques in modern CSS is combining rem and vw using clamp().

h1 {
  font-size: clamp(1.5rem, 4vw, 3rem);
}

What’s happening here:

  • Minimum → 1.5rem (24px)

  • Fluid → 4vw (scales with screen)

  • Maximum → 3rem (48px cap)

This ensures your text is always readable and never extreme.


More Real-World clamp() Examples

Responsive Heading

h2 {
  font-size: clamp(1.25rem, 3vw, 2.5rem);
}

Paragraph Text

p {
  font-size: clamp(0.9rem, 1.2vw, 1.1rem);
}

Section Spacing

.section {
  padding: clamp(1rem, 5vw, 4rem);
}

Container Width

.container {
  width: clamp(300px, 80vw, 1200px);
}

Why clamp() is Better Than Media Queries (Sometimes)

Instead of writing multiple breakpoints like this:

@media (max-width: 768px) {
  h1 { font-size: 24px; }
}

You can often replace it with one clean line using clamp().

Less code, smoother scaling.


So, Which One Should You Use?

In real-world projects, the answer isn’t choosing one—it’s combining them smartly.

  • Use rem for typography and spacing

  • Use vw for layout and responsiveness

  • Use em only when component-level scaling is needed

  • Use clamp() to balance everything

If you stick to one rule:

Default to rem, enhance with vw, control with clamp().


Final Thoughts

Good CSS isn’t about using fancy units—it’s about choosing predictable, scalable patterns.

Start simple:

  • rem → foundation

  • vw → responsiveness

  • clamp() → control

Once you get this combination right, your layouts become much easier to manage as your project grows.