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으로 설정되었을 때, 2em32px(2×16px)가 된다. 

     

<p> 요소는 <body> 요소의 을 받으므로 텍스트의 크기 32px로 설정된다. 

     

font-size 속성(property)에는 em이나 % 모두 동일하게 작용한다. em의 수치에 100을 곱하면 %가 나오는 관계로 아주 심플하다. 그래서 첫 번째 <p> 요소의 font-size50% 이므로 이는 0.5em이고 16px가 된다. 그리고 두 번째 <p> 요소의 font-size1em 이므로 이는 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-size1em으로 하는 값이고 이 값은 다른 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 파일


아래는 본 포스팅의 내용을 갈무리하기 위한 Anki 파일입니다. 참고하시기 바랍니다. 


Ankilog 파일:  0044 CSS의 길이(length) 중 상대 길이(relative length).apkg


2019/01/03 pm 2:40 Ankilog 문구 일부 수정




0034 CSS 요소 선택자(element selector)


선택자CSS규칙(Rule)에서 어떤 HTML 요소(element)규칙을 적용할지 지정하는 역할을 하는 것으로 CSS 뿐만 아니라 jQuery에서도 사용하고 있어 알아두면 매우 유용하다.

    

선택자는 요소의 이름, 아이디(id), 클래스(class), 속성(attribute) 등 그 외에 수많은 방식으로 HTML 요소(element)를 선택하지만 이번에는 가장 기본적인 요소 선택자(element selector)를 살펴보자. 

    

요소 선택자(element selector)요소의 이름으로 해당 요소를 선택한다. 가령, <p> 요소는 p<body> 요소는 body<h1> 요소는 h1으로 선택한다. 

    

규칙선택자를 요소로 하면 해당 웹페이지의 모든 요소들은 일괄적으로 CSS 규칙이 적용을 받는다. 동일한 요소에서 스타일을 다르게 하는 방법은 나중에 논하도록 하자. 

   

우선, 다음과 같이 0034_1.html을 작성해보자. 

    

<!DOCTYPE html>

    

<html>

<head>

 <title>요소 선택자</title>

 <style></style>      내부가 비어 있음

</head>

<body>

 <h1>h1 블록</h1>

 <h2>첫 번째 h2 블록</h2>

 <p>p블록 시작 <br /><br />p블록 끝</p>

 <h2>두 번째 h2 블록</h2>

 <p>2번 p블록 시작 <br /><br />2번 p블록 끝</p>

</body>

</html>


<head> 섹션 내의 <style> 요소에는 어떤 CSS 규칙도 없는 상황이다. 실행해보면 다음과 같다.



CSS 규칙이 전혀 없어도 브라우저가 자체적인 기준으로 HTML 문서를 최소한으로 스타일링하고 있다. 즉, 글꼴(font)과 글자 크기 등이 설정되어 있다.

    

이번에는 요소를 선택하여 CSS 규칙을 적용해보자. 

    

HTML 문서에서 눈에 보이는 부분을 담당하는 영역인 <body>HTML의 요소이므로 이에 적용하는 CSS 규칙을 만들어 볼 수 있을 것이다. 그렇다면 요소 선택자는 body가 될 것이다. <style></style> 사이에 다음과 같이 넣고 이름을 바꿔 0034_2.html로 작성하여 실행해보자. 

    

body { 

 background-color: black; 

 color: white;

 font-family: Arial;

}


위의 구문을 말로 옮기면 이렇다. <body> 요소에 배경색(background-color)검게(black), 글자색(color)은 하얗게(white), 글꼴(font-family)Arial로 적용한다.

   

0034_2.html 파일을 실행한 결과를 처음의 0034_1.html과 같이 놓고 비교해보았다.



<body> 요소가 보이는 영역 전체이므로 웹페이지의 모든 배경색이 전부 검게 칠해진다. <h1>, <h2>, <p> 요소 모두 배경색(background-color)검게(black) 칠해지고 글자색(color)하얗게(white) 글꼴(font-family)Arial로 변경되었다. 

   

이는 <body> 요소에 적용된 규칙<body> 요소 내에 중첩(nesting)<h1>, <h2>, <p> 요소들에게 상속되기 때문이다. 자세하게 살피면 상속되는 속성이 있고 상속되지 않는 속성이 있지만 일단, 위의 예문에서 <body> 요소에 적용된 규칙은 모두 상속되고 있다.

    

만일, 상속된 속성을 사용하지 않고 각각의 <h1>, <h2>, <p> 요소들을 <body> 요소와 다르게 스타일링을 하고 싶다면 해당 요소를 선택자로 가진 규칙을 작성하여 상속을 재정의 하면 된다. 

    

이번에는 <h1><h2><p> 요소에 CSS 규칙을 작성하여 <style></style> 사이에 다음과 같이 넣고 0034_3.html로 작성하여 실행해보자. 

    

body

 background-color: black; 

 color: white;

 font-family: Arial;

}

h1 {

 background-color: white; 

 color: black;

}

h2 {

 background-color: white; 

 color: black;

}

p {

 background-color: yellow; 

 color: blue;

 font-family: serif;

}


실행 결과는 다음과 같다. 



<h1><h2> 요소는 배경색(background-color)검은색에서 하얀색(white)으로 바뀌었고 글자색(color)흰색에서 검은색(black)으로 변했다. 글꼴(font)은 별도로 지정한 바가 없으므로 <body> 요소의 Arial을 그대로 유지하고 있다. 

    

<p> 요소는 배경색(background-color)노랗게(yellow) 바뀌었고 글자색(color)파랗게(blue) 변했으며 글꼴(font)serif로 변경되었다. 

    

즉, <body> 요소에 적용된 규칙<body> 요소 내부의  <h1><h2><p>에 적용된 규칙과 같은 속성(property)에서 서로 다른  속성값을 갖는 경우 각각의 요소에 적용된 규칙의 속성이 우선적으로 적용되는데 이것을 이용하여 상속을 재정의 한다.

    

위에서 <h1><h2> 요소의 CSS 규칙동일하다. 이런 경우에는 다음과 같이 요소들끼리 쉼표로 구분하여 규칙을 한꺼번에 작성할 수 있다. 

    

h1, h2 {

 background-color: white; 

 color: black;

}


CSS에서 border 속성(property)블록 주위에 경계선을 넣는 속성으로 다음과 같이 쓴다.

    
border: 5px solid red;  
→ 경계선을 5픽셀(5px) 두께에 빨간색(red) 실선(solid)으로

<h1><h2> 요소의 CSS 규칙이 동일한 상황에서 추가적으로 <h2> 요소에만 별도로 border 속성(property)를 부여한다고 해보자. 이런 경우 다음과 같이 별도로 작성하는 규칙만 따로 떼어내서 규칙을 작성하면 된다. 
   

h1, h2 {

 background-color: white; 

 color: black;

}

h2 { border: 5px solid red; }


작성한 0034_4.html파일을 실행하면 다음과 같다. 




Anki 파일


아래는 본 포스팅의 내용을 갈무리하기 위한 Anki 파일입니다. 참고하시기 바랍니다. 


Ankilog 파일:  0034 CSS 요소 선택자(element selector).apkg







+ Recent posts