[반응형웹]em 과 rem을 적절하게 사용하자.
반응형 웹을 개발하면서 다들 고민을 해보셨을 이야기 입니다.
em과 rem의 차이. 그리고 적절한 활용 방법을 정확하게 알려주는 글이 있어서 가져옵니다.
출처 (https://webdesign.tutsplus.com/ko/tutorials/comprehensive-guide-when-to-use-em-vs-rem--cms-23984)
여러분은 아마 좀 더 유연한 측정 단위의 사용을 고려해 보신 적이 있으셨을 겁니다. 그런데 언제 rem 단위를 쓰고, 또 언제 em을 쓸 것인지 아직 완전하게 이해하지 못하셨다면, 이번에 확실하게 안내해 드리겠습니다!
em과 rem 모두 길이가 유연한 가변 단위로서, 디자인에 설정된 폰트 크기에 따라 브라우저에 의해 픽셀값으로 변환됩니다. 만약에 1em 혹은 1rem 값을 지정했다면, 브라우저에 의해 16px부터 160px 까지, 아니면 기타 다양한 값으로 변환될 수 있습니다.
반면에 px 값은 브라우저에선 절댓값으로 인식해서, 말 그대로 1px은 항상 정확히 1px로 표시됩니다.
아래 CodePen에 표시된 슬라이더를 조절해서 rem과 em 값이 각기 어떻게 서로 다른 픽셀값으로 변환되는지 확인해 보세요. 반면 명확히 px 단위로 지정한 것은 그 크기가 고정된 것도 확인하실 수 있습니다.
커다란 의문점
em과 rem 단위를 쓰면 디자인이 유연해지면서, 고정된 크기에만 머무는 게 아니라 구성 요소의 크기를 늘리고 줄이는 게 가능해집니다. 그래서 이런 유연성을 디자인에 적용하면 개발 기간에 만나는 여러 상황에 대한 대처가 훨씬 쉬워지고, 또 브라우저 사용자는 전체 사이트의 크기를 조절해 가면서 읽기에 가장 적합한 환경을 손수 구성할 수도 있습니다.
em과 rem 단위 모두 이러한 유연성을 가져다주면서 비슷한 성질을 가졌는데, 여기서 드는 가장 큰 의문은, 그렇다면 언제 em 값을 쓰고 또 언제 rem 값을 써야 할까요?
중요 차이점
em과 rem 단위의 차이점은 이것을 브라우저가 px 값으로 변환할 때 고려하는 결정 요인에 있습니다. 이러한 차이점은 각각의 단위를 어떤 곳에 써야 적당한지를 결정하는 데 중요한 단서가 됩니다.
먼저 rem과 em 단위가 실제 어떻게 적용되는지를 확실히 이해하기 위해 기초부터 자세하게 설명해 드리겠습니다. 그러고 나서 왜 em 혹은 rem 단위를 어느 곳에 써야 하는지 알려드리죠.
마지막엔 디자인 작업 중에 일반적으로 사용되는 각 단위의 사용 유형에 관한 실제 적용법을 살펴보겠습니다.
어떻게 rem 단위가 픽셀(Pixel)값으로 변환되나
rem 단위를 쓰면, 변환된 픽셀 크기는 페이지 최상위(root) 요소, 그러니까 html 요소의 폰트 크기가 기준이 됩니다. 이 최상위 요소의 폰트 크기에다 rem 단위로 지정한 숫자를 곱한 값이 바로 마지막 변환된 값입니다.
예를 들어, 최상위 요소의 폰트 크기가 16px이면, 10rem은 160px가 됩니다. 즉, 다시 말하면 10 x 16 = 160.
em 단위가 픽셀값으로 변환되는 공식
em 단위를 쓰면 변환되는 픽셀값은 스타일을 지정한 요소의 폰트 크기를 곱한 값이 됩니다.
예를 들어, 어느 한 div의 폰트 크기가 18px이라면, 10em은 180px과 같습니다. 즉, 계산은 10 x 18 = 180이 되죠.
알아야 할 중요 사항:
자주 오해되는 것인데, em 단위가 상위 요소의 폰트 크기와 직접 연관되어 있다고 잘못 알려졌죠. 실은, W3 명세서의 의하면, 실제 사용된 요소의 폰트 크기와 직접 연관되어 있습니다.
상위 요소의 폰트 크기가 em 값에 영향을 줄 수는 있지만, 만약 그렇더라도 그것은 오로지 스타일 상속 때문에 그렇습니다. 실제로 이것이 왜, 또 어떻게 작용하는지 살펴보겠습니다.
em 단위에 미치는 스타일 상속의 영향
em 단위를 가지고 작업을 할 땐 상속과 관련해서 약간 복잡한 상황에 부닥칠 수 있습니다. 왜냐하면, 모든 요소가 자동으로 상위 요소로부터 폰트 크기를 상속받기 때문입니다. 그래서 이 상속의 영향을 뒤엎는 방법은 오로지 폰트 크기로 px 혹은 vw와 같이 상속에 영향을 받지 않는 단위를 써서 일일이 지정해주는 겁니다.
em 단위가 사용된 요소의 폰트 크기에 따라 그 변환된 값이 정해집니다. 하지만 해당 요소는 바로 상위에 있는 요소로부터 폰트 크기를 상속받았을 수도 있고, 그 상위 요소도 마찬가지로 또 그렇게 위에 있는 요소로부터 폰트 크기를 상속받았을 수 있습니다. 이렇듯 em 값은 모든 상위 요소의 폰트 크기로부터 영향을 받게 됩니다.
이제 예제를 한번 살펴봅시다. 아래의 과정을 진행하면서 직접 CodePen에서 따라 해 보세요. 따라 하시면서, Chrome Developer Tools 혹은 Firefox for Firebug를 가지고서 변환된em단위의 실제 픽셀값을 확인하실 수 있습니다.
em 상속의 예
페이지 가장 첫 단의 폰트 크기가 (보통 기본값인) 16px로 지정되었다고 가정하고, 그 안 포함된 div에는 패딩(padding)으로 1.5em을 지정했을 때, 해당 div는 최상위 요소로부터 16px의 폰트 크기를 상속받게 됩니다. 그래서 패딩값은 24px로 변환됩니다. 계산: 1.5 x 16 = 24.
그렇다면, 만약 첫 번째 div을 감싸는 또 다른 div을 만들고 이것의 font-size를 1.25em으로 지정하면 어떻게 될까요?
감싸는 div은 최상위 요소의 폰트 크기인 16px을 상속하면서 여기에다 자신한테 설정된 font-size인 1.25em을 곱합니다. 이렇게 해서 div이 갖게 되는 폰트 크기는 20px이 됩니다. 계산: 1.25 x 16 = 20.
이제 원래 div은 최상위 요소로부터 직접적인 상속의 영향을 받지 않고, 대신 감싸고 있는 새 부모 요소로부터 20px의 폰트 크기를 상속받게 됩니다. 1.5em으로 설정된 div의 패딩값은 이제 30px이 됩니다. 계산: 1.5 x 20 = 30.
만약 원래의 div에다 em 기반 폰트 크기를 지정하면 이런 비율의 증대는 더 커지기 마련인데, 아래는 1.2em을 지정한 예입니다.
가장 안쪽에 있는 div은 상위 요소로부터 20px의 폰트 크기를 물려받고, 다음에 자신의 1.2em 설정값을 곱해서 새로 24px 크기의 폰트를 표시하게 됩니다. 계산: 1.2 x 20 = 24.
1.5em으로 설정된 div의 패딩값은 새로운 폰트 크기에 맞춰서 이번엔 36px로 바뀝니다. 계산: 1.5 x 24 = 36.
마지막으로 em 단위는, (상위 요소와는 상관없이), 실제 사용된 요소의 폰트 크기에 비례하다는 것을 좀 더 자세히 살펴보기 위해, div에다 상속의 영향을 받지 않는 14px 크기의 폰트를 지정하면 1.5em 패딩값은 어떻게 변하는지 살펴보겠습니다.
이제 패딩값은 21px로 줄어들었습니다. 계산: 1.5 x 14 = 21. 상위 요소의 폰트 크기로부터 전혀 영향을 받지 않았음을 확인할 수 있습니다.
이런 여러 복잡한 특성 때문에, em 단위를 효과적으로 관리하려면 왜 확실하게 이해하고 있어야 하는지 이제 아셨을 겁니다.
브라우저 설정이 HTML 요소의 폰트 크기에 미치는 영향
기본적으로 브라우저의 폰트 크기는 보통 16px로 설정되어 있습니다만, 사용자에 의해 최소 9px부터 72px까지 변경될 수 있습니다.
알아야 할 중요 사항:
맨 꼭대기에 있는 html 요소의 폰트 크기는, 고정값을 명시적으로 지정해서 덮어씌우지 않았다면, 브라우저에 설정된 값을 상속받게 됩니다.
그래서 html 요소에 지정된 폰트 크기가 직접 rem 값을 결정짓기도 하지만, 애초에 해당 폰트의 크기는 브라우저 설정값에서 전해졌을 수도 있습니다.
그러므로 브라우저에 지정된 폰트 크기 설정값은 디자인에 사용된 모든 rem 단위의 값에 영향을 주며, 상속의 영향을 받는 모든 em 단위도 마찬가지입니다.
HTML의 폰트 크기가 지정되지 않았다면 브라우저 설정값이 효력을 가짐
덮어씌우지 않은 이상, html 요소는 브라우저에서 설정된 기본 폰트 크기를 상속받게 됩니다. 예를 들어, 특정 사이트의 html 요소에 font-size 값이 설정되어 있지 않았다고 가정해 봅시다.
만약 사용자가 브라우저의 폰트 크기를 기본값인 16px로 설정하였다면, 최상위 요소의 폰트 크기는 16px이 됩니다. Chrome Developer Tools에선 Computed 탭에 있는 Show inherited properties 항목에서 해당 요소가 상속받은 값들을 확인하실 수 있습니다.
위 보기에서 10rem은 160px 값을 갖게 됩니다. 계산: 10 x 16 = 160.
만약에 사용자가 브라우저의 폰트 크기를 18px로 키웠다면, 최상위 요소의 폰트 크기는 18px이 됩니다. 이제 10rem은 180px로 변환됩니다. 계산: 10 x 18 = 180.
브라우저 설정이 em 단위로 설정된 HTML 폰트 크기에 미치는 영향
html 요소에 em 기반의 폰트 크기를 지정했다면, 변환된 픽셀값은 브라우저에 지정된 폰트 크기의 배수가 됩니다.
예를 들어, 사이트의 html 요소가 font-size 값으로 1.25em이 지정되었다면, 최상위 요소의 폰트 크기는 브라우저에 설정된 폰트 크기의 1.25배가 됩니다.
만약에 브라우저의 폰트 크기가 16px로 설정되어 있다면, 최상위 요소의 폰트 크기는 20px이 됩니다. 계산: 1.25 x 16 = 20.
이 경우 10rem은 200px과 같습니다. 10 x 20 = 200.
하지만 브라우저의 폰트 크기가 20px로 설정되어 있다면, 최상위 요소의 폰트 크기는 대신 25px로 변환됩니다. 1.25 x 20 = 25.
그리고 10rem이면 250px과 같게 되겠지요. 10 x 25 = 250.
em과 rem 사이의 차이점 요약
앞에서 설명한 내용은 다음과 같이 요약됩니다:
rem 단위의 픽셀값 변환은 html 요소의 폰트 크기에 따라 결정됩니다. 또 이 폰트 크기는 상속에 구애를 받지 않는 절대 단위를 지정해서 직접 덮어씌우지 않았다면, 브라우저에 설정된 폰트 크기를 그대로 상속받게 됩니다.
em 단위의 픽셀값 변환은 사용된 요소의 폰트 크기에 따라 결정됩니다. 이 폰트 크기 또한 상속에 구애를 받지 않는 절대 단위를 가지고 명시적으로 덮어씌우지 않았다면, 상위 요소로부터 상속의 영향을 받습니다.
왜 rem 단위를 써야 하는가
rem 단위가 제공하는 가장 커다란 장점은 단지 요소의 상속 특성에 상관없이 일관된 크기를 돌려주는 것뿐만이 아닙니다. 오히려, 과거 px 단위를 썼던 곳에 대신 rem 단위를 사용함으로써 사용자가 설정한 폰트 크기에 따라 사이트에 배치된 모든 구성 요소가 적절하게 반응하는 길을 제공한다는 점이 가장 큰 이유입니다.
이런 이유로 rem 단위를 사용하는 주된 목적은 사용자가 브라우저의 기본 폰트 크기를 어떤 값으로 설정했든 간에, 이에 따른 가변 텍스트 크기에 맞춰서 사이트 레이아웃이 적절히 조정될 수 있도록 하려는 겁니다.
처음엔 브라우저의 기본 폰트 크기인 16px에 맞춰서 디자인을 진행합니다.
하지만 rem 단위를 쓰면, 사용자가 폰트 크기를 늘리더라도, 레이아웃은 그대로 온전하게 보전될 것이고, 텍스트 또한 작은 텍스트에만 어울리는 아주 빽빽한 공간 안에서 찌그러져 버리는 불상사가 생기지도 않을 겁니다.
또 만약 사용자가 폰트 크기를 줄인다고 해도, 전체 레이아웃도 함께 줄어들면서, 아주 작게 보이는 텍스트가 하얀 여백의 낭비된 공간에 듬성듬성 채워져 보이는 불상사도 생기지 않을 겁니다.
사용자가 폰트 크기의 설정을 바꾸는 이유는 여러 가지인데, 시력이 나쁘거나 혹은 사용 장비의 다양한 크기와 그에 따른 적정 사용 거리 등의 이유로 최적의 사용 환경에 맞춰 조절할 수 있습니다. 이러한 사용자 설정에 적절히 대응한다면 훨씬 나은 사용자 경험을 제공할 수 있을 겁니다.
알아야 할 중요 사항:
간혹 디자이너가 rem 기반 레이아웃을 구현하면서 html 요소의 font-size로 고정된 px 단위를 지정해서 작업한 경우도 목격하곤 합니다. 이렇게 한 이유는 보통 html 요소의 폰트 크기를 바꿔가면서 전체적인 디자인을 키우거나 작게 하려는 게 목적이지요.
그렇지만, 이렇게 해놓으면 사용자가 브라우저에 설정해 놓은 폰트 크기를 html 요소가 아예 무시하게 만드는 일이라서 되도록 삼가야 할 방법입니다. 사용자 설정을 무시해버리면, 사용자로부터 최적화된 콘텐츠 해석의 환경을 갖추도록 하는 기능을 아예 빼앗아버리기 때문입니다.
만약에 그래도 html 요소의 폰트 크기를 바꾸고 싶다면, 대신 폰트 크기를 em이나 rem 값으로 지정해 놓아서 사용자가 지정한 브라우저 폰트 크기와 일정한 비율로 계속 유지될 수 있도록 해야 합니다.
이렇게 해도 html 요소의 폰트 크기를 바꿔가면서 디자인을 확대하거나 축소할 수 있고, 동시에 사용자의 브라우저 설정값이 가진 효과도 계속 유지될 수 있습니다.
왜 em 단위를 써야 하는가
em 단위가 가지고 있는 최대 장점이라면 이놈은 html 요소 말고도 다른 요소의 폰트 크기에 따라서 변하는 특성이 있다는 것입니다.
이런 이유로, em 단위를 쓰는 주된 목적은 디자인 요소가 지닌 특별한 상황에 따라 거기에 어울리는 변동성이 요구될 때 사용하면 좋습니다.
예를 들어, 사이트 이동 메뉴에 속해 있는 각 항목마다 주변에 padding, margin 그리고 line-height을 설정할 때 em 값을 사용하면 좋습니다.
이렇게 해서 만약에 메뉴의 폰트 크기가 변해도, 다른 주변 레이아웃에게 영향을 끼치지 않고, 메뉴 항목 주변의 공간도 비례해서 크기가 바뀌게 됩니다.
앞서 상속 관련 내용에서도 살펴봤지만, em 단위의 변동 상황을 끊임없이 관리하기란 무척 어려운 일입니다. 이런 이유로, 꼭 필요할 때만 em 단위를 쓰실 것을 권합니다.
실제 활용
웹 디자이너 사이에서 약간의 논쟁거리가 될 수도 있고, 또 권장하는 게 서로 다를 수도 있습니다만, 아래는 제가 추천하는 방법입니다.
em 단위를 써야할 때:
최상위 요소 말고 기타 다른 특정 요소의 font-size를 기준으로 그 크기가 바뀌어야 하는 곳에 사용.
일반적으로, em 단위를 써야 할 오직 하나의 예를 꼽자면 어느 한 요소의 크기를 정할 때 해당 요소가 기본 폰트 크기로 지정되어 있지 않았을 때 뿐입니다.
앞의 예제에서도 살펴봤듯이, 디자인 구성 요소 중 메뉴 항목, 버튼 그리고 제목은 자기만의 폰트 크기가 지정되어 있을 겁니다. 만약에 이들의 폰트 크기를 변경하면, 전체 구성 요소들도 같이 비례하게 크기가 바뀌길 바라지요.
이런 지침에 해당하는 설정 속성엔 margin, padding, width, height 그리고 line-height이 있는데, 물론 사용된 요소에는 기본 폰트 크기로 지정되어 있지 않아야 합니다.
하나 더 충고해 드리고 싶은 말은, em 단위를 쓰실 땐 상속에 따른 애매한 상황을 피하고 또 크기가 대칭적으로 변할 수 있도록, 지정한 요소의 폰트 크기는 꼭 rem 단위를 쓰시기 바랍니다.
웬만하면 폰트 크기로 em 단위를 쓰진 마세요
보통 폰트 크기로, 특히나 제목 같은 경우, em 단위를 많이 쓰지만, 그냥 rem 단위를 쓰시면 디자인을 관리하기에 더 편하실 겁니다.
종종 제목에 px 단위 대신 em 단위를 사용하는 이유는 일반 글자 크기에 비례한 성질 때문일 겁니다. 하지만 rem 단위도 이런 똑같은 성질을 가지고 있습니다. 만약에 html 요소의 폰트 크기를 바꾸면, 마찬가지로 제목 크기로 따라서 바뀌게 됩니다.
아래 CodePen에서 직접 html 요소의 em 폰트 크기를 바꿔보세요:
몇 가지 예외 상황을 제외하곤, 폰트 크기가 최상위 요소에 지정된 것 말고 다른 요소의 영향을 받아서 바뀌게 되는 상황을 원하는 경우는 별로 없을 겁니다.
em 기반의 폰트 크기를 쓰기 적당한 한 예를 들자면 드롭 다운 메뉴가 있는데, 보통 두 번째 단계에 있는 메뉴 항목의 폰트 크기는 첫째 단에 있는 메뉴의 폰트 크기를 기준으로 정할 때가 있을 겁니다. 또 다른 예를 들자면, 버튼에 사용된 폰트 아이콘의 크기를 정할 때 함께 있는 버튼 텍스트의 크기에 맞도록 해야 할 경우입니다.
하지만 대부분 웹 디자인에 필요한 요소는 이러한 요구 사항이 필요 없을 터라, 일반적으로 폰트 크기를 지정할 땐 rem 단위를 쓰고, 특별한 상황에서만 em 단위를 쓰시면 되겠습니다.
rem 단위를 써야할 때:
바로 위에서 설명한 em 단위를 써야 할 이유 말고, 브라우저에 설정된 폰트 크기에 따라 그 크기가 변해야 하는 곳에는 모두 사용합니다.
여기에는 일반 디자인 거의 모두에 해당하는 높이라던가, 너비, 패딩, 마진, 테두리 너비, 대부분의 폰트 크기, 그림자 등등 기본적으로 레이아웃의 모든 부분이 해당합니다.
한 마디로, 크기가 변해야 하는 곳이라면 rem 단위를 쓰라는 말이죠.
요령
레이아웃을 구성할 땐 픽셀 단위로 생각하고 결과는 나중에 rem 단위로 환산하면 쉽습니다.
Stylus/Sass/Less와 같은 프리프로세서(preprocessor)나 혹은 PostCss의 PXtoRem 플러그인과 같은 포스트프로세서(postprocessor)를 사용하면 픽셀을 rem으로 변환하는 계산을 자동으로 하실 수 있습니다.
아니면, 손수 PXtoEM을 써서 변환하실 수도 있습니다.
항상 rem Media Queries를 쓰십시오
rem 단위를 써서 일정한 비율로 크기가 변해야 하는 디자인을 구성할 땐 media queries한테도 꼭 rem 단위를 써주는 것이 중요합니다. 이렇게 하면 작성한 media queries는 사용자가 지정한 브라우저의 폰트 크기에 맞춰 올바로 반응하면서 안성맞춤의 레이아웃으로 자동 조정될 겁니다.
예를 들어, 만약에 사용자가 글자를 아주 크게 키웠을 경우, 레이아웃은 두 개의 칼럼 형태에서 하나의 칼럼으로 줄어들어야 할거고, 이것은 작은 스크린 크기의 휴대 장비에서도 마찬가지입니다.
만약에 레이아웃 전환점이 고정된 픽셀의 너비를 가지고 있다면, 오직 화면 크기만이 그 효력을 갖습니다. 하지만 rem 기반의 전환점이라면 여러 폰트 크기에도 올바로 반응하겠지요.
em과 rem 모두 쓰지 말아야 하는 곳:
다중 칼럼 레이아웃의 너비
레이아웃의 다중 칼럼은 보통 % 기반의 단위를 쓰도록 해서 예상치 못한 화면 크기에도 유동적으로 반응할 수 있도록 해야 합니다.
칼럼이 하나일 경우에도 일반적으로 max-width에 rem 값을 지정해 놓아도 원만히 작동할 겁니다.
예를 들면:
이렇게 하면 칼럼의 크기는 유동적으로 변하지만, 동시에 그 안에 있는 글이 읽기 불편할 정도로 너무 넓어지는 것도 막을 수 있습니다.
요소의 크기가 절대 변하면 안 되는 상황일 때
일반 웹 디자인에선 레이아웃 구성 요소 중에 크기가 변한다고 부적절한 상황을 초래할 일은 별로 없을 겁니다. 하지만 간혹 크기가 변하는 것을 막기 위해 고정된 값을 지정해야 하는 상황이 생길 수도 있겠지요.
고정된 크기의 값을 지정하기 전에 미리 고려해야 할 사항이라면 해당 요소의 크기가 변할 경우 레이아웃이 망가져 버릴 때입니다. 하지만 이런 경우는 별로 없으므로, px 단위를 꺼내 들기 전에 정말로 필요한 것인지 한번 더 검토해 보시기 바랍니다.
총정리
그럼 지금까지 설명한 내용의 요점들을 짚어보겠습니다:
- 디자인에 쓰인 rem과 em 단위는 폰트 크기를 기준으로 브라우저에 의해 픽셀값으로 변환됩니다.
- em 단위는 지정된 요소의 폰트 크기를 기준으로 합니다.
- rem 단위는 html 요소의 폰트 크기를 기준으로 합니다.
- em 단위는 모든 상위 부모 요소로부터의 폰트 크기를 상속받으면서 영향을 받을 수 있습니다.
rem 단위는 브라우저에 설정된 폰트 크기를 상속받는 특성이 있습니다.
- em 단위는 최상위 요소에 지정된 폰트 크기 말고, 다른 특정 요소의 폰트 크기에 따라 그 크기가 변해야 하는 곳에 사용하십시오.
- rem 단위는 em 단위를 쓸 필요가 없고, 또 브라우저의 폰트 크기 설정에 따라 그 크기가 변해야 하는 곳에 사용하십시오.
- 폰트 크기 지정을 비롯해서 꼭 em 단위를 써야 하는 곳이 아니라면 rem 단위를 사용하십시오.
- media queries에도 rem 단위를 쓰세요.
- 다중 칼럼 레이아웃의 너비에는 em 혹은 rem을 쓰진 마십시오 - 대신 %를 쓰세요.
- 만약에 크기가 변할 경우 해당 요소의 레이아웃이 깨지는 걸 막을 수 없다면 em과 rem 모두 쓰지 마세요.
이제 em과 rem 단위가 어떻게 작동하는지 전체적인 윤곽을 명확히 이해하셨을 거로 생각합니다. 또 이를 통해 얻은 지식이 여러분의 디자인에도 충분히 활용될 수 있기를 바랍니다.
여기서 설명한 사용 요령을 직접 실험해 보시고, 이렇게 해서 다듬어진 훨씬 유연한 반응형 레이아웃의 장점들을 여러분도 십분 활용해 보세요.