Question
Why should I use em rather than px when defining sizes and spacing in CSS stylesheets? Is there a practical example that shows the benefit of using em units?
Short Answer
You will learn the difference between CSS px and em units, how em values inherit and scale from font sizes, and when rem is a clearer alternative. By the end, you will be able to choose units intentionally for text, spacing, and reusable components.
Concept
A CSS unit tells the browser how to interpret a measurement such as 16px or 1em.
pxis a CSS pixel: a fixed unit in the CSS layout system.emis a relative unit: for most properties,1emequals the element's computedfont-size.
For example, if a button has font-size: 20px, then:
button {
font-size: 20px;
padding: 0.5em 1em;
}
Its vertical padding is 10px and horizontal padding is 20px. If the button's font size changes, its padding changes proportionally.
This relationship is useful because many component measurements should follow the text size. A larger button label usually needs more surrounding space; em makes that happen automatically.
However, em is not automatically better than px in every situation. Use em when a value should scale with the component's text. Use px when a stable, precise size is appropriate, such as a 1px border. In modern CSS, rem is often preferred for site-wide typography and spacing because it scales from the root font size without being affected by nested elements.
Mental Model
Think of px as writing an exact measurement on a blueprint: “make this gap 16 units.” It stays 16 CSS pixels regardless of the text nearby.
Think of em as saying: “make this gap as wide as the current letter size.” If the component's text becomes larger, the gap grows with it. If the text becomes smaller, the gap shrinks too.
A component using em is like clothing sized relative to the person wearing it. A component using px is like clothing with one fixed measurement.
Syntax and Examples
The basic syntax is a number followed by a unit:
.element {
font-size: 1.25em;
padding: 0.5em 1em;
margin-bottom: 1.5em;
border: 1px solid #333;
}
For most CSS properties:
1em = the element's computed font size
Example: a scalable button
<button class="button button--normal">Save</button>
<button class="button button--large">Save</button>
.button {
font-size: 1rem;
padding: 0.5em 1em;
border: 1px solid #1d4ed8;
border-radius: 0.25em;
background: #2563eb;
color: white;
}
.button--large {
font-size: 1.5rem;
}
The large button changes only font-size. Because the padding and border radius use em, they also become larger:
- Normal button:
font-sizeis1rem; padding is0.5emby1emrelative to that size. - Large button:
font-sizeis1.5rem; the same padding values become 1.5 times larger.
The 1px border remains thin and consistent, which is often desirable for borders.
Step by Step Execution
Consider this CSS:
.card {
font-size: 16px;
padding: 1em;
}
.card--large {
font-size: 24px;
}
And this HTML:
<article class="card">Regular card</article>
<article class="card card--large">Large card</article>
Step by step:
- The first card has
font-size: 16px. - Its
padding: 1emis calculated from its own font size. - Therefore, its padding is
16pxon all sides. - The second card has both classes, but
.card--largesets its font size to24px. - Its
padding: 1emis recalculated using24px. - Therefore, its padding becomes
24pxon all sides.
One relative padding rule keeps the visual proportions of both cards consistent.
Real World Use Cases
em is useful when a measurement belongs to a text-based component and should grow with that component.
- Buttons and links: Scale padding and border radius with the label's font size.
- Badges and tags: Keep compact labels proportionate when different size variants are used.
- Alerts and callouts: Let padding scale if the alert has a larger text style.
- Icons next to text: Use sizes such as
1emso an icon follows the text size. - Text spacing: Use margins such as
margin-bottom: 0.75emwhen the gap should match the text being separated.
Example of an icon that follows text size:
.button-icon {
width: 1em;
height: 1em;
margin-right: 0.4em;
}
If the button's font size changes, the icon and its gap change too.
Real Codebase Usage
In real projects, developers typically choose units based on what should control the size.
Component-relative sizing with em
A reusable component can expose size variants by changing only its font size:
.tag {
display: inline-block;
font-size: 0.875rem;
padding: 0.25em 0.6em;
border-radius: 999px;
}
.tag--large {
font-size: 1.125rem;
}
Root-relative tokens with rem
Many design systems define a spacing scale in rem so values are consistent across the application:
:root {
--space-1: 0.25rem;
--space-2: 0.5rem;
--space-4: 1rem;
--space-6: 1.5rem;
}
.page-section {
padding: var(--space-6);
}
Stable visual details with px
Pixels remain common for details that should not scale with text:
.input {
border: 1px solid #9ca3af;
box-shadow: 0 1px 2px rgb(0 0 0 / 0.08);
}
A practical pattern is: use rem for global type and layout scales, em inside components that should scale with their own text, and px for thin borders or similarly precise details.
Common Mistakes
Assuming em always uses the root font size
For most properties, em uses the current element's computed font-size, not the root font size.
.parent {
font-size: 20px;
}
.child {
padding: 1em; /* 20px, not necessarily 16px */
}
Use rem when you specifically want the root font size as the reference.
Unintended compounding in nested font sizes
This can make deeply nested content unexpectedly large:
/* Usually a bad idea for nested content */
.panel {
font-size: 1.2em;
}
If a .panel appears inside another .panel, the inner size becomes 1.2 times the outer size again. Prefer rem for predictable type scales:
.panel {
font-size: 1.2rem;
}
Using only em for every measurement
A 1px border is often clearer than an em border because borders usually should remain visually thin at all text sizes.
/* Often too thick when font size increases */
.card {
border: 0.1em solid #444;
}
Treating CSS pixels as physical screen pixels
A CSS px is not guaranteed to equal one physical pixel on a device. Browsers account for display density and zoom. px is still a useful CSS unit; it is simply not the same thing as a hardware pixel.
Forgetting the special case for font-size
When setting font-size itself in em, the value is relative to the parent's font size. For example:
.parent {
font-size: 20px;
}
.child {
font-size: 1.5em; /* 30px */
}
Comparisons
| Unit | Relative to | Best for | Watch out for |
|---|---|---|---|
px | CSS pixel | Borders, small fixed details, exact visual adjustments | Does not scale with surrounding text |
em | Current element's font size for most properties | Component padding, icon size, component border radius | Nested font sizes can compound |
rem | Root element's font size | Global typography, spacing scales, predictable layouts | Does not automatically scale with a component variant |
% | Usually a parent-related dimension, depending on the property | Widths and fluid layout relationships | Its reference changes by property |
em versus rem
.card {
font-size: 1.25rem;
padding: 1em;
}
font-size: 1.25remis based on the root font size, so it is predictable across nesting.padding: 1emis based on the card's own font size, so it remains proportional to the card text.
This combination is common and avoids many em nesting surprises.
Cheat Sheet
/* 1em equals this element's computed font size for most properties */
.component {
font-size: 1rem;
padding: 0.5em 1em;
border-radius: 0.25em;
}
/* An icon that follows surrounding text */
.icon {
width: 1em;
height: 1em;
}
/* Root-relative size */
.heading {
font-size: 2rem;
}
/* Stable thin detail */
.box {
border: 1px solid #666;
}
- Use
emwhen a measurement should scale with the component's text. - For most properties,
1emis the element's own computed font size. - For
font-size, anemvalue is based on the parent's font size. - Nested
emfont sizes can compound. - Use
remfor root-based, predictable scales. - Use
pxfreely for borders and precise visual details when scaling is not needed.
FAQ
Should I always use em instead of px in CSS?
No. Use em for values that should scale with a component's text. px is appropriate for stable details such as thin borders, and rem is often better for global sizing.
What does 1em equal in CSS?
For most properties, 1em equals the element's computed font-size. If that size is 18px, then 1em is 18px.
Why can nested em font sizes become too large?
An em font size is calculated from the parent's font size. If nested elements repeatedly use font-size: 1.2em, each level grows relative to the previous level.
Is rem better than em?
Neither is universally better. Use rem for predictable root-based values. Use em when internal component values should follow that component's text size.
Does using em improve accessibility?
Relative units can help components preserve their proportions when text sizing changes. Accessibility also depends on responsive layout, readable text, semantic HTML, and testing at browser zoom.
Should borders use em?
Usually no. A 1px border is common because it stays visually thin when text size changes. Use em borders only when the border thickness intentionally belongs to the component's scale.
Is a CSS px a physical device pixel?
Not necessarily. A CSS pixel is a unit used by the browser's layout system. High-density screens can use multiple physical pixels to render one CSS pixel.
Mini Project
Description
Create a small set of reusable buttons with normal, large, and small variants. The project demonstrates how em can make a button's padding, corner radius, and icon scale automatically when only the button's font size changes.
Goal
Build button variants that keep their internal spacing proportional to their text size.
Requirements
- Create normal, small, and large button examples.
- Use a shared base button class.
- Use
emfor the button padding and border radius. - Change each variant primarily through
font-size. - Include an icon that scales with the button text.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
Apply CSS to an iframe: Same-Origin Styling in HTML
Learn why parent-page CSS does not style iframe content, how same-origin rules work, and practical ways to style embedded pages safely.
Apply Multiple CSS Transforms: rotate() and translate()
Learn how to combine multiple CSS transform functions such as rotate() and translate(), understand transform order, and avoid overwritten rules.