Back to Blog
By AriesZhou · · 3 min read

CSS: How to Choose Between rem, em, and px

CSS

Have you ever run into this? Font sizes look perfect on a small screen but become absurdly large on a big one. Or you change the root font size and the entire page layout falls apart. These issues all come down to your choice of CSS units. CSS units seem simple, but using the wrong one in the wrong place can make responsive design painful.

TLDR

ScenarioRecommendation
Font sizerem
Layout width%, vw
Spacing (margin/padding)rem / em
Borders, shadowspx
Full-screen hero sectionvh

Relative Units: rem vs em

rem: Relative to the Root Element

html {
  font-size: 16px;  /* 默认值 */
}

h1 {
  font-size: 2rem;  /* 2 * 16px = 32px */
}

p {
  font-size: 1rem;  /* 1 * 16px = 16px */
}

Why recommend rem?

  1. Change one place, apply globally

    /* 用户设置了大字号,rem 自动响应 */
    html {
      font-size: 18px;  /* 所有 rem 都自动变大 */
    }
  2. No side effects

    /* 嵌套多层时,em 会逐层累积,rem 不受影响 */
    .parent {
      font-size: 2em;  /* 子元素会是 2 * 2em = 4em */
    }
    .child {
      font-size: 1rem;  /* 永远是 16px,不受父元素影响 */
    }

em: Relative to the Parent Element

.parent {
  font-size: 20px;
}

.child {
  padding: 1em;  /* 1 * 20px = 20px */
  margin: 2em;   /* 2 * 20px = 40px */
}

Scenarios where em fits well

/* 按钮:保持和文字成比例的内边距 */
.btn {
  padding: 0.5em 1em;
  /* 字体大 → 按钮大,字体小 → 按钮小 */
}

Percentage: %

Relative to the parent element’s dimensions.

.container {
  width: 80%;  /* 父元素宽度的 80% */
}

.child {
  width: 50%;  /* container 宽度的 50% */
}

Common applications

/* 居中布局 */
.box {
  width: 80%;
  margin: 0 auto;
}

/* 响应式图片 */
img {
  max-width: 100%;
  height: auto;
}

Viewport Units: vw / vh

Relative to the browser’s visible area.

/* 全屏 hero 区 */
.hero {
  height: 100vh;  /* 100% 视口高度 */
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 响应式文字 */
h1 {
  font-size: 5vw;  /* 随视口宽度缩放 */
}

Practical tip: clamp the range

/* vw 太大时会失控,用 clamp 限制 */
h1 {
  font-size: clamp(24px, 5vw, 64px);
  /* 最小 24px,最大 64px,中间随 vw 变化 */
}

Absolute Unit: px

A fixed value that does not change relative to anything.

Suitable scenarios

/* 边框 - 像素级精确 */
.card {
  border: 1px solid #ddd;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

/* 分割线 */
.divider {
  height: 1px;
  background: #eee;
}

/* 小间距微调 */
.icon {
  margin-right: 4px;
}

Use px for fonts with caution

/* ❌ 响应式差,小屏手机上显得太大 */
body {
  font-size: 16px;
}

/* ✅ 响应式好,尊重用户设置 */
body {
  font-size: 1rem;
}

Selection

Typical scenario comparison

ScenarioRecommendationReason
Page root font sizeremUnified control
Text inside componentsremScales correctly even in standalone components
Button paddingemKeeps proportion with text
Card width%Adapts to container
Modal centeringflex / gridMore reliable
Hero full screenvhDirectly fills the viewport
Fixed headerpx or remNo need for responsiveness

Complete example

:root {
  /* 统一管理字号 */
  --font-size-base: 1rem;      /* 16px */
  --font-size-lg: 1.25rem;     /* 20px */
  --font-size-xl: 1.5rem;       /* 24px */
  --font-size-2xl: 2rem;        /* 32px */
}

body {
  font-size: var(--font-size-base);
  line-height: 1.6;
}

h1 {
  font-size: var(--font-size-2xl);
}

.card {
  padding: 1.5rem;
  margin-bottom: 1rem;
}

.btn {
  padding: 0.5em 1.5em;
  border: 1px solid currentColor;
}

Summary

  • Use rem for font sizes: easy to maintain and respects user preferences
  • Use rem/em for spacing: keeps proportion with font size
  • Use % / vw for layout: responsive and adaptive
  • Use px for borders and shadows: precise control
  • Use vw/vh for full-screen sections: simple and direct

Remember: the core of responsive design is “proportion” rather than “fixed values.” Using relative units well makes page scaling feel more natural.