EM, REM 그리고 UX

em이란

em은 가변값relative unit으로, parent element의 상속에 영향을 받습니다. 중요한 점은 상속의 영향을 받지만, em의 픽셀값 변환은 사용된 요소의 폰트 크기에 따라 결정된다는 것입니다. 따라서 고정값으로 명시하면 상속의 영향을 받지 않게 됩니다.

body {
  font-size: 8px;
}
div {
  font-size: 1.5em;
  padding: 1.5em;
  border: 1px solid #3a84a7;
  border-radius: .5em;
}

See the Pen em example A by J.hyeonjin (@Slime) on CodePen.light

해당 코드에서 보듯, body에서 설정한 font-size는 8px이고 각 div에서 설정한 값은 1.5em으로 동일하지만 em의 특성인 상속의 영향을 받아 하위 div로 갈수록 폰트가 커짐을 알 수 있습니다. 그리고 요소의 폰트 크기에 따라 padding과 border-radius값도 변화합니다.

rem이란

rem은 풀어서 쓰면 root em으로, r은 바로 root를 뜻합니다. em값을 root element에서 가져온다고 생각하면 됩니다. 어떠한 parent element도 rem값에 영향을 주지 않습니다. 오로지 root만!

상위 요소의 상속에 영향을 받지 않습니다. body에 설정된 값인 8에 1.5rem을 곱한 값인 12px이 균일하게 나타납니다. (정확히는, 여러분의 브라우저에 설정된 값에 1.5를 곱하게 됩니다. 저의 경우에는 17에 1.5를 곱한 25.5px로 나타납니다)

body {
  font-size: 8px;
}
div {
  font-size: 1.5rem;
}

See the Pen rem example A by J.hyeonjin (@Slime) on CodePen.light

font-size를 em으로

나쁘지 않습니다. 다만 em은 parent element의 상속에 영향을 받기 때문에 개발 또는 유지/보수 과정에서 관리하기가 꽤 까다롭습니다. 수고를 덜기 위해 rem을 사용하는 것을 권장합니다.

그러면 rem 단위를 써야할까요?

인터넷에 있는 다양한 글을 보면 반응형 웹에 맞는 단위는 상대적이어야 하므로 px과 같은 고정값absolute unit보다는 rem과 같은 가변값을 써야한다고 말하고 있습니다. 이는 틀린 말은 아닙니다. 다만, 좀 더 깊이 들어가 볼 필요가 있습니다.

rem에서 root는 맨 꼭대기에 있는 html 요소에서 가져오게 됩니다. html 요소에서 고정값는 명시해서 덮어씌웠다면 그 값을 가져오겠지만, 만약 그렇지 않다면? rem값이 가져오는 값은 브라우저에서 설정된 값이 됩니다. 따라서 브라우저에서 지정된 폰트 설정은 모든 rem 단위에 영향을 주게 되죠.

보통 브라우저 폰트의 기본값은 16px로 설정되어 있습니다. 여러분이 html에 별다른 선언을 하지 않았고, 여러분의 사이트를 보는 유저도 별다른 설정을 건드리지 않았다면 rem은 16이라는 값을 가져오겠죠. 그러면 1rem은? 16px입니다.

여기에 가상의 유저 A를 떠올려 봅시다. 이 분은 모종의 이유로 27인치 QHD 모니터를 사용하고 있는데 이 해상도는 그에게 너무 작은 글자 크기를 선사하고 있습니다. 게다가 바른 자세를 유지하려고 하기 때문인지 눈과 모니터의 거리도 상당합니다. 인터넷 서핑을 자주하는 A는 방문하는 사이트들의 폰트를 보다가 이내 미간에 주름이 잡히게 되고 결국 브라우저 설정에 들어가 폰트 크기를 살짝 조정합니다. A가 조정한 값을 18px이라고 합시다.

A가 당신의 사이트에 들어와서 기대하는 것은 적어도 사이트에서 주로 쓰고 있는 폰트(예를 들어 본문이라던가)가 18px로 조절되어 있는 모습입니다. 하지만 여러분의 사이트에서 폰트들이 px이라는 고정값을 가지고 있다면 A가 설정에서 조절한 값은 완전히 무시됩니다. 이는 정말 나쁜 UX입니다. A의 수고는 아무런 효과가 없었고 그는 브라우저의 zoom 기능으로 당신의 사이트를 확대하는 수고를 더 들이던가, 최악의 경우에는 사이트를 나가버릴지도 모릅니다.

이 때 여러분의 사이트가 rem값을 사용하고 있다면 어떨까요? 이전 문단에서 언급했듯이 A는 브라우저의 기본 폰트를 18px로 조정했고, 이 경우에 1rem은 자동적으로 root element인 브라우저의 기본 폰트 크기를 가져옵니다. 18px로 변환되는 것이죠. 비로소 A의 수고가 인정을 받는 순간입니다. 다시 말해 폰트의 가변값은 반응형 웹을 만드는 디자이너를 위해서가 아니라 (물론 디자이너를 위해서이기도 합니다) 유저의 설정을 존중하는 것에 방점이 있습니다.

유저가 스스로에게 최적화된 UX환경을 설정했다면, 디자이너는 이를 존중해야 합니다. rem값을 사용해야하는 것은 그런 이유입니다.

  • rem 단위로 폰트를 구성하면서 html 요소에 font-size를 고정값(px, pt 같은 것들)으로 설정해서는 안됩니다! rem은 root에서 값을 가져오므로 html에 고정값을 선언하면 브라우저의 설정값을 덮어씌우게 되고, 모든 rem값이 해당 값을 상속 받게 됩니다.

따라서 폰트 사이즈를 선언할 때 reasonable한 표기는 다음과 같습니다

div{
   font-size: 16px;
   font-size: 1rem;
}

rem값이 px값 뒤에 선언되면서 일반적으로 rem 값이 사용될 것이며, rem 값을 지원하지 않는 구형 브라우저의 경우에는 고정값인 16px이 사용될 것입니다.

EM으로 다시 돌아옵시다

font-size를 rem으로 잡았다면 레이아웃은 em으로 잡는 것을 추천합니다. em은 rem과 달리 root element에서 값을 가져오는 것이 아닌, em값이 쓰인 바로 그 요소의 font-size를 기준으로 합니다. 물론 상속의 영향도 받습니다. 이 장점을 이용합니다.

rem으로 폰트 크기가 정해지면 em은 해당 요소의 rem값을 기준으로 변환됩니다. width, height, margin, padding, line-height 등의 값들이 안에 들어 있는 폰트의 크기에 맞춰서 가변적으로 변합니다. 안에 있는 폰트의 크기가 작아지면 그러한 값들도 작아질 것이고, 폰트가 커지면 맞춰서 커집니다. 요소들이 주변에 영향을 끼치지 않고 글자 주변의 공간들도 비례해서 움직이게 됩니다.

앞서 A가 브라우저의 폰트 설정을 바꿨던 것, 기억하시나요? 유저가 설정한 브라우저의 폰트 크기에 따라 rem의 변환값이 결정되고, 그렇게 변환된 rem 값에 따라 각 요소들의 em들이 움직이기 시작합니다. 사이트의 레이아웃이 자연스럽게 조절되는 것이죠.

요약

  • 유저가 설정한 UX 환경을 존중해 주세요. 폰트 사이즈에 rem 단위를 사용해 주세요.
  • em 단위를 통해 유저가 설정한 폰트 크기에 따른 가변적 레이아웃을 구축하세요.

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다