CSS / 상대적인 크기를 정하는 em 단위와 rem 단위의 차이
em과 rem은 글자 크기를 기준으로 길이를 정하는 CSS 상대 단위입니다. font-size에서 em은 부모로부터 상속되는 글자 크기, rem은 루트 요소인 html의 글자 크기를 기준으로 합니다. 다만 padding이나 width에서 em을 쓰면 부모가 아니라 해당 요소 자신의 글자 크기가 기준이 됩니다.
em은 속성에 따라 기준을 구분하기
| 지정 위치 | em의 기준 | rem의 기준 |
|---|---|---|
| font-size | 부모에서 상속되는 글자 크기 | 루트 요소의 글자 크기 |
| padding·margin·width 등 | 해당 요소 자신의 글자 크기 | 루트 요소의 글자 크기 |
부모의 font-size가 20px인 상황에서 자식에게 font-size: 1.5em을 지정하면 자식의 글자 크기는 30px입니다. 그 자식에 padding: 1em도 지정하면 padding은 20px가 아니라 자식 자신의 글자 크기인 30px이 됩니다. “em은 언제나 부모 크기를 따른다”라고 외우면 이 부분에서 계산이 틀어집니다.
글자 크기를 em으로 계속 지정한 요소를 중첩하면 배율도 이어집니다. 20px인 부모 안에서 1.5em을 두 단계 적용하면 20 × 1.5 × 1.5 = 45px입니다. em 자체가 예측 불가능한 단위인 것은 아니며, 어느 요소의 어떤 속성에 쓰였는지가 중요합니다.
rem은 html의 글자 크기를 기준으로 하기
루트의 font-size가 16px이면 1rem은 16px이고, 1.5rem은 24px입니다. 중간 부모의 글자 크기가 20px이든 30px이든 이 기준은 바뀌지 않습니다. 그래서 문서 전반의 본문 크기나 간격을 하나의 기준으로 맞추기 쉽습니다.
1rem이 항상 16px인 것은 아닙니다. html의 font-size 선언과 브라우저 기본 글자 크기 설정에 따라 달라집니다. html에 font-size: 100%를 지정하면 기본 글자 크기를 출발점으로 삼습니다. 예외로 html 자신의 font-size에 rem을 쓰는 경우에는 자기 자신을 무한히 참조하지 않도록 초기 글자 크기를 기준으로 계산합니다.
전체 예제: 중첩과 padding을 함께 비교하기
다음 코드를 em-rem.html로 저장하고 브라우저에서 엽니다. 개발자 도구의 Elements에서 각 section과 안쪽 div를 선택한 뒤 Computed의 font-size와 padding을 확인합니다. 외부 파일이나 라이브러리는 필요하지 않습니다.
<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>em과 rem 비교</title>
<style>
body { margin: 20px; font: 16px/1.6 "Noto Sans KR", sans-serif; color: #203348; }
html { font-size: 100%; }
.parent { font-size: 20px; max-width: 650px; }
.em { font-size: 1.5em; }
.rem { font-size: 1.5rem; }
.panel { border: 1px solid #6685a5; padding: 1em; margin-bottom: 16px; }
.child { border-left: 4px solid #16818c; padding-left: 8px; }
h1 { font-size: 1.5rem; }
</style>
</head>
<body>
<h1>em과 rem의 기준</h1>
<div class="parent">
<section class="panel em">em 바깥
<div class="child em">em 안쪽</div>
</section>
<section class="panel rem">rem 바깥
<div class="child rem">rem 안쪽</div>
</section>
</div>
</body>
</html>
브라우저 기본 글자 크기가 16px이면 em 바깥은 30px, em 안쪽은 45px입니다. rem 바깥과 rem 안쪽은 모두 24px입니다. 두 panel의 padding은 같은 1em이지만 각각 30px와 24px입니다. padding의 차이도 글자 크기를 따른 결과이며 테두리나 내용의 길이 때문이 아닙니다.
이제 html의 font-size: 100%만 125%로 바꾸고 새로고침합니다. 기본값이 16px인 환경에서 루트는 20px이 되고 rem 상자는 안팎 모두 30px로 바뀝니다. em 상자는 부모를 20px로 명시했기 때문에 여전히 30px와 45px입니다. 비교를 마치면 html의 값을 100%로 되돌립니다.
어떤 단위를 선택하고 무엇을 점검할까?
문서 전체에 일관된 글자·간격 체계를 만들 때는 rem이 편리합니다. 반면 크기가 다른 버튼에 글자 크기와 비례하는 여백을 주려면 padding: 0.5em 1em처럼 em이 유용합니다. 한 사이트에서 둘을 함께 써도 되며 모든 값을 한 단위로 바꿀 필요는 없습니다.
중첩 뒤 글자가 예상보다 커지면 개발자 도구에서 부모부터 자식까지 실제 font-size를 차례로 확인하세요. 화면이 좁거나 글자 크기가 커져도 내용이 잘리지 않는지 함께 봅니다. 상대 단위를 사용해도 컨테이너를 작은 고정 높이로 제한하거나 줄바꿈을 막으면 읽기 어려워질 수 있습니다.
기준과 루트 요소의 예외는 MDN의 CSS 길이 단위 설명과 W3C의 글꼴 상대 길이 정의를 참고할 수 있습니다.




