CSS - 반응형 웹 텍스트의 핵심 em과 rem 을 이해하자 - Understand CSS em & rem

데스크탑 환경만 고려하면 되던 고대 HTML 환경? 에서는 글자 크기는 모두 픽셀 단위(px) 였습니다.

조금 고급으로 CSS를 구성하는 정도가 퍼센트(%) 값으로 픽셀 단위를 보조하는 수준입니다.

font-size: 16px;

font-size: 85%;

그것이 당연한 것이었고, 지금도 픽셀 단위 글자 크기는 유효하지만, 레티나 디스플레이나 모바일 환경을 함께 고려해야 하거나, 모바일 환경을 위한 웹페이지를 만들 경우 픽셀 단위의 글자 크기는 여지없이 문제가 나타납니다.

하나의 웹 페이지로 데스크탑 환경과 모바일 환경을 모두 대응하는 반응형 웹페이지의 경우,

미디어 쿼리로 일일이 하나씩 글자크기를 맞춰주기에는 너무 작업량이 많아지고 유지보수도 쉽지 않습니다.

더 큰 문제는 모바일 기기의 해상도가 제각각이다보니 어떤 모바일 기기에서는 적당한 글자크기로 보이던 것이, 다른 모바일 기기에서는 너무 크거나 작게 보이는 문제가 있습니다.

이렇게 해서 등장한 단위가 em과 rem 단위입니다.

em 과 rem 단위 값의 등장

em과 rem 단위는 모두 부모의 글자 크기를 상속받아 배율로 그 상대적인 크기를 정합니다.

font-size: 0.9375em;

font-size: 1.0625rem;

em이 먼저 나왔고 그 이후에 rem 이 나왔기 때문에 em 단위의 호환성이 더 광범위하고 개념도 비교적 널리 알려져 있습니다.

rem 단위는 그 이후에 em 단위의 중첩으로 인한 불편함과 복잡함을 해소하기 위해 나왔고 호환성 면에서는 em 단위보다 떨어집니다.

rem 단위가 호환성이 em 보다 떨어진다고 해도 인터넷 익스플로러 9 이상에서는 모두 지원하기 때문에, 현재 웹브라우저 환경에서는 호환성 문제를 고려하지 않아도 될 정도입니다.

다만 아직 rem 단위의 사용 빈도는 높지 않으며 em 단위의 보조적인 용도로만 주로 사용됩니다.

rem 단위의 웹브라우저 버전 호환성은 다음과 같습니다.

크롬

파이어폭스 

사파리(맥OS)

오페라 

인터넷익스플로러 

엣지

 4.0 이상 지원

3.6 이상 지원

4.1 이상 지원

11.6 이상 지원

9.0 이상 지원

지원

국내에서 가장 중요한 부분은 인터넷 익스플로러 호환성 문제입니다.

최근 대부분 사이트들이 인터넷 익스플로러 10 이상을 최소 환경으로 하고 있기 때문에, rem 단위 사용에 따르는 호환성 문제는  더이상 걱정하지 않아도 됩니다.

상속되는 em 단위 글자 크기의 이해

em 단위는 픽셀 단위와 달리 소수점 이하 숫자를 사용하며, 바로 위 부모 엘리먼트(태그)의 글자 크기에 em값을 곱한 값이 글자 크기(픽셀 단위 값)로 정해집니다.

예를 들어 아래와 같이 부모 엘리먼트의 글자 크기라 16px 였고, 그 하위 엘리먼트에 0.375em 글자 크기를 지정했다면

<div class="wrap"> <div class="inner">글자 크기는 15px 임.</div></div>
.wrap{font-size: 16px;}.wrap > .inner{font-size: 0.9375em;}

0.925em 단위는 16 * 0.9375 = 15 가 되서 div.inner 클래스 안의 텍스트는 기본 크기가 15px로 정해지게 됩니다.

0.9375em 과 같은 복잡한 크기 값을 사용해야 하는 이유에 대해서는 아래 "가독성 문제" 에서 자세히 설명합니다.

em 단위의 상속형 특성은 CSS의 모든 속성들이 그런것처럼 다단으로 중첩되는데 따라 하위 요소는 상위 요소의 속성들을 모두 상속받게 됩니다.

예를 들어 

<div class="wrap"> <div class="inner"> <span>글자 크기는 15px 임.</span> <span class="small">12px 작은 글자</span> </div></div>
.wrap{font-size: 16px;}.wrap > .inner{font-size: 0.9375em;}.wrap > .inner > .small{font-size: 0.8em;}이렇게 2중첩으로 글자 크기를 em 값으로 지정한 경우span.small 안의 텍스트는 최상위 크기값으로 정해진 16px * 0.9375 * 0.8 = 12px가 됩니다.

즉, em 크기는 상속 받은 것을 다시 상속 받게 됩니다.

더 쉽게 정리하면 나의 바로 위에 있는 요소(태그, 엘리먼트)의 글자 크기 속성값을 기준으로 상대 크기 배율이 정해지게 됩니다.최상위 글자크기의 이해em 값으로 상위 요소에 대한 상대 크기로 글자 크기를 정하지만, 최상위 요소는 언제는 절대값으로 정해진 기본 글자 크기값을 가지고 있습니다.정해진 기준 크기가 있어야 그 하위에 상대 크기로 지정한 em이나 rem이 배율에 따라 크기값이 정해질 수 있기 때문입니다.사용자가 최상의 요소(엘리먼트)의 글자 크기를 따로 지정하지 않아도 웹브라우저에는 기본 글자 크기가 있습니다.정확하게는 최상위 요소에 사용자가 글자 크기를 지정하지 않은 경우 사용하는 기본값입니다.우리가 아는 대부분의 데스크탑 환경에서 실행되는 웹브라우저들은 이 기본값을 16px 로 사용합니다.따라서, 별도의 글자 크기가 정해지지 않은 모든 요소들의 글자 크기는 16px 라고 이해하면 됩니다.em과 rem 값은 이 크기를 기준으로 상대 글자 크기가 정해집니다.물론 중간에 사용자가 픽셀 단위로 절대값 글자 크기를 지정한 경우, 그 하위에 사용되는 em값은 이 크기를 기준으로 다시 정해지게 됩니다.전체 웹페이지의 최상위 글자 크기 지정웹브라우저의 최상위 글자 크기를 강제로 변경하기 전에 현재 기본 값이 얼마인지 알아야 할 필요가 있습니다.간단하게 아래와 같은 HTML 문서를 하나 만들어서 웹브라우저에서 엽니다.<html> <body> <span>font-size:?</span> </body></html>크롬 개발자 도구(F12) 를 연 후 요소 선택자(엘리먼트 셀렉터)로 "font-size:?"를 선택해 보면 font-size: 16px 라는걸 확인할 수 있습니다.별도의 글자크기나 CSS가 없는 상태에서 브라우저가 기본으로 설정한 최상의 글자 크기가 16px 입니다.

위 문서에 CSS 파일을 하나 만들어 연결해봅니다.CSS에는 다음과 같이 html 태그와 그 안의 span 태그에 에 글자 크기를 지정하는 아주 간단한 내용만 있습니다.html {font-size: 20px;}이렇게 하면 span 태그의 글자는 별도의 글자 크기가 지정되지 않았지만 20px가 되게 됩니다.

CSS를 조금 확장해서 span 태그에 0.8em 을 적용해 보면html {font-size: 20px;}span { font-size: 0.8em;}표시되는 span 태그의 텍스트는 16px 가 됩니다. ( 20px * 0.8em )

em과 rem의 차이

앞서 rem은 em의 문제점을 보완하게 위해 추가된 단위라고 설명을 했습니다.

rem은 최상위 글자 크기를 기준으로 상대 크기가 정해집니다.

즉, 중첩과 무관하게 무조건 최상위 글자 크기롤 기준으로만 상대 크기를 계산합니다.

em 에서 상속의 개념을 없앤 것이라고 이해하면 됩니다.

따라서 rem 은 em과 상대적인 크기를 계산한 결과 값이 전혀 다릅니다.

위의 예에서 2중첩을 한 css의 글자 크기를 계산하는 코드를 동일하게 rem으로 변경할 경우 

(idv.wrap 요소에 픽셀 값으로 글자 크기가 정해져 있으므로 이 값을 상속받기 때문에 div.wrap 요소가 최상위 요소가 됩니다.)

<div class="wrap"> <div class="inner"> <span>글자 크기는 15px 임.</span> <span class="small">12px 작은 글자</span> </div></div>
.wrap{font-size: 16px;}.wrap > .inner{font-size: 0.9375rem;}.wrap > .inner > .small{font-size: 0.8rem;}

em 사용시 div.inner 클래스의 글자크기는 15px, div.small 클래스의 글자 크기는 12px가 되지만

rem 사용시 div.inner 클래스의 글자크기는 16 * 0.9375 = 15px, div.small 클래스의 글자 크기는 16 * 0.8 = 12.8px가 됩니다. 

HTML 문서의 특성상 2중첩 정도가 아니라 10 ~ 20중첩까지 내려가는 것은 기본이기 때문에 뎁스가 내려갈수록 em 과 rem은 전혀 다른 글자 크기를 가지게 됩니다.

em, rem 단위와 가독성 문제

em 과 rem 단위는 상대 크기를 배율값으로 지정하기 때문에 소숫점이 들어가는 실수 값으로 상대 크기를 지정합니다.

따라서 그 결과값이 되는 최종 픽셀값도 소수점 크기를 가지게 됩니다.

위의 예를 든 것을 확장해서 아래와 같은 예를 만들어서

<div class="wrap"> <div class="inner"> <span>글자 크기는 15px 임.</span><br/> <span class="smallfloor">작은 글자- 0.8rem 12.4px</span><br/> <span class="small">작은 글자 - 0.8rem 12.8px</span><br/> <span class="smallfix">작은 글자 - 0.8125rem 13px</span> </div> </div>

rem 으로 소숫점 글자 크기와 정수 픽셀 값으로 딱 떨어지는 글자를 만들어보면

.wrap{font-size: 16px;}.wrap > .inner{font-size: 0.9375rem;}.wrap > .inner > .smallfloor{font-size: 0.775rem;}.wrap > .inner > .small{font-size: 0.8rem;}.wrap > .inner > .smallfix{font-size: 0.8125rem;}

아래와 같은 결과로 웹브라우저에서 렌더링 됩니다. ( 결과는 크롬 브라우저 기준)

"작은 글자" 의 "자" 자를 보면 12.8px 라는 결과가 가져오는 차이점을 알 수 있습니다.

0.2px가 모자라기 때문에 줄어든 크기에 맞춰 글자를 렌더링 하게 되면 이런 안티알리아싱 적용때문에 글자의 선명도가 떨어지게 되고, 전체 웹페이지의 가독성을 떨어뜨리는 결과를 초래합니다.

이 문제는 해상도가 아주 높은 레티나 디스플레이나 모바일 기기에서는 별다른 영향을 주지 않기 때문에 모바일 환경에서는 별개의 이야기입니다.

16px 인 상위 요소의 글자 크기에 0.8125rem 을 곱하면 13px가 되지만 0.8rem를 곱하면 12.8px가 됩니다.

원했던 결과가 13px 였다면, 예상보다 글자는 미세하게 더 작게 출력될 것이고, 초보자라면 글자가 미세하게 뭉게져 보이는 현상 때문에 rem 값을 고쳐가면서 원하는 결과를 얻기 위해 시행 착오를 하게 됩니다.

영문보다 한글 글꼴은 글꼴 크기, 특히 작은 글꼴 크기에 대한 가독성 차이가 심한 편입니다.

글꼴에 따라서도 가독성이 좋은 크기가 다르기 때문에 이런 부분은 결국 시행 착오를 해야 합니다.

아래 표를 보면 일반적인 웹브라우저 최상위 글자 크기인 16px 를 기준으로 em 값으로 얼마를 지정해야 하는지 알 수 있습니다.

픽셀 크기 

em/rem (16px 기준) 

10px

0.625

11px

0.6875

12px

0.75

13px 

0.8125

14px 

0.875

15px 

0.9375

16px

1

17px 

1.0625

18px 

1,125

19px 

1.1875

20px 

1.25

21px

1.3125

34px

2.125

48px

3

특히 0.9375em(15px), 0.8125em(13px) 같은 크기 값은 자주 사용되기 때문에 알아두면 유용합니다.

다른 사람이 만든 CSS를 볼때 이런 글자 크기를 적용한 em 이나 rem 값들을 보게 되면 최소 배우신분이 만든 CSS 라고 판단해도 됩니다.

왜냐하면 구글이나 애플에서 모바일 기기나 웹페이지용 UI 가이드라인으로 제시하는 일종의 표준? 이 16px 의 최상위 기본 글꼴 크기를 기준으로 해서

본문 글자 크기는 16px로 그 하위 내용에 대해서는 13px 나 14px를 사용할 것을 권장하고, 제목이나 헤드라인에는 48px나 34px를 사용할 것을 권장합니다.

이런 기준에 따라 위에 해당하는 em 이나 rem값을 CSS에 적용해서 사용하면 원하는 정확한 글자 크기를 얻을 수 있습니다.