~ / posts / developer
💻 개발자

px rem em 차이, 언제 무엇을 쓰나와 px→rem 변환표 총정리

CSS를 쓰다 보면 font-size: 14px 로 쓸지 0.875rem 으로 쓸지, 버튼 패딩은 em 으로 줄지 매번 고민돼요. 결론부터 말하면 px는 고정 크기, rem은 루트(html) 글자 크기 기준(브라우저 기본 16px), em은 부모(또는 자기 자신)의 글자 크기 기준이에요. 글자 크기와 간격은 rem, 글자 크기에 비례해야 하는 컴포넌트 안쪽 여백은 em, 1px 테두리·그림자처럼 커지면 어색한 것은 px로 쓰는 게 기본 원칙이에요.

이 원칙이 왜 생겼는지 알면 헷갈릴 일이 없어요. em이 중첩되면 크기가 복리처럼 곱해지는 문제, 사용자가 브라우저 글자 크기를 키웠을 때 px만 안 커지는 접근성 문제, 유명한 html { font-size: 62.5% } 트릭의 함정까지 실제 숫자로 계산해서 정리했어요.

핵심 요약

rem은 항상 html 요소의 font-size를 기준으로 해서 어디에 써도 값이 같아요. 기본값 16px이면 1rem = 16px, 0.875rem = 14px이에요.

em은 font-size 속성에서는 부모 글자 크기, 다른 속성(padding 등)에서는 자기 글자 크기 기준이에요. 0.8em을 4단계 중첩하면 16px이 6.55px까지 줄어들어요.

브라우저 설정에서 글자 크기를 키우면 rem·em으로 지정한 글자는 따라 커지지만 px 글자는 그대로예요. 그래서 글자 크기는 rem이 접근성에 유리해요.

미디어 쿼리 안의 em·rem은 html의 font-size가 아니라 브라우저 초기값 기준이라, 48em은 기본 설정에서 768px이에요.

px, rem, em 차이 한 번에 보기

세 단위의 기준을 표로 먼저 정리할게요.

단위기준1의 크기(기본 설정)브라우저 글자 크기 설정 반영주 용도
pxCSS 픽셀(고정)1px반영 안 됨 (화면 확대는 반영)테두리, 그림자, 아이콘 선 굵기
remhtml 요소의 font-size16px반영됨글자 크기, 레이아웃 간격
emfont-size에서는 부모, 그 외 속성은 자기 font-size상황마다 다름반영됨버튼·배지 안쪽 여백, 아이콘 크기

rem의 r은 root예요. 문서 최상위 요소인 html 의 글자 크기를 기준으로 하니까, 어느 깊이의 요소에 쓰든 1rem 은 같은 크기예요. 반면 em은 "지금 이 요소가 놓인 문맥의 글자 크기"를 기준으로 해서, 같은 1em 이라도 위치에 따라 크기가 달라져요. 정의는 W3C CSS Values and Units Level 4의 font-relative lengths 항목에 있어요.

헷갈리기 쉬운 부분이 em의 기준이에요. font-size: 1.5em 처럼 font-size 속성 자체에 em을 쓰면 부모의 글자 크기가 기준이고, padding: 0.5em 처럼 다른 속성에 쓰면 그 요소 자신의 (계산된) 글자 크기가 기준이에요.

.card       { font-size: 20px; }
.card h2    { font-size: 1.5em;   /* 부모 20px × 1.5 = 30px */
              margin-bottom: 0.5em; /* 자기 30px × 0.5 = 15px */ }
.card p     { font-size: 0.875rem; /* html 16px × 0.875 = 14px, 부모와 무관 */ }
rem은 모든 깊이에서 html 기준 16px을 쓰고, em은 부모 글자 크기를 곱해 내려가는 구조 비교
rem은 항상 루트 기준, em은 부모 기준으로 곱해져요

em 중첩 문제, 복리처럼 곱해지는 계산

em의 가장 유명한 함정은 중첩이에요. 목록 글자를 조금 작게 하려고 li { font-size: 0.8em; } 을 썼다고 해 볼게요. 목록 안에 목록이 들어가면 이렇게 돼요.

4단계면 원래의 41% 크기라 사실상 못 읽어요. 반대로 1.2em 을 중첩하면 19.2 → 23.04 → 27.648 → 33.1776px로 커져요. 같은 코드를 0.8rem 으로 바꾸면 깊이와 상관없이 전부 12.8px이에요.

목록 중첩 깊이별 글자 크기 (0.8em vs 0.8rem)
0.8em0.8rem
02.557.51012.5151단계 · 0.8em 12.8px1단계 · 0.8rem 12.8px1단계2단계 · 0.8em 10.2px2단계 · 0.8rem 12.8px2단계3단계 · 0.8em 8.2px3단계 · 0.8rem 12.8px3단계4단계 · 0.8em 6.5px4단계 · 0.8rem 12.8px4단계

em은 단계마다 0.8배가 곱해지고, rem은 항상 html 기준이라 일정해요

단위: px · 자료: 루트 16px 기준 직접 계산 (16 × 0.8의 거듭제곱)
표로 보기
구분0.8em0.8rem
1단계12.812.8
2단계10.212.8
3단계8.212.8
4단계6.512.8

그래서 글자 크기(font-size)에는 em보다 rem을 쓰는 게 안전해요. em이 의도대로 동작하는 건 "부모가 커지면 같이 커져야 하는" 경우예요. 예를 들어 버튼의 패딩을 0.5em 1em 으로 주면 .btn-sm { font-size: 0.875rem }, .btn-lg { font-size: 1.25rem } 처럼 글자 크기만 바꿔도 패딩이 비율대로 따라와요. 크기별로 패딩을 따로 정의할 필요가 없어지죠.

.btn    { padding: 0.5em 1em; border: 1px solid; border-radius: 0.375em; }
.btn-sm { font-size: 0.875rem; } /* 패딩 7px 14px */
.btn-lg { font-size: 1.25rem; }  /* 패딩 10px 20px */

브라우저 글자 크기 설정과 rem — 접근성 차이

px와 rem의 실질적인 차이는 사용자가 브라우저 설정에서 기본 글자 크기를 바꿨을 때 드러나요. 크롬은 설정 > 모양 > 글꼴 크기에서 아주 작게·작게·보통·크게·아주 크게를 고를 수 있고, 이는 기본 글자 크기 9·12·16·20·24px에 해당해요. 시력이 약한 사용자는 이 설정을 크게 바꿔 두고 쓰는 경우가 많아요.

이때 html의 font-size를 직접 지정하지 않았다면 1rem이 그 값이 돼요. 본문을 1rem 으로 쓴 사이트는 따라서 커지고, 16px 로 박아 둔 사이트는 그대로예요.

브라우저 기본 글자 크기 설정별 본문 크기 (16px vs 1rem)
font-size 16pxfont-size 1rem
0510152025아주 작게 · font-size 16px 16px아주 작게 · font-size 1rem 9px아주 작게작게 · font-size 16px 16px작게 · font-size 1rem 12px작게보통 · font-size 16px 16px보통 · font-size 1rem 16px보통크게 · font-size 16px 16px크게 · font-size 1rem 20px크게아주 크게 · font-size 16px 16px아주 크게 · font-size 1rem 24px아주 크게

화면 확대(Ctrl +)는 px도 함께 키우지만, 글꼴 크기 설정은 상대 단위에만 반영돼요

단위: px · 자료: 크롬 글꼴 크기 설정값(9·12·16·20·24px) 기준 계산
표로 보기
구분font-size 16pxfont-size 1rem
아주 작게169
작게1612
보통1616
크게1620
아주 크게1624

"요즘 브라우저는 확대(줌)하면 px도 커지니까 상관없다"는 말도 반은 맞아요. 페이지 확대는 모든 것을 키우니 px 글자도 커져요. 하지만 글꼴 크기 설정만 바꾼 사용자는 px 사이트에서 아무 변화도 못 느껴요. WCAG 1.4.4 텍스트 크기 조정 기준은 글자를 200%까지 키워도 내용과 기능이 유지돼야 한다고 요구하는데, rem으로 짜 두면 두 가지 확대 방식 모두에 자연스럽게 대응돼요. 색 대비 같은 다른 접근성 기준은 WCAG 명도 대비 4.5:1 기준 글에 정리했어요.

가장 흔한 실수는 html { font-size: 16px; } 처럼 루트를 px로 고정하는 거예요. 이러면 rem을 아무리 열심히 써도 사용자 설정이 무시돼요. 루트를 바꾸고 싶다면 100%, 112.5% 같은 퍼센트로 지정하세요.

html font-size 62.5% 트릭의 장단점

계산 편의를 위해 html { font-size: 62.5%; } 를 쓰는 패턴이 있어요. 16px × 0.625 = 10px이 되니까 1.4rem = 14px, 2.4rem = 24px처럼 px 값을 10으로 나누기만 하면 돼요.

html { font-size: 62.5%; }   /* 16px × 0.625 = 10px */
body { font-size: 1.6rem; }  /* 다시 16px로 복구 */
h1   { font-size: 3.2rem; }  /* 32px */

퍼센트로 지정했으니 사용자가 기본 글자를 20px로 바꾸면 루트가 12.5px이 되어 비율은 유지돼요. 접근성 자체가 망가지는 건 아니에요. 다만 단점이 있어요.

요즘은 트릭 대신 루트를 기본값 그대로 두고, 변환은 Sass 함수나 px rem 변환기에 맡기는 쪽을 더 많이 권해요. 16으로 나누는 계산은 도구가 하면 되니까요.

px → rem 변환표 (루트 16px 기준)

공식은 rem = px ÷ 루트 글자 크기(16), 거꾸로 px = rem × 16이에요. 자주 쓰는 값을 정확히 계산해 뒀어요. 62.5% 트릭을 쓸 때의 값도 함께 적었어요.

pxrem (루트 16px)rem (62.5% 트릭, 루트 10px)주로 쓰는 곳
40.250.4작은 간격
80.50.8간격 기본 단위
100.6251캡션
120.751.2보조 텍스트
130.81251.3작은 본문
140.8751.4작은 본문, 버튼
150.93751.5본문
1611.6기본 본문
181.1251.8큰 본문, h4
201.252h3
241.52.4h2, 간격
281.752.8h2
3223.2h1, 섹션 간격
402.54큰 제목
4834.8히어로 제목
6446.4섹션 여백

13px(0.8125rem), 15px(0.9375rem)처럼 소수점 넷째 자리까지 나오는 값도 있지만 브라우저는 정확히 계산하니 반올림하지 말고 그대로 쓰는 게 좋아요. 0.81rem으로 줄이면 12.96px이 돼요.

디자인 시안 px를 rem으로 옮기는 순서

피그마 시안은 대부분 px로 나와요. 옮길 때는 이 순서로 하면 깔끔해요.

  1. 시안의 기준 본문 크기 확인: 본문이 16px이면 그대로 1rem 기준으로 변환해요. 시안이 14px 본문이라도 루트를 바꾸지 말고 본문을 0.875rem으로 쓰는 게 나아요.
  2. 글자 크기·줄 간격 외 간격은 rem: margin, gap, 섹션 padding을 rem으로 바꾸면 사용자가 글자를 키웠을 때 여백도 비례해서 숨이 막히지 않아요.
  3. 줄 간격은 단위 없이: line-height: 1.5 처럼 단위 없는 값을 쓰면 자식에게 비율로 상속돼요. 1.5em 이나 24px 은 계산된 값이 상속돼서 자식 글자가 커질 때 줄이 겹쳐요.
  4. 테두리·그림자·구분선은 px 유지: 1px 선이 1.25px로 번지면 흐릿해 보여요.
  5. 컴포넌트 안쪽 여백은 em: 버튼, 배지, 태그처럼 크기 변형이 있는 컴포넌트예요.

vw와 clamp()로 반응형 타이포그래피 만들기

화면 너비에 따라 제목 크기를 부드럽게 바꾸고 싶을 때 vw 를 써요. 1vw는 뷰포트 너비의 1%예요. 그런데 font-size: 2.5vw 만 쓰면 320px 휴대폰에서 8px, 1280px 모니터에서 32px로 양 끝이 극단적이에요. 게다가 vw만으로 지정한 글자는 브라우저 글꼴 크기 설정을 무시해요.

그래서 clamp()로 최솟값·선호값·최댓값을 묶고, 선호값에 rem을 섞어요. 뷰포트 320px에서 16px, 960px에서 24px이 되게 만들어 볼게요.

기울기 = (24 - 16) ÷ (960 - 320) = 0.0125  →  1.25vw
절편   = 16 - 0.0125 × 320 = 12px          →  0.75rem
결과   = clamp(1rem, 0.75rem + 1.25vw, 1.5rem)

640px에서 확인하면 12 + 640 × 0.0125 = 20px이에요. 960px 이후로는 최댓값 1.5rem(24px)에서 멈춰요.

뷰포트 너비별 글자 크기 (2.5vw vs clamp)
2.5vwclamp(1rem 0.75rem+1.25vw 1.5rem)
0102030403204806408009601280320 · 2.5vw 8px480 · 2.5vw 12px640 · 2.5vw 16px800 · 2.5vw 20px960 · 2.5vw 24px1280 · 2.5vw 32px32320 · clamp(1rem 0.75rem+1.25vw 1.5rem) 16px480 · clamp(1rem 0.75rem+1.25vw 1.5rem) 18px640 · clamp(1rem 0.75rem+1.25vw 1.5rem) 20px800 · clamp(1rem 0.75rem+1.25vw 1.5rem) 22px960 · clamp(1rem 0.75rem+1.25vw 1.5rem) 24px1280 · clamp(1rem 0.75rem+1.25vw 1.5rem) 24px24

clamp는 16~24px 사이에서만 움직이고, 선호값의 rem 부분 덕분에 글꼴 크기 설정도 반영돼요

단위: px · 자료: 루트 16px 기준 직접 계산
표로 보기
구분2.5vwclamp(1rem 0.75rem+1.25vw 1.5rem)
320816
4801218
6401620
8002022
9602424
12803224

미디어 쿼리에 em을 쓰는 이유

미디어 쿼리의 상대 단위는 특별해요. Media Queries Level 4 명세는 미디어 쿼리 안의 em·rem이 html에 지정한 font-size가 아니라 초기값(브라우저 기본 글자 크기) 을 기준으로 한다고 정해요. 그래서 62.5% 트릭을 써도 미디어 쿼리의 1em은 여전히 16px이에요.

@media (min-width: 48em) { ... }  /* 기본 설정에서 768px */
@media (min-width: 64em) { ... }  /* 1024px */

em으로 쓰면 장점이 있어요. 사용자가 기본 글자를 20px로 키우면 48em은 960px이 돼요. 글자가 커진 만큼 한 줄에 들어가는 글자 수가 줄어드니, 더 넓은 화면에서도 모바일 레이아웃을 유지해서 글이 비좁게 깨지는 걸 막아줘요. 과거 사파리에서 rem 미디어 쿼리가 확대와 엇갈리게 동작한 버그가 있어 em이 관례로 굳었고, 지금은 em과 rem이 사실상 같게 동작해요. 다만 사내 규칙이 px 브레이크포인트라면 일관성을 지키는 것도 중요해요.

상황별로 어떤 단위를 쓸지 정리

글자 크기는 rem, 크기 변형 컴포넌트 여백은 em, 테두리와 그림자는 px, 반응형 제목은 clamp, 미디어 쿼리는 em을 고르는 판단 흐름
무엇을 정하느냐에 따라 단위가 갈려요
대상추천 단위이유
본문·제목 font-sizerem중첩 영향 없음, 글꼴 설정 반영
레이아웃 간격(margin, gap)rem글자와 함께 비례
버튼·배지 padding, 아이콘 크기em컴포넌트 글자 크기를 따라감
line-height단위 없음비율로 상속
border, box-shadow, outlinepx번지지 않는 선명한 선
반응형 제목clamp(rem, rem + vw, rem)범위 제한 + 설정 반영
미디어 쿼리em초기값 기준, 글꼴 설정 반영
최대 너비(max-width)rem 또는 ch글자 수 기준 가독 폭

간격 체계를 rem으로 정해 두면 색처럼 토큰으로 관리하기도 좋아요. 색 단계 토큰을 만드는 방식은 디자인 시스템 컬러 스케일 글에 있어요.

자주 묻는 질문

rem과 em 중 하나만 써야 하나요?

아니에요. 글자 크기와 레이아웃 간격은 rem, 컴포넌트 안쪽 여백처럼 그 요소의 글자 크기에 비례해야 하는 값은 em으로 섞어 쓰는 게 일반적이에요. font-size에 em을 쓰는 것만 피하면 중첩 문제는 거의 생기지 않아요.

1rem은 항상 16px인가요?

아니에요. 1rem은 html 요소의 font-size예요. 브라우저 기본값이 16px이라 대부분 16px이지만, 사용자가 글꼴 크기 설정을 바꾸거나 사이트가 html의 font-size를 바꾸면 달라져요. 그래서 rem을 쓰는 의미가 있어요.

px를 쓰면 접근성 위반인가요?

px 자체가 위반은 아니에요. 페이지 확대는 px 글자도 키우니까요. 다만 글꼴 크기 설정만 바꾸는 사용자에게는 반영되지 않아서, 글자 크기만큼은 rem으로 쓰는 게 더 많은 사용자를 배려하는 방법이에요. 테두리나 그림자는 px로 써도 괜찮아요.

62.5% 트릭은 써도 되나요?

퍼센트로 지정하니 접근성이 깨지진 않아요. 하지만 body 복구를 빠뜨리거나 1rem = 16px을 전제로 한 라이브러리와 섞이면 크기가 틀어지고, 미디어 쿼리에서는 적용되지 않아 혼란이 생겨요. 새 프로젝트라면 루트를 기본값으로 두고 변환 도구를 쓰는 편이 안전해요.

14px은 몇 rem인가요?

루트 16px 기준으로 14 ÷ 16 = 0.875rem이에요. 12px은 0.75rem, 18px은 1.125rem, 24px은 1.5rem이에요. 다른 값은 위 변환표나 px rem 변환기로 바로 확인할 수 있어요.

정리

px는 고정, rem은 html 글자 크기 기준, em은 부모(font-size일 때) 또는 자기 글자 크기 기준이에요. 글자 크기에 em을 쓰면 0.8em 4단계 중첩만으로 16px이 6.55px이 되니, 글자 크기는 rem, 크기 변형 컴포넌트의 안쪽 여백은 em, 선과 그림자는 px로 나누면 대부분의 상황이 정리돼요. 루트를 px로 고정하지 않는 것, 줄 간격은 단위 없이 쓰는 것, 반응형 제목은 rem을 섞은 clamp()로 범위를 묶는 것까지 지키면 사용자가 글자를 키워도 레이아웃이 버텨요.

시안의 px 값을 옮길 때는 px rem 변환기로 16으로 나눈 값을 바로 확인하세요. 색상 값을 함께 다룬다면 색상 변환기와 HEX·RGB·HSL 차이 글도 도움이 돼요.

#px rem em 차이#rem 단위#em 단위#px rem 변환#CSS 단위#62.5% 트릭#clamp 반응형 폰트#미디어쿼리 em
← 이전 글서브넷 마스크·CIDR 계산법, /24 /26 호스트 수와 나누기 예제

더 둘러보기

💻 개발자 다른 도구

🔥 많이 찾는 도구

🔮 재미로 한 번 더

📝 읽어 볼 만한 글

글 전체 보기 →