CSS 단위 완벽 가이드 - px, rem, em, vh, vw 등

CSS 단위 완벽 가이드 - px, rem, em, vh, vw 등

CSS의 모든 단위를 체계적으로 설명하는 완벽 가이드입니다. px, rem, em, vh, vw, %, ch, vmin, vmax, dvh 등 절대 단위와 상대 단위의 차이, 각각의 사용 시기, 반응형 디자인 적용법, 실용적 예제를 포함합니다.

2026년 3월 2일15분 소요

CSS 단위 완벽 가이드 - px, rem, em, vh, vw 등

CSS에서 올바른 단위를 선택하는 것은 반응형 디자인, 접근성, 유지보수성에 직접적인 영향을 미칩니다. 2026년 현재 CSS에는 수십 가지의 단위가 존재하며, 각각 고유한 특성과 적합한 사용 사례가 있습니다. 이 가이드에서는 CSS의 모든 주요 단위를 체계적으로 분류하고, 각 단위의 동작 원리, 적절한 사용 시기, 그리고 실무에서의 활용 방법을 상세히 설명합니다.

CSS 단위의 분류

CSS 단위는 크게 절대 단위상대 단위로 나뉩니다.

분류단위기준
절대 단위px, cm, mm, in, pt, pc고정된 물리적 크기
글꼴 상대 단위em, rem, ch, ex, cap, ic, lh, rlh글꼴 크기 기준
뷰포트 상대 단위vw, vh, vmin, vmax, svh, lvh, dvh뷰포트 크기 기준
컨테이너 상대 단위cqw, cqh, cqi, cqb컨테이너 크기 기준
백분율%부모 요소 기준

절대 단위

px (픽셀)

px는 CSS에서 가장 기본적이고 널리 사용되는 절대 단위입니다. 그러나 CSS의 px는 물리적 화면 픽셀과 반드시 1:1로 대응하지는 않습니다. CSS px는 "참조 픽셀"로, 96dpi 해상도에서의 1/96인치에 해당하는 각도 크기를 기준으로 합니다.

/* px 사용이 적절한 경우 */
.border {
  border: 1px solid #e0e0e0;  /* 테두리 */
}

.shadow {
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);  /* 그림자 */
}

.icon {
  width: 24px;   /* 아이콘 크기 */
  height: 24px;
}

.divider {
  height: 1px;   /* 구분선 */
  background: #ddd;
}

px 사용 권장 사례:

  • 테두리(border) 두께
  • 그림자(box-shadow) 오프셋
  • 아이콘 고정 크기
  • 1px 구분선
  • 미디어 쿼리 브레이크포인트

px 사용을 피해야 하는 경우:

  • 글꼴 크기 (접근성 문제)
  • 여백과 패딩 (반응형 어려움)
  • 너비와 높이 (유연성 부족)

기타 절대 단위

단위설명px 환산사용 상황
cm센티미터1cm = 37.8px인쇄용 스타일
mm밀리미터1mm = 3.78px인쇄용 스타일
in인치1in = 96px인쇄용 스타일
pt포인트1pt = 1.33px인쇄용 글꼴 크기
pc파이카1pc = 16px인쇄용 레이아웃
/* 인쇄 스타일시트에서의 절대 단위 사용 */
@media print {
  body {
    font-size: 12pt;
    line-height: 1.5;
  }

  .page {
    width: 210mm;   /* A4 너비 */
    height: 297mm;  /* A4 높이 */
    margin: 2cm;
  }

  h1 { font-size: 18pt; }
  h2 { font-size: 14pt; }
}

글꼴 상대 단위

rem (Root EM)

rem은 루트 요소(<html>)의 글꼴 크기를 기준으로 하는 단위입니다. 일관성과 예측 가능성이 뛰어나 2026년 현재 가장 권장되는 단위 중 하나입니다.

/* 기본 설정 */
html {
  font-size: 16px; /* 브라우저 기본값 */
  /* 또는 font-size: 100%; 으로 사용자 설정 존중 */
}

/* rem 사용 예시 */
body {
  font-size: 1rem;      /* 16px */
  line-height: 1.5;     /* 24px (1rem * 1.5) */
}

h1 {
  font-size: 2.5rem;    /* 40px */
  margin-bottom: 1rem;  /* 16px */
}

h2 {
  font-size: 2rem;      /* 32px */
  margin-bottom: 0.75rem; /* 12px */
}

h3 {
  font-size: 1.5rem;    /* 24px */
  margin-bottom: 0.5rem; /* 8px */
}

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

.container {
  max-width: 75rem;     /* 1200px */
  padding: 2rem;        /* 32px */
  margin: 0 auto;
}

.card {
  padding: 1.5rem;      /* 24px */
  border-radius: 0.5rem; /* 8px */
  margin-bottom: 1.5rem; /* 24px */
}

.button {
  padding: 0.75rem 1.5rem; /* 12px 24px */
  font-size: 1rem;         /* 16px */
  border-radius: 0.375rem; /* 6px */
}

rem의 장점:

  • 일관된 크기 체계 유지
  • 사용자의 브라우저 글꼴 크기 설정 존중 (접근성)
  • 전체 사이트의 크기를 한 곳에서 조절 가능
  • 중첩에 의한 크기 변화 없음

em (EM)

em은 현재 요소의 글꼴 크기를 기준으로 하는 단위입니다. 글꼴 크기(font-size)에 사용되면 부모 요소의 글꼴 크기를 기준으로 합니다.

/* em의 동작 방식 */
.parent {
  font-size: 20px;
}

.child {
  font-size: 0.8em;     /* 20px * 0.8 = 16px */
  padding: 1em;         /* 16px (현재 요소의 font-size 기준) */
  margin-bottom: 1.5em; /* 24px */
}

.grandchild {
  font-size: 0.8em;     /* 16px * 0.8 = 12.8px (중첩 효과!) */
}

em의 중첩 문제:

/* 문제: em이 중첩되면 크기가 누적됨 */
ul { font-size: 0.9em; }

/* 중첩된 목록 */
/* <ul>          → 0.9em = 14.4px (16px * 0.9) */
/*   <ul>        → 0.9em = 12.96px (14.4px * 0.9) */
/*     <ul>      → 0.9em = 11.66px (12.96px * 0.9) */
/*       <ul>    → 0.9em = 10.5px (점점 작아짐!) */

/* 해결: rem 사용 */
ul { font-size: 0.9rem; }
/* 모든 수준에서 동일하게 14.4px */

em이 적합한 경우:

/* 컴포넌트 내부에서 비례적 크기를 원할 때 */
.button {
  font-size: 1rem;
  padding: 0.5em 1em;      /* 글꼴 크기에 비례하는 패딩 */
  border-radius: 0.25em;   /* 글꼴 크기에 비례하는 둥글기 */
}

.button--small {
  font-size: 0.875rem;
  /* padding과 border-radius가 자동으로 비례 축소 */
}

.button--large {
  font-size: 1.25rem;
  /* padding과 border-radius가 자동으로 비례 확대 */
}

/* 아이콘이 텍스트와 비례해야 할 때 */
.icon-text {
  display: inline-flex;
  align-items: center;
  gap: 0.25em;
}

.icon-text svg {
  width: 1em;   /* 텍스트 크기와 동일 */
  height: 1em;
}

rem vs em - 언제 어떤 것을 사용할까?

속성권장 단위이유
font-sizerem중첩 문제 방지, 일관성
padding (컴포넌트 내)em글꼴 크기에 비례하는 여백
padding (레이아웃)rem일관된 간격
marginrem일관된 간격
width/max-widthrem 또는 %상황에 따라
border-radiusem 또는 px컴포넌트 내 비례 또는 고정
gaprem일관된 간격

ch (Character Width)

ch는 현재 글꼴에서 문자 "0"의 너비를 기준으로 하는 단위입니다. 텍스트 콘텐츠의 최적 너비를 설정할 때 매우 유용합니다.

/* 가독성을 위한 최적 줄 길이 설정 */
.article {
  max-width: 65ch;  /* 한 줄에 약 65자 */
  /* 서양 타이포그래피에서 권장하는 줄 길이는 45-75자 */
}

/* 입력 필드 너비를 예상 문자 수에 맞추기 */
input[type="tel"] {
  width: 15ch; /* 전화번호 길이 */
}

input[type="text"].zip-code {
  width: 7ch;  /* 우편번호 길이 */
}

input[type="text"].year {
  width: 6ch;  /* 연도 (2026) */
}

ex, cap, ic, lh, rlh

단위기준설명
ex현재 글꼴의 x-height소문자 'x'의 높이
cap현재 글꼴의 Cap Height대문자의 높이
ic현재 글꼴의 ideographic characterCJK(한중일) 문자 '水'의 너비
lh현재 요소의 line-height줄 높이
rlh루트 요소의 line-height루트 줄 높이
/* ic 단위 - 한글 텍스트에 유용 */
.korean-text {
  max-width: 35ic; /* 한글 약 35자 너비 */
}

/* lh 단위 - 줄 높이 기반 간격 */
.paragraph {
  margin-bottom: 1lh; /* 정확히 1줄 높이만큼의 여백 */
}

.drop-cap {
  float: left;
  font-size: 3lh;  /* 3줄 높이의 드롭캡 */
  line-height: 1;
}

뷰포트 상대 단위

vw와 vh

vw(viewport width)와 vh(viewport height)는 뷰포트의 크기를 기준으로 하는 단위입니다.

/* 1vw = 뷰포트 너비의 1% */
/* 1vh = 뷰포트 높이의 1% */

/* 전체 화면 히어로 섹션 */
.hero {
  width: 100vw;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* 반응형 타이포그래피 */
.hero-title {
  font-size: 5vw; /* 뷰포트 너비에 비례 */
}

/* 문제: 모바일에서 너무 작아지거나 데스크톱에서 너무 커질 수 있음 */
/* 해결: clamp() 함수 사용 */
.hero-title {
  font-size: clamp(2rem, 5vw, 4rem);
  /* 최소 2rem, 기본 5vw, 최대 4rem */
}

vmin과 vmax

/* vmin = vw와 vh 중 작은 값 */
/* vmax = vw와 vh 중 큰 값 */

/* 가로/세로 모드에 관계없이 일관된 크기 */
.square-element {
  width: 50vmin;   /* 작은 쪽 기준 50% */
  height: 50vmin;
  /* 세로 모드(portrait)에서는 너비 기준 */
  /* 가로 모드(landscape)에서는 높이 기준 */
}

/* 정사각형 카드 */
.profile-card {
  width: 80vmin;
  height: 80vmin;
  max-width: 400px;
  max-height: 400px;
}

새로운 뷰포트 단위: svh, lvh, dvh

모바일 브라우저에서 주소창의 표시/숨김에 따라 뷰포트 높이가 변하는 문제를 해결하기 위해 도입된 단위들입니다.

/*
  svh (Small Viewport Height): 주소창이 표시된 상태의 뷰포트 높이
  lvh (Large Viewport Height): 주소창이 숨겨진 상태의 뷰포트 높이
  dvh (Dynamic Viewport Height): 현재 실제 뷰포트 높이 (동적 변화)
*/

/* 모바일에서 100vh 문제 해결 */
.fullscreen-section {
  /* 기존: 모바일에서 콘텐츠가 잘릴 수 있음 */
  /* height: 100vh; */

  /* 권장: 동적 뷰포트 높이 사용 */
  height: 100dvh;

  /* 폴백 */
  height: 100vh; /* dvh 미지원 브라우저용 */
  height: 100dvh;
}

/* 최소 높이에 svh 사용 (안전한 최소 크기) */
.hero-section {
  min-height: 100svh; /* 주소창이 보여도 최소한 전체 화면 */
}

/* 사이드바에 lvh 사용 (최대 크기) */
.sidebar {
  height: 100lvh; /* 최대 뷰포트 높이에 맞춤 */
  position: fixed;
}

뷰포트 단위 비교표

단위설명모바일 주소창사용 사례
vh기존 뷰포트 높이일관성 없음데스크톱 전용
svhSmall viewport height표시 상태 기준안전한 최소 크기
lvhLarge viewport height숨김 상태 기준고정 요소
dvhDynamic viewport height실시간 반영전체 화면 섹션
vw뷰포트 너비영향 없음가로 크기
svw/lvw/dvwSmall/Large/Dynamic 너비대부분 동일특수 상황
vi인라인 축 뷰포트쓰기 방향에 따라국제화
vb블록 축 뷰포트쓰기 방향에 따라국제화

컨테이너 상대 단위

2026년에 Container Queries와 함께 도입된 컨테이너 상대 단위는 컴포넌트 기반 반응형 디자인의 핵심입니다.

/* 컨테이너 쿼리 단위 */
.card-container {
  container-type: inline-size;
  container-name: card;
}

.card-title {
  /* cqw: 컨테이너 너비의 1% */
  font-size: clamp(1rem, 4cqw, 2rem);
}

.card-body {
  /* cqi: 컨테이너 인라인 크기의 1% */
  padding: 2cqi;
}

@container card (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 1fr 2fr;
    gap: 2cqi;
  }
}
단위설명
cqw쿼리 컨테이너 너비의 1%
cqh쿼리 컨테이너 높이의 1%
cqi쿼리 컨테이너 인라인 크기의 1%
cqb쿼리 컨테이너 블록 크기의 1%
cqmincqi와 cqb 중 작은 값
cqmaxcqi와 cqb 중 큰 값

백분율 (%)

백분율은 부모 요소의 해당 속성을 기준으로 합니다. 단, 어떤 속성에 사용되느냐에 따라 기준이 달라집니다.

/* 백분율의 기준 */

/* width: 부모의 width 기준 */
.child {
  width: 50%; /* 부모 너비의 50% */
}

/* height: 부모의 height 기준 (부모에 높이가 지정되어야 함) */
.child {
  height: 50%; /* 부모 높이의 50% */
}

/* padding, margin: 부모의 WIDTH 기준 (상하 패딩/마진도!) */
.child {
  padding: 10%; /* 상하좌우 모두 부모 너비의 10% */
  /* padding-top: 10%도 부모 너비의 10% (높이가 아님!) */
}

/* font-size: 부모의 font-size 기준 */
.child {
  font-size: 120%; /* 부모 글꼴 크기의 120% */
}

/* line-height: 요소 자신의 font-size 기준 */
.child {
  line-height: 150%; /* 자신의 font-size의 150% */
}

/* transform: translate: 요소 자신의 크기 기준 */
.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* 자기 자신 너비의 50%, 높이의 50%만큼 이동 */
}

반응형 종횡비 유지 (padding 트릭)

/* 16:9 비율 유지 (옛날 방식) */
.video-wrapper {
  position: relative;
  width: 100%;
  padding-top: 56.25%; /* 9/16 * 100 = 56.25% */
}

.video-wrapper iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

/* 현대적 방법: aspect-ratio 속성 사용 */
.video-wrapper {
  width: 100%;
  aspect-ratio: 16 / 9;
}

반응형 디자인에서의 단위 활용

clamp() 함수

clamp(최소값, 선호값, 최대값)은 반응형 디자인에서 가장 강력한 CSS 함수입니다.

/* 반응형 타이포그래피 */
.heading {
  font-size: clamp(1.5rem, 2vw + 1rem, 3rem);
  /* 최소 1.5rem (24px) */
  /* 선호 2vw + 1rem (뷰포트에 비례) */
  /* 최대 3rem (48px) */
}

/* 반응형 여백 */
.section {
  padding: clamp(1rem, 5vw, 4rem);
  /* 작은 화면: 1rem */
  /* 중간 화면: 5vw */
  /* 큰 화면: 4rem */
}

/* 반응형 그리드 간격 */
.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr));
  gap: clamp(1rem, 2vw, 2rem);
}

/* 반응형 컨테이너 */
.container {
  width: min(90%, 75rem);
  margin-inline: auto;
  padding-inline: clamp(1rem, 3vw, 2rem);
}

완전한 반응형 타이포그래피 시스템

:root {
  /* 유동적 타입 스케일 */
  --step--2: clamp(0.6944rem, 0.6597rem + 0.1736vw, 0.8rem);
  --step--1: clamp(0.8333rem, 0.7754rem + 0.2899vw, 1rem);
  --step-0: clamp(1rem, 0.9091rem + 0.4545vw, 1.25rem);
  --step-1: clamp(1.2rem, 1.0636rem + 0.6818vw, 1.5625rem);
  --step-2: clamp(1.44rem, 1.2418rem + 0.9909vw, 1.9531rem);
  --step-3: clamp(1.728rem, 1.4473rem + 1.4036vw, 2.4414rem);
  --step-4: clamp(2.0736rem, 1.6845rem + 1.9455vw, 3.0518rem);
  --step-5: clamp(2.4883rem, 1.9582rem + 2.6505vw, 3.8147rem);

  /* 유동적 간격 스케일 */
  --space-3xs: clamp(0.25rem, 0.2045rem + 0.2273vw, 0.375rem);
  --space-2xs: clamp(0.5rem, 0.4545rem + 0.2273vw, 0.625rem);
  --space-xs: clamp(0.75rem, 0.6591rem + 0.4545vw, 1rem);
  --space-s: clamp(1rem, 0.9091rem + 0.4545vw, 1.25rem);
  --space-m: clamp(1.5rem, 1.3636rem + 0.6818vw, 1.875rem);
  --space-l: clamp(2rem, 1.8182rem + 0.9091vw, 2.5rem);
  --space-xl: clamp(3rem, 2.7273rem + 1.3636vw, 3.75rem);
  --space-2xl: clamp(4rem, 3.6364rem + 1.8182vw, 5rem);
  --space-3xl: clamp(6rem, 5.4545rem + 2.7273vw, 7.5rem);
}

/* 사용 */
body {
  font-size: var(--step-0);
  line-height: 1.6;
}

h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-3); }
h4 { font-size: var(--step-2); }
h5 { font-size: var(--step-1); }

.section {
  padding-block: var(--space-xl);
}

.stack > * + * {
  margin-top: var(--space-m);
}

미디어 쿼리와 단위

/* 미디어 쿼리에서는 em 사용 권장 */
/* em을 사용하면 사용자의 글꼴 크기 설정을 존중 */

/* 권장 */
@media (min-width: 48em) {  /* 768px at 16px base */
  .container {
    padding: 2rem;
  }
}

@media (min-width: 64em) {  /* 1024px at 16px base */
  .container {
    padding: 3rem;
  }
}

/* 비권장 (사용자의 글꼴 크기 설정 무시) */
@media (min-width: 768px) {
  /* ... */
}

단위 사용 모범 사례

접근성을 고려한 단위 선택

/* 접근성 최우선 원칙 */

/* 1. 글꼴 크기: 항상 rem 사용 */
html {
  /* px 대신 % 사용하여 사용자 설정 존중 */
  font-size: 100%; /* = 16px (기본값) */
}

/* 절대 font-size: px 사용하지 마세요! */
/* BAD: font-size: 14px; */
/* GOOD: font-size: 0.875rem; */

/* 2. 줄 높이: 단위 없는 숫자 사용 */
p {
  line-height: 1.6; /* 단위 없음 - 글꼴 크기에 비례 */
  /* BAD: line-height: 24px; */
  /* BAD: line-height: 1.5em; (상속 시 문제) */
}

/* 3. 최소 터치 타겟 크기 */
button, a {
  min-height: 44px;  /* WCAG 최소 터치 타겟 */
  min-width: 44px;
  /* 또는 */
  min-height: 2.75rem;
  padding: 0.5rem 1rem;
}

/* 4. 포커스 표시 */
:focus-visible {
  outline: 3px solid #4A90D9;
  outline-offset: 2px;
  /* 포커스 아웃라인은 px로 일관된 두께 유지 */
}

속성별 권장 단위 총정리

CSS 속성권장 단위예시이유
font-sizerem1.125rem접근성, 일관성
line-height단위 없음1.6상속 시 비례 유지
padding (컴포넌트)em0.5em 1em글꼴에 비례
padding (레이아웃)rem2rem일관된 간격
marginrem1.5rem일관된 간격
width%, rem, vwmin(90%, 75rem)반응형
heightauto, dvh, rem100dvh콘텐츠에 맞춤
max-widthrem, ch65ch가독성
borderpx1px solid고정 크기
border-radiuspx, em, %0.5rem상황에 따라
box-shadowpx0 2px 4px고정 크기
gaprem, clamp()clamp(1rem, 2vw, 2rem)반응형 간격
미디어 쿼리em48em접근성

실전 레이아웃 예제

/* 완전한 반응형 레이아웃 시스템 */

/* 기본 설정 */
html {
  font-size: 100%;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
}

/* 컨테이너 */
.container {
  width: min(90%, 75rem);
  margin-inline: auto;
}

/* 그리드 시스템 */
.grid {
  display: grid;
  gap: clamp(1rem, 2vw, 2rem);
}

.grid--2-col {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 25rem), 1fr));
}

.grid--3-col {
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}

/* 카드 컴포넌트 */
.card {
  container-type: inline-size;
  container-name: card;
  padding: clamp(1rem, 3cqi, 2rem);
  border-radius: 0.5rem;
  border: 1px solid #e5e7eb;
}

.card__title {
  font-size: clamp(1.125rem, 3cqi, 1.5rem);
  margin-bottom: 0.5em;
}

.card__text {
  font-size: var(--step-0);
  line-height: 1.6;
  max-width: 65ch;
}

/* 히어로 섹션 */
.hero {
  min-height: 100svh;
  padding: var(--space-xl) var(--space-m);
  display: grid;
  place-items: center;
}

.hero__title {
  font-size: clamp(2rem, 5vw + 1rem, 5rem);
  line-height: 1.1;
}

.hero__subtitle {
  font-size: clamp(1rem, 2vw, 1.5rem);
  margin-top: var(--space-s);
  max-width: 50ch;
}

관련 도구 활용

CSS 작업을 할 때 유용한 온라인 도구들입니다:

결론

CSS 단위의 올바른 선택은 반응형 디자인, 접근성, 유지보수성의 토대입니다. 2026년 기준으로 핵심 원칙을 정리하면:

  1. 글꼴 크기에는 rem을 사용하세요 - 접근성과 일관성을 보장합니다
  2. 컴포넌트 내부 간격에는 em을 활용하세요 - 글꼴 크기에 비례하는 디자인을 만듭니다
  3. 뷰포트 단위는 dvh/svh/lvh를 사용하세요 - 모바일 주소창 문제를 해결합니다
  4. clamp() 함수를 적극 활용하세요 - 미디어 쿼리 없이 유동적인 크기를 구현합니다
  5. 테두리와 그림자에는 px를 사용하세요 - 시각적 일관성을 유지합니다
  6. line-height는 단위 없이 사용하세요 - 상속 시 올바르게 비례합니다
  7. 컨테이너 쿼리 단위(cqi 등)를 활용하세요 - 컴포넌트 기반 반응형 디자인을 구현합니다

각 단위의 특성을 이해하고 적절한 곳에 사용하면, 다양한 기기와 사용자 환경에서도 일관되고 접근성 높은 웹 경험을 제공할 수 있습니다. 이 가이드에서 소개한 원칙과 예제를 참고하여 프로젝트에 적용해 보세요.

관련 글