0044 CSS의 길이(length) 중 상대 길이(relative length)
앞에서 CSS의 절대 길이(absolute length)를 다루면서 웹페이지는 모니터 스크린에 구현되므로 절대 길이(absolute length) 중에서 픽셀(px)을 자주 사용한다는 점에 대해서 언급했다. 하지만 절대 길이(absolute length) 보다는 상대 길이(relative length)를 사용하는 경우가 훨씬 더 많다.
상대 길이(relative length)란 것은 다른 기준이 되는 길이에 비례하여 결정되는 길이를 말한다. 여기에서 기준이 되는 길이를 어떤 것으로 잡느냐에 따라서 다양한 상대 길이(relative length)가 나온다.
W3C의 튜토리얼에서 상대 길이(relative length)로 제시하는 단위들은 다음과 같다.
em, ex, ch, rem, vw, vh, vmin, vmax, %
각각의 설명은 다음과 같다.
em : 현재 요소의 텍스트 크기를 1em으로 하는 단위
ex : 현재 텍스트 크기에서 소문자 x의 높이를 1ex로 하는 단위
ch : 현재 텍스트 크기에서 숫자 "0"의 너비를 1ch로 하는 단위
rem : 루트 요소의 텍스트 크기를 1rem으로 하는 단위이다.
vw : 화면(viewport) 너비(width)의 1%를 1vw로 하는 단위
vh : 화면(viewport) 높이(height)의 1%를 1vh로 하는 단위
vmin : 1vw와 1vh 중 작은 쪽을 1vmin으로 하는 단위
vmax : 1vw와 1vh 중 큰 쪽을 1vmax로 하는 단위
% : 부모 요소의 텍스트 크기에 비례하는 단위 (이 부분은 조금 잘못되었다.)
이 중에서 ex, ch, rem은 많이 사용하지 않는 단위들이고 vw, vh, vmin, vmax는 화면(viewport) 크기를 기준으로 상대적인 크기를 갖는 단위이므로 다음 기회에 살펴보고 가장 자주 사용하는 em과 %만 자세히 살펴보자.
최근 CSS 관련 포스팅을 하지 못하고 있는 이유는 em과 %의 개념이 헷갈려 이것 저것 찾다가 결국 결론을 내리지 못했기 때문이다.
em과 %에 대한 W3C 튜토리얼의 정의는 다음과 같다.
em : 현재 요소의 텍스트 크기를 1em으로 하는 단위
% : 부모 요소의 텍스트 크기에 비례하는 단위
이 설명은 정확하지 않다. 위의 설명에 따르면 em과 % 모두 텍스트 크기를 기준으로 작동한다고 설명하고 있지만 실험해보면 em은 확실히 텍스트 크기를 기준으로 작동한다. 하지만 퍼센트(%)는 다양한 기준이 있다. 가령 다음과 같은 HTML을 작성해서 0044.html로 저장하고 실행해보자. (0044example.zip
<!DOCTYPE html>
<html>
<head>
<title>relative size</title>
</head>
<body style="font-size: 2em;">
<p style="font-size: 50%;">
첫 번째 p요소의 폰트 사이즈는 50%인 16px
</p>
<p style="font-size: 1em;">
두 번째 p 요소의 폰트 사이즈는 1em인 32px<br />
이미지는 높이 3em, 너비 100%<br />
<img src="sun.jpg" style="height: 3em; width: 100%;" alt="sun" />
</p>
</body>
</html>
모든 브라우저의 기본 텍스트 크기는 보통 16px로 설정되어 있다.
따라서 <body> 요소에 적용되는 텍스트의 크기는 16px이고 이 상황에서 텍스트의 크기를 2em으로 설정되었을 때, 2em은 32px(2×16px)가 된다.
<p> 요소는 <body> 요소의 상속을 받으므로 텍스트의 크기는 32px로 설정된다.
font-size 속성(property)에는 em이나 % 모두 동일하게 작용한다. em의 수치에 100을 곱하면 %가 나오는 관계로 아주 심플하다. 그래서 첫 번째 <p> 요소의 font-size는 50% 이므로 이는 0.5em이고 16px가 된다. 그리고 두 번째 <p> 요소의 font-size는 1em 이므로 이는 100%이고 32px가 된다. W3C에서 제시한 설명은 %는 부모 요소의 텍스트 크기를 기준으로 하고 em은 현재 요소의 텍스트 크기를 기준으로 한다고 설명되어 있지만 실제 font-size에 적용해보면 부모 요소를 기준으로 하거나 현재 요소를 기준으로 하는 경우에도 차이가 없다.
하지만 우리가 지금 이야기하고 있는 것은 텍스트의 크기 뿐만 아니라 상대 길이(relative length)에 대하여 이야기하고 있는 것이므로 이 상대 길이를 다른 것에 적용할 때 어떻게 달라지는지 살펴볼 필요가 있다.
0044.html에는 <p> 요소 내부에 <img /> 요소를 중첩시켜 놓았다.
그리고 그 <img /> 요소의 크기(size)는 style="height: 3em; width: 100%;" 으로 높이가 3em이고 너비가 100%로 규정해놓았다. W3C에서 제시한 바에 따르면 이런 경우 너비는 <p> 요소의 텍스트 크기인 32px가 되어야 할 것이다.
이제 0044.html을 실행해보자.
가장 위의 첫 번째 <p> 요소는 텍스트 크기가 16px로 설정되어 있고, 그 아래의 두 번째 <p> 요소는 32px로 나타난다. 텍스트 크기를 결정하는 font-size 속성(property)에서는 em과 %는 완전히 동일하게 작동한다.
하지만 이미지의 크기에서는 전혀 다르다. 위의 결과에서 이미지의 높이는 3em으로 설정되어 있다. 해당 이미지의 여백까지 생각하면 얼추 96px(3×32px)로 제대로 작동하고 있는 것 같다. 하지만 너비(width)는 100%이므로 32px가 되어야 하는데 가로폭을 완전히 차지하는 모양으로 나타난다.
이는 브라우저 창의 가로폭을 이리저리 변화시켜 보아도 이미지는 항상 가로폭 전체에 걸쳐 나타나도록 변형되는 것을 다음과 같이 확인할 수 있다.
이는 결국, <img /> 요소의 너비로 부과된 100%가 브라우저 창의 가로폭 전체를 의미한다는 것을 알 수 있다. 즉, W3C에서 설명한 것과는 다르게 부모 요소의 텍스트 크기를 반영하는 것이 아니라 너비처럼 해당 CSS 속성(property)에 설정된 별도의 기준이 작동하는 것을 알 수 있다.
반대로, em은 <img /> 요소의 크기를 결정하는 상대 길이(relative length)를 결정할 때에도 font-size를 기준으로 해당 크기를 적용하고 있다.
이외에도 이리저리 실험을 계속해본 결과 다음과 같은 사실을 알게 되었다.
em은 기존의 설명대로 현재 요소의 텍스트 크기를 1em으로 하는 단위라고 하면 된다. 하지만 %는 부모 요소의 텍스트 크기가 아닌 그냥 %가 쓰이는 해당 속성(property) 크기에 비례하는 단위로 수정하면 타당하다.
em은 해당 요소의 font-size를 1em으로 하는 값이고 이 값은 다른 CSS 속성에도 그대로 적용할 수 있다. 즉, 다른 CSS 속성의 길이(length)가 해당 요소의 텍스트 크기에 따라서 상대적인 길이로 조정되는 것이다.
하지만 %는 각각의 CSS 속성 별로 정해진 별도의 길이를 기준으로 작동한다. font-size 속성에서는 %의 기준이 부모 요소의 font-size 속성값을 기준으로 비례하지만 해당 %를 width로 가져가면 이는 부모 요소의 width 속성값을 기준으로 비례하지 해당 요소의 font-size 속성을 기준으로 비례하지 않는다. 또, %는 어떤 경우에는 작동하지 않는 것 처럼 보이기도 한다.
가령, CSS에서 border 속성에 경계선의 두께를 %로 주면 경계선이 나타나지 않는다. 즉, 다음과 같은 경우다.(참조 0044_1.html)
<p style="border: 100% solid red;">첫 번째 p 요소</p>
<p style="border: 1em solid red;">두 번째 p 요소</p>
실행해보면 다음과 같이 두 번째 <p> 요소에만 경계선이 1em 두께로 나타나는데 결론적으로 말하면 부모 요소인 <body> 요소에 경계선이 없어 두께가 0px이므로 이를 기준으로 하는 % 길이도 같이 0px가 되어 경계선이 나타나지 않는 것이다.
이리저리 실험해보고 내리고 생각해본 결과 em과 %의 차이를 나름 정리해보았다. 결국, W3C에서 em을 기준으로 작성하라고 권고하는 이유도 em이 텍스트의 크기를 기준으로 다른 CSS 속성(property)의 길이를 모두 규정할 수 있어 일관되면서도 광범위하게 사용할 수 있기 때문이 아닌가 싶다.
이 내용들은 명쾌하고 믿을만한 자료를 찾지 못해서 임의로 이것저것 실험해보고 스스로 개인적인 확신으로 결론을 내렸으니 주의하시기 바랍니다.
아래는 본 포스팅의 내용을 갈무리하기 위한 Anki 파일입니다. 참고하시기 바랍니다.
Ankilog 파일: 0044 CSS의 길이(length) 중 상대 길이(relative length).apkg
2019/01/03 pm 2:40 Ankilog 문구 일부 수정