CSS Units: px, rem, em, %, vw, vh and dvh
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,emand%are relative to - Viewport units:
vw,vh,vmin,vmaxand the dynamic variantssvh,lvh,dvh - Other useful units:
ch,lh,fr - Fluid sizing with
clamp(),min()andmax() - 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
remfor font sizes, page spacing and media queries. It is predictable. - Use
emfor 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 asauto.font-size: percent of the parent font size.top,leftand similar on positioned elements: percent of the containing block size.transform: translate(): percent of the element own size, which is whytranslate(-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 examplegrid-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, orclamp()with rem and vw. - Padding and margin:
remfor layout spacing,emfor component internals. - Borders, shadows, hairlines:
px. - Width of layout blocks:
%,fr,min(), ormax-widthinchorrem. - Full-screen sections:
svh,dvhwith avhfallback. - Media queries:
emorrem, so breakpoints respect user font size.
Common Mistakes
- Setting
html { font-size: 16px; }in px and blocking user scaling. - Using
100vwfor full width and getting a horizontal scrollbar. - Using
100vhon mobile and losing content behind the browser toolbar. - Expecting
height: 50%to work when the parent has no explicit height. - Nesting
emfont sizes and ending up with tiny or huge text. - Using pure
vwfor 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
pxis fixed,remfollows the root,emfollows the element,%follows the containing block.- Viewport units are
vw,vh,vmin,vmax. On mobile prefersvhordvhovervh. - Avoid
100vwfor layout width. - Use
chfor readable line length andclamp()for fluid typography. - Keep the root font size in relative units for accessibility.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
Press Run to execute.
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.
Press Run to execute.
Show expected output
1.5
1
24This is a self-check — compare your result with the expected output above.
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.
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.
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.
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?