
CSS 단위 변환기: 더 이상 단위 계산으로 머리 아프지 마세요
📷 Christina Morillo / PexelsCSS 단위 변환기: 더 이상 단위 계산으로 머리 아프지 마세요
px, rem, em, vh, vw를 언제, 왜 쓰는지 — 기준 폰트 크기 개념부터 em 상속 함정까지, CSS 단위를 실무에서 제대로 쓰는 방법을 정리했습니다.
디자이너가 24px라고 했을 때 벌어지는 일
Figma 파일을 받았습니다. 모든 측정값이 픽셀로 표기되어 있습니다 — 24px 폰트, 16px 패딩, 48px 마진. 그 값을 그대로 CSS에 붙여 넣습니다. 내 컴퓨터에서는 완벽하게 보입니다.
그런데 브라우저 기본 폰트 크기를 20px로 늘려놓은 동료가 페이지를 열면 어떻게 될까요? 24px 헤딩은 정확히 24px로 고정된 채, 주변의 다른 요소들은 비율에 맞춰 커집니다. 디자인 시스템이 아니라 각 요소가 제멋대로 사이즈가 맞지 않는 상태가 됩니다.
이건 드문 엣지 케이스가 아닙니다. 모든 값을 절대값으로 입력했을 때 생기는 필연적인 결과입니다. 해결책은 어떤 단위를 언제 써야 하는지 이해하고, 단위 간 변환을 빠르게 할 수 있는 도구를 갖추는 것입니다.
CSS 단위 변환기가 바로 그 도구입니다. 하지만 도구 소개 전에 먼저 개념부터 제대로 잡아봅시다.
CSS 단위 용어 정리
CSS에는 생각보다 많은 단위가 있습니다. 각각이 무엇을 의미하는지 정리해 보겠습니다.
px — 픽셀
대부분이 CSS를 처음 배울 때 만나는 기본 단위입니다. 1px는 표준 해상도 화면에서 화소 하나에 해당합니다. 고해상도(레티나) 디스플레이에서는 기기 픽셀 비율에 따라 물리적으로 2~3픽셀로 렌더링되지만, 그 계산은 브라우저가 알아서 처리합니다.
핵심 특성: px는 고정입니다. 사용자 설정, 부모 요소, 문서의 어떤 것에도 반응하지 않습니다. 1px 테두리가 항상 1px여야 할 때는 딱 맞는 단위지만, 사용자가 더 큰 텍스트를 원할 때는 문제가 됩니다.
rem — 루트 Em
rem은 "루트 em"의 약자입니다. 1rem은 <html> 요소의 폰트 크기와 같습니다 — 대부분의 브라우저에서 기본값은 16px이지만, 사용자가 브라우저에서 설정한 기본 폰트 크기를 그대로 반영합니다.
사용자가 브라우저 기본 폰트 크기를 20px로 설정했다면, 페이지의 모든 1rem은 20px가 됩니다. 레이아웃 전체가 비례적으로 확대됩니다. 접근성 측면에서 큰 장점입니다.
1.5rem = 16px 기준일 때 24px. 기준이 달라져도 비율은 일정하고 예측 가능합니다.
em — Em (조심해야 하는 단위)
em은 rem과 비슷하지만 현재 요소의 폰트 크기를 기준으로 합니다. 중첩이 없으면 괜찮지만, 요소를 중첩하기 시작하면 상황이 복잡해집니다.
font-size: 1.2em인 요소가 마찬가지로 font-size: 1.2em인 부모 안에 있으면, 자식 요소는 1.2 × 1.2 = 1.44em이 됩니다. 세 단계 중첩이면 1.728em. 이것이 em 상속 함정입니다 — 아래에서 자세히 다룹니다.
vh / vw — 뷰포트 높이와 너비
1vh = 브라우저 뷰포트 높이의 1%. 1vw = 뷰포트 너비의 1%. 전체 화면 섹션과 화면 크기에 따른 유동적인 타이포그래피에 매우 유용합니다.
주의사항: 모바일에서는 브라우저 주소 표시줄이 스크롤에 따라 나타났다 사라지면서 뷰포트 높이가 변합니다. 그래서 100vh 요소가 높이가 갑자기 바뀌는 현상이 생깁니다. CSS 워킹 그룹이 이 문제를 해결하기 위해 dvh(동적 뷰포트 높이)를 추가했지만 아직 브라우저 지원이 따라가는 중입니다.
% — 퍼센트
%는 숙련된 개발자도 헷갈리는 방식으로 컨텍스트에 의존합니다. width: 50%는 부모 너비의 50%. font-size: 120%는 상속된 폰트 크기의 120%(em처럼 동작). margin-top: 10%는 포함 블록의 높이가 아니라 너비의 10% — 처음 만나면 대부분 놀라는 부분입니다.
pt, cm, mm — 인쇄 단위
물리적 측정 단위입니다. 웹에서는 거의 인쇄 스타일시트에서만 씁니다. 1pt = 1인치의 1/72. 일반 웹 스타일에서는 쓸 일이 거의 없습니다.
기준 폰트 크기 개념 이해하기
많은 튜토리얼이 건너뛰는 부분: 브라우저는 단순히 기본 폰트 크기를 갖고 있는 게 아니라 사용자가 변경할 수 있는 기본 폰트 크기를 갖고 있습니다. Chrome, Firefox, Safari 모두 환경설정에서 이 값을 바꿀 수 있습니다. 역사적으로 브라우저 기본값은 16px이고, 대부분의 변환표가 이를 기준으로 합니다.
이 기준에서 나오는 계산:
1rem = 16px (브라우저 기본값 기준)
0.75rem = 12px
1.25rem = 20px
1.5rem = 24px
2rem = 32px
일부 디자인 시스템은 html { font-size: 62.5%; }를 사용해 1rem = 10px로 만들어 계산을 쉽게 합니다(1.6rem = 16px). 이 방법이 편리하기는 하지만 브라우저 기본값을 가정하는 컴포넌트에서 조용히 문제를 일으키고, 접근성 개선 효과도 없습니다. 이 트릭을 쓰는 코드베이스를 물려받았다면 초반에 확인해 두세요.
결론: rem은 항상 하나의 값에 고정되어 있기 때문에 예측 가능합니다. 그래서 대부분의 타이포그래피와 간격 결정에 rem이 올바른 선택입니다.
어떤 상황에 어떤 단위를?
폰트 크기 → rem
항상입니다. font-size를 px로 설정할 이유는 거의 없습니다. 사용자가 브라우저 기본 폰트를 변경했을 때 텍스트 계층 구조가 그대로 유지되어야 합니다. rem이 이걸 자동으로 처리합니다.
body { font-size: 1rem; } /* 기본값에서 16px */
h1 { font-size: 2.5rem; } /* 기본값에서 40px */
h2 { font-size: 2rem; } /* 기본값에서 32px */
small { font-size: 0.875rem; } /* 기본값에서 14px */
컴포넌트 간격 → rem 또는 px (의도에 따라)
패딩과 마진은 판단이 필요합니다. 텍스트와 함께 커져야 하는 간격(예: 버튼의 상하 패딩)이면 rem을 쓰세요. 고정된 시각적 간격(예: 아이콘과 텍스트 사이)이라면 px도 괜찮습니다.
.button {
padding: 0.75rem 1.5rem; /* 폰트 크기에 비례 */
border: 1px solid currentColor; /* 항상 1px */
border-radius: 4px; /* 고정 시각 속성 */
}
전체 화면 및 뷰포트 기반 레이아웃 → vh/vw
히어로 섹션, 화면의 일정 비율을 차지해야 하는 모달, 스티키 사이드바 등은 뷰포트 단위를 씁니다.
.hero {
min-height: 100vh;
width: 100vw;
}
모바일 주소 표시줄 문제를 기억하세요. 모바일에서 완벽한 전체 화면이 중요하다면 dvh를 검토해 보세요.
인쇄 스타일 → pt/cm/mm
@media print 섹션에서는 물리적 단위로 전환하세요. 프린터는 인치와 포인트 단위를 기준으로 합니다.
em 상속 함정 (실제 예시)
왜 em이 폰트 크기에서 위험해지는지 직접 보여드리겠습니다.
카드 컴포넌트를 만든다고 가정합니다:
.card { font-size: 1.2em; }
.card .meta { font-size: 0.9em; }
.card .meta .timestamp { font-size: 0.85em; }
.card의 부모가 font-size: 16px라면 실제 값은:
.card→ 16px × 1.2 = 19.2px.card .meta→ 19.2px × 0.9 = 17.28px.card .meta .timestamp→ 17.28px × 0.85 = 14.688px
의도와 전혀 다른 결과입니다. 계산기 없이는 디버깅도 어렵습니다.
같은 스타일을 rem으로 바꾸면:
.card { font-size: 1.2rem; }
.card .meta { font-size: 0.9rem; }
.card .meta .timestamp { font-size: 0.85rem; }
각 값이 루트 폰트 크기에 직접 대응됩니다. 복잡한 계산 없이 예측 가능합니다.
em이 정말 유용한 경우: line-height: 1.5em처럼 요소 자신의 폰트 크기에 비례해야 하는 경우, 또는 버튼의 padding: 0.5em처럼 버튼 폰트가 바뀔 때 패딩도 같이 변해야 할 때입니다.
변환 참조표 (16px 기준)
| px | rem | em (상속 없음) | pt |
|---|---|---|---|
| 10px | 0.625rem | 0.625em | 7.5pt |
| 12px | 0.75rem | 0.75em | 9pt |
| 14px | 0.875rem | 0.875em | 10.5pt |
| 16px | 1rem | 1em | 12pt |
| 18px | 1.125rem | 1.125em | 13.5pt |
| 20px | 1.25rem | 1.25em | 15pt |
| 24px | 1.5rem | 1.5em | 18pt |
| 32px | 2rem | 2em | 24pt |
| 40px | 2.5rem | 2.5em | 30pt |
| 48px | 3rem | 3em | 36pt |
이 표는 1rem = 16px 기준입니다. 루트 폰트 크기가 다르면 모든 변환이 달라집니다. 그래서 도구가 필요합니다.
CSS 단위 변환기 사용법
CSS 단위 변환기는 정적인 표가 해결하지 못하는 문제를 다룹니다: 기준 폰트 크기가 16px가 아닐 때, 또는 뷰포트 크기가 특정 값일 때의 정확한 변환이 필요할 때입니다.
이 도구로 할 수 있는 것:
- 숫자값 입력
- 소스 단위 선택 (px, rem, em, vh, vw, %, pt, cm, mm)
- 기준 폰트 크기 설정 (기본 16px, 변경 가능)
- 뷰포트 크기 설정 (vh/vw 변환용)
- 모든 동등한 값 즉시 확인
Figma 스펙(항상 px 기준)을 디자인 시스템용 rem 값으로 변환할 때 이 워크플로를 씁니다. px 값 입력 → rem 값 확인, 끝. DevTools에서 레이아웃이 약간 틀어졌을 때 px 값을 입력해 rem과 비교하는 데도 유용합니다.
Tailwind CSS 사용자를 위한 팁
Tailwind 문서는 px 값을 보여주지만 실제로는 rem을 사용합니다.
Tailwind는 내부적으로 rem을 씁니다. text-base는 1rem, text-lg는 1.125rem, text-xl은 1.25rem입니다. Tailwind 클래스에 맞춰 font-size를 직접 지정해야 한다면 px 숫자가 아닌 rem을 쓰세요.
간격 스케일도 rem입니다. p-4는 1rem(기본값에서 16px). p-8은 2rem(32px). 디자이너가 "패딩 24px"라고 하면 Tailwind에서는 p-6(1.5rem)입니다. 특정 디자인 값을 Tailwind 클래스에 매핑할 때 변환기가 유용합니다.
커스텀 기준 폰트 크기도 Tailwind와 함께 잘 동작합니다. html { font-size: 18px }로 설정하면 모든 Tailwind rem 값이 자동으로 재계산됩니다. 변환기에서 기준값을 18px로 설정해 확인해 보세요.
정리
CSS 단위 선택은 사소한 문제가 아닙니다. 일부 사용자에게 레이아웃이 깨지느냐, 아니면 우아하게 적응하느냐의 차이입니다.
- px — 테두리, 아웃라인처럼 절대 바뀌면 안 되는 속성
- rem — 폰트 크기와 확장 가능한 간격 (접근성의 기본)
- em — 요소 자신의 크기에 비례해야 할 때만 제한적으로
- vh/vw — 뷰포트 기반 레이아웃, 모바일 전체 화면은 dvh 검토
- % — 컨테이너 상대 크기 (margin의 너비 기반 동작 유의)
- pt/cm/mm — 인쇄 스타일시트에서만
CSS 단위 변환기를 북마크해 두면 단위 변환에 쓰는 시간을 아껴 실제 개발에 집중할 수 있습니다.