반응형 웹디자인이 대두되면서 점점 많은 웹사이트들이 em과 rem라고 불리는 CSS 단위를 이용해서 스타일링이 되고 있습니다. 이번 포스팅에서는 em과 rem 단위가 실제로 브라우저에서 어떻게 동작하는지 정확히 알고 좀 더 적재적소에 사용하는 방법에 대해서 알아보도록 하겠습니다.
상대(relative) 단위란 고정되지 않고 어떤 기준에 따라서 유동적으로 바뀔 수 있는 길이를 나타내는 단위입니다. 본 포스팅에서 다룰 em과 rem을 포함해 %, vw, vh 등이 대표적인 CSS의 상대 단위입니다.
반면 절대(absolute) 단위는 어떤 상황에서든 항상 고정된 길이를 나타내는 단위입니다. 대표적으로 예전부터 현재까지 많이 사용되는 px와 pt를 들 수 있고, cm나 in와 같은 실생활에서 많이 사용되는 단위들도 이 절대 단위에 범주에 속합니다.
쉽게 말해, 실생활에서 1cm가 항상 1cm인 것처럼, 1px는 항상 1px(=0.02645833cm)이지만, 1em이나 1rem은 항상 고정된 길이를 나타나지 않고 대신 브라우저가 어떤 기준에 따라 계산을 하여 px로 변환을 해줍니다. 따라서 그 기준이 무엇인지를 파악하는 것이 em과 rem을 정확히 이해하는데 핵심이 됩니다.
뭐 적어도 px나 pt와 같은 절대 단위를 쓰는 것 보다는 나을테니라는 생각으로 많은 분들이 em과 rem을 혼용해서 사용하시는 것 같습니다. 사실 브라우저에서 이 두 단위가 같은 길이로 계산될 때가 상당히 많고, 둘 중에 뭐를 쓰든 큰 차이가 나지 않아서 그럴 수도 있을 것입니다.
em과 rem은 둘 다 CCS의 font-size 속성 값에 비례해서 결정되는 상대 단위입니다. 예를 들어, font-size: 16px인 경우, 상대 단위는 브라우저에 의해서 다음과 같이 계산됩니다.
여기서 font-size를 20px로 늘릴 경우, 상대 단위도 다음과 같이 비례해서 증가되게 됩니다.
반대로 font-size를 10px로 줄일 경우, 상대 단위도 다음과 같이 비례해서 감소되게 됩니다.
위와 font-size 값에 증감에 비례해서 유동적으로 길이가 결정되고 싶은 속성에 em이나 rem 단위를 사용해서 길이 지정을 해줄 수 있습니다.
em과 rem 단위의 기준은 font-size 속성 값이라고 했는데, 정확히 어디에 있는 font-size 속성 값인지에 따라 차이가 발생합니다. em의 경우, 해당 단위가 사용되고 있는 요소의 font-size 속성 값이 기준이 됩니다. 반면에 rem에서 r은 root, 즉 최상위 요소를font-size 속성 값 의미합니다. HTML에서 최상위 요소는 입니다. 따라서 rem 경우, html 요소의 font-size 속성 값이 기준이 됩니다.
예를 들어, 다음과 같이 html 요소의 font-size 속성 값이 16px이라고 가정해봅시다.
html {
font-size: 16px;
}
그리고 다음과 같이 div 요소가 스타일링 된다면 width 속성의 값은 200px이 됩니다. 왜냐하면 em은 해당 요소의 font-size에 비례해서 커지기 때문에 div 요소의 font-size인 20px에 10을 곱해야 합니다.
div {
font-size: 20px;
width: 10em; /* 200px */
}
하지만 다음과 같이 em 대신에 rem 단위를 이용해서 div 요소가 스타일링 된다면 width 속성값은 160px이 됩니다. 왜냐하면 rem은 html 요소의 font-size가 16px이기 때문에, 16px에 10을 곱해야 합니다.
div {
font-size: 20px;
width: 10rem; /* 160px */
}
다시 말해, rem 단위를 사용하면 해당 요소의 font-size 속성 값은 전혀 중요하지 않게 됩니다.
자 그럼 여기서 퀴즈! div 요소에서 font-size 속성을 제거하면 어떻게 될까요?
rem의 경우 원래부터 해당 요소의 font-size를 무시하기 때문에 달라질 게 없습니다.
div {
width: 10rem; /* 160px */
}
하지만 em을 사용할 경우, 약간의 상상력이 필요합니다. 왜냐하면 없는 font-size 속성 값을 고려해야 하기 떄문입니다. 어떤 요소에 font-size 속성이 정의되지 않은 경우 부모의 font-size 값을 그대로 상속받게 됩니다. 따라서, 아까 html 요소의 font-size가 16px가 div 요소의 font-size 값이 되고, 결국 width: 10em 값은 16px * 10 = 160px로 계산됩니다.
div {
width: 10em; /* 160px */
}
하지만 만약에 html 요소와 이 div 사이에 다른 요소들이 층층이 끼어 있으면 어떻게 될까요? (실제 이런 경우가 훨씬 많겠죠?) 예를 들어 header 요소가 이 둘 사이에 있고, 이 header 요소의 font-size가 30px이라면, 이 header 요소를 부모로 가지는 div 요소의 font-size도 상속이 되어 30px이되서 width 값을 300px로 만들 것입니다. 이건 그나마 난데, 만약 이 header 요소의 font-size가 절대 단위가 아닌 상대 단위를 사용하고 있다면 어떨까요? heaer의 font-size를 2rem이라고 한다면 16px x 2 = 32px로 계산될 것이고, div 요소의 font-size도 32px이되서 최종적으로 width 값이 320px이 될 것입니다.
이 처럼, em을 사용할 때는 font-size가 html 요소부터 시작해 여러 상위 요소들을 거치면서 상속될 수 있기 때문에 실제 어떤 값으로 계산될지 예측하기가 복잡할 때가 있습니다.
많은 CSS 가이드들이 em을 사용해야만 하는 타당한 이유가 없는 경우라면 가급적 rem을 우선적으로 쓰도록 권고하고 있습니다. (특히 초보자들에게…) 왜냐하면 em의 경우 위에서 보았듯이 실제 몇 px로 변환될지에 영향을 주는 변수가 많아지기 때문에, em을 사용해서 스타일된 요소의 경우 재사용이 어렵고 유지보수가 힘들어지는 경향이 있기 때문입니다.
출처 : https://www.daleseo.com/css-em-rem/
반응형 웹사이트를 만들기 위해 필요해 공부하고 적용했다.
CSS도 결국 끝이 없는거 같다는 느낌이다.
하나하나 쌓아가자