Skip to main content
Syllabus

CSS Units: px, rem, em, %, vw, vh and dvh

Badar KhalilUpdated September 30, 2026 7 min read

CSS Units: px, rem, em, %, vw, vh and dvh Explained

CSS units decide how big things are. Choosing between px, rem, em, %, vw and the newer dvh affects responsiveness, accessibility and how your layout behaves on phones. This lesson explains what each unit is relative to, when to use it, and the traps to avoid.

What You Will Learn

  • Absolute vs relative units
  • What rem, em and % are relative to
  • Viewport units: vw, vh, vmin, vmax and the dynamic variants svh, lvh, dvh
  • Other useful units: ch, lh, fr
  • Fluid sizing with clamp(), min() and max()
  • Which unit to choose for font size, spacing, width, height and media queries

Absolute Units: px

The px unit is a CSS pixel, a fixed reference size that scales with device pixel ratio, not one physical screen dot. Other absolute units such as cm, mm, in, pt and pc exist but are almost only useful for print stylesheets. On screens, px is good for borders, shadows, hairlines and small fixed details.

rem: Relative to the Root Font Size

One rem equals the computed font-size of the html element. Browsers default to 16px, so 1rem = 16px unless the user or your CSS changes it. Because rem respects the user font-size setting in the browser, it is the best unit for font sizes and global spacing scales. 1.5rem is 24px by default.

em: Relative to the Element Font Size

One em equals the font size of the element itself when used for most properties, but when used for font-size it is relative to the parent font size. This makes em powerful for components whose padding should scale with their text, such as a button with padding: 0.5em 1em;. It also makes nested em font sizes compound: a list inside a list with font-size: 0.9em gets smaller at each level.

rem vs em Quick Guide

  • Use rem for font sizes, page spacing and media queries. It is predictable.
  • Use em for component internals (button padding, icon size next to text) that should scale with the local font size.

The 62.5% Trick: Use with Care

Some developers set html { font-size: 62.5%; } so that 1rem = 10px. It makes mental math easier but it breaks many third-party components and shrinks default text unless you reset the body size. A safer option is to keep the default and use a spacing scale like 0.25rem, 0.5rem, 1rem, 1.5rem, 2rem. Never set the root font size in px, because that overrides the user preference.

Percentages (%): Relative to What?

The meaning of % depends on the property:

  • width, margin, padding: percent of the containing block width (even for vertical margin and padding).
  • height: percent of the containing block height, but only if that height is explicitly set. Otherwise it is treated as auto.
  • font-size: percent of the parent font size.
  • top, left and similar on positioned elements: percent of the containing block size.
  • transform: translate(): percent of the element own size, which is why translate(-50%, -50%) is used to center.

Viewport Units: vw, vh, vmin, vmax

  • 1vw = 1% of the viewport width.
  • 1vh = 1% of the viewport height.
  • 1vmin = 1% of the smaller viewport dimension, 1vmax = 1% of the larger.

Trap: 100vw includes the width of the vertical scrollbar on desktop, so a full-width element with width: 100vw creates a horizontal scrollbar. Prefer width: 100% for layout and use vw mainly for fluid type and decorative sizing.

The Mobile Problem with 100vh

On phones, the browser toolbar slides in and out while scrolling. Classic 100vh is based on the largest possible viewport (toolbar hidden), so a height: 100vh hero can be cut off behind the toolbar on first load. Modern CSS fixes this with three new families:

  • svh, svw: small viewport, sized as if the toolbars are visible.
  • lvh, lvw: large viewport, sized as if the toolbars are hidden (same as classic vh).
  • dvh, dvw: dynamic viewport, which updates as the toolbar shows or hides.

For full-screen sections use min-height: 100svh for a stable layout, or 100dvh when you want it to track the visible area exactly (it can cause resizing while scrolling). Provide a fallback for older browsers: min-height: 100vh; min-height: 100dvh;.

Other Useful Units

  • ch: width of the zero character in the current font. Perfect for readable text columns: max-width: 65ch;.
  • lh: the computed line height. Handy for vertical rhythm: margin-block: 1lh;.
  • ex: the x-height of the font (rarely used).
  • fr: a fraction of free space, only in CSS Grid, for example grid-template-columns: 1fr 2fr;.
  • Container query units cqw, cqh, cqi, cqb: relative to the size of a query container, useful for component-level responsiveness.

Fluid Sizing with clamp(), min() and max()

Math functions let a value grow with the viewport inside safe limits:

h1 { font-size: clamp(1.75rem, 1.2rem + 2.5vw, 3.5rem); }
.container { width: min(100% - 2rem, 70rem); margin-inline: auto; }

Mixing a rem term with a vw term in the preferred value keeps text zoomable for accessibility. A pure vw font size does not respond properly to browser zoom.

Unitless Values

A few properties accept unitless numbers: line-height: 1.5 (multiplier of the element font size, recommended), flex-grow, opacity, z-index and 0 for lengths (margin: 0 needs no unit).

Choosing the Right Unit

  • Font size: rem, or clamp() with rem and vw.
  • Padding and margin: rem for layout spacing, em for component internals.
  • Borders, shadows, hairlines: px.
  • Width of layout blocks: %, fr, min(), or max-width in ch or rem.
  • Full-screen sections: svh, dvh with a vh fallback.
  • Media queries: em or rem, so breakpoints respect user font size.

Common Mistakes

  • Setting html { font-size: 16px; } in px and blocking user scaling.
  • Using 100vw for full width and getting a horizontal scrollbar.
  • Using 100vh on mobile and losing content behind the browser toolbar.
  • Expecting height: 50% to work when the parent has no explicit height.
  • Nesting em font sizes and ending up with tiny or huge text.
  • Using pure vw for text, which breaks zoom.

Frequently Asked Questions

Should I use px or rem?

Use rem for text and spacing so the page respects user settings, and px for thin details like borders.

What is the difference between em and rem?

rem is always relative to the root font size. em is relative to the current element (or parent for font-size) and can compound when nested.

What is dvh in CSS?

It is the dynamic viewport height, which adjusts as mobile browser toolbars appear and disappear.

Why does my percentage height not work?

Because the parent has no explicit height. Set a height on the parent (or all ancestors up to html), or use Flexbox or Grid instead.

Key Takeaways

  • px is fixed, rem follows the root, em follows the element, % follows the containing block.
  • Viewport units are vw, vh, vmin, vmax. On mobile prefer svh or dvh over vh.
  • Avoid 100vw for layout width.
  • Use ch for readable line length and clamp() for fluid typography.
  • Keep the root font size in relative units for accessibility.
Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself HTML
Output

Press Run to execute.

Try it Yourself CSS
Output

Press Run to execute.

Try it Yourself JAVASCRIPT
Output

Press Run to execute.

Exercise: Convert UnitsJAVASCRIPT

Write two functions, pxToRem(px, base) and remToPx(rem, base), where base is the root font size in px (default 16). Round the rem result to 3 decimals.

Try it Yourself JAVASCRIPT
Output

Press Run to execute.

Show expected output
1.5
1
24

This is a self-check — compare your result with the expected output above.

Exercise: Fluid Heading and Readable TextHTML

Make the h1 fluid with clamp() (minimum 1.75rem, maximum 3.5rem, preferred value using rem plus vw) and limit the paragraph to a comfortable reading width of 60 characters using the ch unit. Do not use media queries.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
The heading scales smoothly between 1.75rem and 3.5rem and the paragraph is at most 60ch wide.

This is a self-check — compare your result with the expected output above.

Exercise: Full-Screen Section on MobileHTML

Make the .hero at least the full visible screen height. Use the classic vh unit first as a fallback and then the small viewport unit svh, so it works on old browsers and does not hide behind mobile toolbars.

Try it Yourself HTML
Output

Press Run to execute.

Show expected output
The hero uses min-height: 100vh followed by min-height: 100svh.

This is a self-check — compare your result with the expected output above.

Was this page helpful?