
px를 rem으로 바꿔야 하는 이유 — 접근성과 유지보수를 위한 CSS 단위 가이드
📷 Boskampi / Pexelspx를 rem으로 바꿔야 하는 이유 — 접근성과 유지보수를 위한 CSS 단위 가이드
픽셀로 스타일을 짜는 개발자가 여전히 많습니다. rem 단위가 왜 더 나은 선택인지, em과는 어떻게 다른지, 실무에서 어떻게 전환할 수 있는지 정리했습니다.
프론트엔드 코드를 리뷰하다 보면 반복적으로 발견하는 패턴이 있습니다. font-size: 16px, padding: 24px, margin-bottom: 32px — 거의 모든 값이 픽셀로 고정되어 있습니다. rem이 무엇인지 설명해달라고 하면 대부분의 개발자가 정확하게 설명합니다. 그런데도 픽셀을 사용합니다.
이유는 단순합니다. 픽셀이 먼저 배운 단위이고, 16으로 나누는 연산이 귀찮고, "어차피 잘 작동하는데"라는 생각이 있기 때문입니다. 합리적인 이유들입니다. 하지만 픽셀이 "잘 작동한다"는 것은 어떤 사용자를 기준으로 한 이야기인지 생각해볼 필요가 있습니다.
rem이 정확히 무엇인가
rem은 "root em"의 약자입니다. 문서의 루트 요소인 <html> 태그에 설정된 폰트 크기를 기준으로 계산되는 상대 단위입니다.
브라우저의 기본 루트 폰트 크기는 16px입니다. 아무 설정도 하지 않으면:
1rem= 16px1.5rem= 24px0.875rem= 14px2rem= 32px
변환 공식은 간단합니다. rem = px ÷ 기본 폰트 크기. 반대 방향은 px = rem × 기본 폰트 크기.
대부분의 경우 기본 폰트 크기는 16px입니다. 하지만 프로젝트에서 루트 폰트 크기를 다른 값으로 설정했다면 그 값을 기준으로 계산해야 합니다.
em과 무엇이 다른가
rem과 em은 비슷해 보이지만 실질적으로 다르며, 이 차이를 모르면 예상치 못한 버그를 만납니다.
em은 현재 요소의 폰트 크기, 또는 일부 CSS 속성에서 부모 요소의 폰트 크기를 기준으로 합니다. 이것이 복잡해지는 이유는 중첩 시 값이 누적되기 때문입니다. font-size: 0.8em인 컨테이너 안에 font-size: 0.8em인 자식을 넣으면, 자식의 실제 폰트 크기는 루트 대비 0.8 × 0.8 = 0.64em입니다. 디자이너가 설정한 0.8em보다 훨씬 작아지죠.
rem은 항상 <html>로 돌아갑니다. 요소가 DOM의 어디에 있든 상관없이 기준점이 바뀌지 않습니다. 1.5rem이라고 쓰면 루트 폰트 크기의 1.5배, 끝입니다.
em이 여전히 유용한 경우가 있습니다. 버튼 패딩처럼 버튼 자체의 폰트 크기와 비례해서 변해야 하는 속성이라면 em이 맞습니다. 그러나 일반적인 폰트 크기와 간격 설정에는 rem이 기본 선택입니다.
Pixel-REM Converter 사용하기
Pixel-REM Converter는 이 계산을 대신해줍니다.
픽셀값을 입력하면 해당하는 rem과 em 값을 즉시 보여줍니다. 반대로 rem을 입력해서 픽셀을 확인할 수도 있습니다. 기본 폰트 크기는 16px로 설정되어 있지만, 프로젝트에서 다른 값을 쓴다면 변경할 수 있습니다. html { font-size: 18px }를 사용하는 프로젝트라면 기본 크기 필드에 18을 입력하면 모든 변환이 정확하게 됩니다.
변환 테이블 기능도 있어서 일반적으로 많이 쓰는 픽셀 값들(8, 10, 12, 14, 16, 18, 20, 24, 32, 48, 64, 96)을 설정한 기본 크기 기준의 rem 값과 함께 한눈에 볼 수 있습니다. 디자인 스펙을 보면서 작업할 때 이 테이블을 열어두면 매번 계산하지 않아도 됩니다.
사용 방법은 간단합니다:
- 픽셀값을 입력합니다 — "px"는 쓰지 않아도 됩니다.
- 기본 폰트 크기를 확인하거나 수정합니다 — 기본값은 16. 프로젝트에 맞게 변경하세요.
- rem 값을 읽습니다 — 입력하는 즉시 결과가 업데이트됩니다.
- 변환 테이블을 스캔합니다 — 자주 쓰는 크기들을 한눈에 확인합니다.
접근성 이야기
픽셀 대신 rem을 써야 하는 핵심 이유는 접근성입니다.
많은 사람들이 브라우저 설정에서 기본 폰트 크기를 변경합니다. 시력이 좋지 않은 사용자, 화면에서 멀리 떨어져 사용하는 사람, 단순히 텍스트가 크게 보이는 것을 선호하는 사람들입니다. 이들은 브라우저 설정에서 기본 폰트를 20px, 24px, 또는 그 이상으로 설정합니다.
CSS에서 픽셀 단위로 폰트 크기를 설정하면 이 설정이 조용히 무시됩니다. 브라우저가 고정 픽셀값을 사용자 선호에 맞게 스케일하지 않습니다. 사용자가 텍스트를 크게 보고 싶어서 설정을 바꿨지만 여러분의 사이트만 변하지 않는 상황이 됩니다.
rem을 사용하면 달라집니다. 루트 폰트가 20px인 사용자는 1rem 텍스트를 20px로 봅니다. 1.5rem 헤딩은 30px가 됩니다. 전체 레이아웃이 비례적으로 확대되어 사용자가 원했던 경험을 얻게 됩니다.
웹 접근성 국제 표준(WCAG)의 성공 기준 1.4.4도 이 내용을 다룹니다: 텍스트를 200%까지 확대할 수 있어야 하며, 브라우저 수준의 폰트 스케일링이 그 방법 중 하나입니다. 픽셀 기반 폰트 크기는 많은 구현에서 이 기준을 충족하지 못합니다.
또 다른 관점도 있습니다. 사용자가 브라우저 폰트 크기를 설정했는데 여러분의 사이트만 변하지 않는다면, 다른 모든 사이트와 다르게 보입니다. 작은 차이지만 사이트에 대한 인상에 영향을 줍니다.
자주 나오는 반론들
"브라우저 줌으로 충분하지 않나요?" 브라우저 줌은 텍스트, 이미지, 레이아웃 전체를 함께 확대합니다. 텍스트만 크게 보고 싶은 사용자의 요구와는 다릅니다. 브라우저 폰트 크기 설정은 레이아웃 변경 없이 텍스트만 스케일하는 기능입니다.
"우리 사용자들은 16px 기본 설정을 쓴다" 여러분은 사용자들이 어떤 폰트 크기를 설정했는지 알 수 없습니다. 분석 도구가 브라우저 폰트 크기 설정을 수집하지 않습니다. 픽셀 기반 폰트에 가장 큰 영향을 받는 사용자들이 추적 데이터에 덜 잡히는 경향이 있습니다.
"rem은 코드 가독성이 나쁘다" 어느 정도 맞는 말입니다. font-size: 1.25rem은 font-size: 20px보다 한눈에 파악하기 어렵습니다. 이 문제는 CSS 커스텀 속성에 픽셀 주석을 달아 해결할 수 있습니다. --text-xl: 1.25rem; /* 20px */ 같은 방식입니다. 변환 테이블을 열어두는 것도 도움이 됩니다.
"디자인 스펙이 픽셀로 되어 있다" 변환 도구가 있는 이유가 바로 이 때문입니다. 스펙에 24px라고 나와 있으면 변환기를 거쳐 1.5rem으로 구현하면 됩니다. 스펙의 값과 구현 단위를 분리하는 것입니다.
루트 폰트 크기 설정 방식들
실무에서 흔히 보이는 설정 방식들입니다.
기본값 유지 (16px). 가장 일반적입니다. 별도 CSS 설정이 필요 없습니다. 단점은 16이 계산하기 불편한 수라는 점입니다. 14px = 0.875rem, 18px = 1.125rem처럼 소수점이 많이 생깁니다.
62.5% 설정 (10px 기준). html { font-size: 62.5%; }. 1rem = 10px이 되어 14px = 1.4rem, 24px = 2.4rem처럼 계산이 깔끔해집니다. 다만 body에 font-size: 1.6rem 등을 명시하지 않으면 텍스트가 10px로 렌더링됩니다. 합류하는 팀원이 이 규칙을 모르면 실수하기 쉬운 함정입니다.
100% 명시 (16px 유지). html { font-size: 100%; }. 기본값과 기능적으로 동일하지만 CSS에 명시적으로 적혀 있어 의도를 전달합니다.
세 가지 모두 유효합니다. 중요한 것은 팀 내에서 일관성을 유지하는 것입니다.
실무 적용 팁
구현하면서 바로 변환하세요. 컴포넌트를 만들 때 픽셀로 쓰고 나중에 일괄 변환하려면 번거롭습니다. 변환기는 값 하나당 1초가 안 걸립니다. 바로바로 변환하는 게 낫습니다.
커스텀 속성으로 관계를 문서화하세요. 디자인 토큰 파일에 이런 형태로 작성하면 좋습니다:
:root {
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
}
주석에 픽셀값을 적어두면 다른 사람이 코드를 읽을 때 직관적으로 파악할 수 있습니다.
모든 값을 rem으로 바꿀 필요는 없습니다. 테두리, 박스 그림자, 장식적 요소들은 픽셀로 고정해도 됩니다. 중요한 곳은 폰트 크기, 줄 높이, 텍스트 가독성에 영향을 주는 여백값입니다.
다른 브라우저 폰트 크기로 직접 테스트해보세요. 브라우저 설정에서 기본 폰트를 20px이나 24px로 바꿔보고 자신의 사이트를 열어보세요. 레이아웃이 깨지거나 텍스트가 겹치면 픽셀 기반 CSS의 문제가 드러납니다. 이 테스트는 30초면 됩니다. 그리고 일부 사용자가 매일 경험하는 것을 직접 확인하게 됩니다.
em이 여전히 유용한 경우
rem이 기본 선택이지만, em이 더 적합한 상황도 있습니다.
버튼 패딩. 버튼에 font-size: 0.875rem, 패딩에 0.5em 1em을 설정하면 패딩이 버튼의 자체 폰트 크기를 기준으로 계산됩니다. 나중에 큰 버튼 변형이 필요해 폰트 크기를 키우면 패딩도 자동으로 비례해서 커집니다. 의도된 동작입니다.
아이콘 크기. 텍스트와 나란히 배치되는 아이콘에 width: 1em; height: 1em을 주면 주변 텍스트와 시각적으로 맞는 크기를 유지합니다.
컴포넌트 내부 스케일링. 컴포넌트에 고정 폰트 크기가 있고 내부 간격이 그 폰트에 비례해야 할 때 em이 그 관계를 명시적으로 표현합니다.
핵심은 em이 의도적인 상대 관계를 위한 것이라는 점입니다. 전역 사용자 설정과 관계된 값에는 rem을 씁니다.
관련 도구
CSS Units Converter — vh, vw, vmin, vmax, pt 등 더 넓은 범위의 CSS 단위 간 변환을 지원합니다. 뷰포트 상대 단위 변환에 유용합니다.
CSS Box Shadow Generator — 컴포넌트 스타일에 박스 그림자를 추가할 때 CSS를 생성해줍니다. 박스 그림자 값은 픽셀을 계속 써도 괜찮은 예외적인 경우입니다.
Color Converter — 디자인 시스템 작업 시 hex, RGB, HSL 등 색상 형식을 변환합니다. 단위 변환과 함께 자주 필요한 작업입니다.
FAQ
px, rem, em의 차이는 무엇인가요? px는 고정값으로 브라우저 폰트 설정을 무시합니다. rem은 루트 요소 폰트 크기 기준 (기본 16px). em은 부모 요소 폰트 크기 기준으로, 중첩 시 누적됩니다. 대부분의 경우 rem이 가장 예측 가능합니다.
px를 rem으로 어떻게 변환하나요? 픽셀값을 기본 폰트 크기로 나눕니다. 기본 16px 기준: 24px ÷ 16 = 1.5rem. Pixel-REM Converter를 사용하면 커스텀 기본 크기를 설정해 즉시 변환할 수 있습니다.
rem을 쓰면 레이아웃이 깨지지 않나요? 점진적으로 적용하면 문제없습니다. 폰트 크기와 텍스트 주변 여백부터 시작하고, 테두리와 장식 요소는 픽셀 유지로도 충분합니다. 한 번에 모든 것을 바꿀 필요가 없습니다.
html { font-size: 62.5% } 트릭이 좋은 방법인가요?
사용하는 팀이 많습니다. 계산이 편해지는 장점이 있지만, body에 명시적인 폰트 크기 설정이 꼭 필요합니다. 새로 합류하는 팀원이 이 규칙을 모르면 실수할 수 있으므로 팀 내 문서화가 중요합니다.
rem 변환이 귀찮아서 픽셀을 쓰게 됩니다. Pixel-REM Converter의 변환 테이블을 브라우저 탭에 열어두세요. 자주 쓰는 값들(16, 20, 24, 32...)을 스캔하는 데 몇 초면 됩니다. 계산기 없이 빠르게 확인할 수 있어 실제로 전환 장벽이 낮아집니다.
마치며
px에서 rem으로 바꾸는 것은 작은 변화지만 접근성 효과는 생각보다 큽니다. 개념적으로 이해하는 것과 실제로 적용하는 것 사이에 있는 장벽은 대부분 16으로 나누는 귀찮음입니다. 변환 도구는 그 장벽을 없애기 위해 존재합니다.
디자인 스펙의 픽셀값을 rem으로 바꿔야 할 때, Pixel-REM Converter를 탭 하나로 열어두세요. 계산이 필요한 순간 바로 쓸 수 있습니다.