상속과 단계적 상속

개요

이 가이드는 상속과 단계적 상속을 설명한다. CSS에서 두 가지 기본 개념이다.

소개

상속과 단계적 상속은 CSS에서 두 개의 기본 개념이다. 이해하는 것이 중요하다. 두 개념은 밀접한 관련이 있다. 그러나 다르다:

  • 상속은 HTML 마크업의 요소가 자신의 부모(포함하고 있는) 요소 속성을 상속 받고 자식에게 전달하는 방법과 관련이 있다.
  • 단계적 상속은 문서에 적용되고 있는 CSS 선언 그리고 충돌하는 규칙을 적용하는 방법 또는 규칙들이 서로 재정의(override) 되지 않는 방법과 관련이 있다.

이 강좌는 두 개념의 개요를 제공한다. 이 문서의 예제 코드 Download the source code for the examples; ZIP 파일은 완성된 CSS 및 HTML을 포함한다. 마찬가지로, 예제를 따라가는 동안 처음의 HTML 템플릿도 사용할 수 있다.

상속 (Inheritance)

상속은 유전학과 같은 방식으로, 특정 속성이 부모 요소에서 자식 요소로 전달되는 방식이다: 부모가 파란 눈이면, 자식도 아마 파란 눈일 것이다.

모든 CSS 속성이 상속되지는 않는다. 상속되면 말이 되지 않는 것이 있기 때문이다. 예를 들어, margins 및 width는 상속되지 않는다. 자식 요소는 부모와 같은 마진이 필요하지 않을 것 같기 때문이다. 사이트의 내용 블록을 브라우저 창 폭의 70%로 설정하고, 그리고 이것의 모든 자식이 부모 요소의 70% 폭을 채택한다고 상상해 보자. CSS로 페이지 레이아웃을 디자인 하는 것은 악몽이 될 것이다.

대부분의 경우에, 상식적으로 어떤 속성이 상속되고, 안 되는지 알 수 있다: 확실하지 않다면, CSS 2.1 specification property summary table 에서 CSS2에서 제시되는 모든 속성을 살펴보자. CSS3 속성은, 개개의 CSS3 모듈 명세를 참고하자. CSS current work page 참조.

왜 상속이 유용한가

CSS는 상속이라는 방법을 가지고 있다. 상속이 없었다면 CSS 규칙은 쓸모 없을 것이다. 상속의 개념이 없었다면, 글꼴, 글씨크기, 글 색상 같은 스타일을 – 모든 요소들에 대해 – 각각 지정해야 할 것이다. 코드는 불어나고 반복될 것이다.

상속을 사용하면, html 또는 body 요소의 글꼴 속성을 지정할 수 있고, 그 스타일은 모든 요소가 상속받을 것이다. 특정 컨테이너 요소의 배경색과 글 색상을 지정할 수 있다. 그리고 글 색상은 콘테이너의 모든 자식 요소에 자동으로 상속될 것이다. 배경색은 상속되지 않는다. 그러나 background-color 의 초기 값은 transparent 하다. 이것은 부모의 배경색이 나타남을 의미한다. 배경색이 상속된다면, 그 효과는 페이지의 모습과 비슷할 것이다.

주의: 배경 images 가 상속된다면 어떤 일이 일어날지 생각해보자. 모든 자식은 부모와 같은 배경 이미지를 표시할 것이다. 그 결과는 심각한 마약 문제가 있는 사람이 조립한 조각 그림 맞추기 같이 보일 것이다. 이후의 각 자식 요소 안에 배경 이미지가 다시 그려질 것이기 때문이다.

상속의 작동 원리 (How inheritance works)

HTML 문서의 모든 요소는 부모의 상속 가능 속성을 모두 상속받는다. 부모가 없는 root 요소 (<html>) 는 제외한다.

상속된 속성이 적용될지의 여부는 다른 것들에 달려있다. 나중에 단계적 상속에 관한 섹션에서 설명된다. 파란 눈의 어머니는, 아버지가 갈색 눈이라면, 갈색 눈의 자식을 가질 수 있듯이, CSS에서 상속된 속성은 무시(override)될 수 있다.

상속의 예

  1. 텍스트 편집기로 다음 HTML 문서를 새 파일로 복사하고, inherit.html로 저장한다.

    웹 브라우저에서 이 문서를 열면, 브라우저의 기본 스타일에 따라 다소 지루한 문서를 볼 수 있을 것이다.

  2. 텍스트 편집기에서 새 파일을 만들고, 다음 CSS 규칙을 복사하고, HTML 파일과 같은 위치에 style.css로 저장한다.

  3. </head> 태그 앞에 다음 행을 삽입하여, 스타일 시트를 HTML 문서에 연결한다:

  4. 수정된 HTML 파일을 저장하고 브라우저에서 이 문서를 다시 로드한다.

글꼴이 브라우저의 기본 글꼴(보통 Times 또는 Times New Roman으로 설정)에서 Verdana로 변경된다.

당신의 컴퓨터에 Verdana 글꼴이 설치되어 있지 않다면, 텍스트는 브라우저 설정에서 지정한 기본 sans-serif 글꼴로 표시된다. 그 밖에 텍스트는 더 작아진다; 스타일이 적용되지 않은 크기의 단지 3/4 이다. CSS 규칙은 <html> 요소에만 적용된다. 제목과 단락에는 어떤 규칙도 지정하지 않았다. 그러나 모든 텍스트는 지금 기본 크기의 75% 크기의 Verdana 글꼴로 표시된다. 왜? 상속 때문이다. font 속성은 축약 (shorthand) 속성이다. 이 축약 속성은 글꼴과 관련된 모든 속성들을 한 번에 설정한다.

CSS 규칙에서 두 속성만을 지정하였다 – 글꼴 크기와 글꼴 — 그러나 이 규칙은 다음과 동일하다:

이 속성 모두 상속되므로, <body> 요소는 <html> 요소로 부터 이 속성들을 상속 받고 자식 – 제목과 문단 – 에게 전달한다. 그러나 글꼴 크기 상속과 관련하여 특이한 일이 발생한다는 사실에 주목하자.

<html> 요소의 글꼴 크기는 75%로 설정되지만, 무엇 의 75%인가? 분명하게 <body> 의 글꼴 크기는 부모 글꼴 크기의 75%이고, 제목과 문단의 글꼴 크기는 <body> 요소의 75% 이어야 하는가? 상속된 값은 지정된 값이 아니라 — 스타일 시트에 입력한 값 — 계산된 값이다.

계산된 값은, 글꼴의 경우에, 픽셀로 계산된 절대 값이다.<html> 요소는 상속받을 부모 요소가 없다. 글꼴 크기의 퍼센트 값은 브라우저에서 설정된 기본 글꼴 크기와 관련이 있다. 현대의 대부분의 브라우저는 기본 글꼴로 16 픽셀을 설정한다. 16의 75%는 12이므로, <html> 요소의 계산된 글꼴 크기는 약 12픽셀이다.

이것이 <body> 가 상속받은 값이고, 제목과 문단에 전달된다. (제목의 글꼴 크기는 더 크다, 브라우저는 자신의 내장 스타일을 일부 적용하기 때문이다. 자세한 내용은 아래의 단계적 상속에 관한 섹션을 참조하자.)

이 예제를 생각해보자:

  1. 스타일 시트 규칙에 두 개의 선언을 더 추가한다:

  2. CSS 파일을 저장하고 브라우저에서 문서를 다시 로드한다. 이제 전체 문서의 배경은 밝은 파란색이고, 모든 텍스트는 흰색이다. 흰색 텍스트 색상은 <body> 요소가 상속받는다. 그리고 body 의 모든 자식들에게 전달된다 — 이 경우에는 제목과 단락이다. 그러나 제목과 단락은 배경색은 상속받지 않는다. 그러나 대신에 기본은 transparent 이다. 그래서 보이는 결과는 파란색 배경에 흰색 텍스트로 표시된다.

  3. 스타일 시트에 새 규칙을 하나 더 추가한다:

  4. 저장하고 문서를 다시 로드한다: 이 규칙은 제목의 글꼴 크기를 설정한다. 앞에서 논의한 바와 같이 상속 받은 글꼴 크기 12 픽셀에 퍼센트가 적용된다 — 그러므로 제목의 크기는 12 픽셀의 300%, 또는 36 픽셀이 된다.

강제 상속 (Forcing inheritance)

강제로 상속할 수 있다 — 기본으로 상속되지 않는 속성들도 — inherit 키워드를 사용하여. 그러나 사용에 주의하자. 왜냐하면 이 키워드는 IE 7 이하 버전에서는 지원되지 않는다.

다음 규칙은 모든 문단에 부모의 배경 속성을 상속시킨다.:

강제 상속은 일반적인 관행은 아니다. 이것은 충돌하는 규칙에서 한 선언을 “취소(undoing)”하거나, 또는 특정 값을 하드 코딩(hard coding)하지 않도록 하는데 유용하다. 예제로, 전형적인 검색 메뉴를 고려해보자:

이 링크 목록을 가로 메뉴로 표시하려면, 다음 CSS 규칙을 사용할 수 있다:

여기에서 전체 목록의 배경색이 #nav 규칙의 파란색이 설정된다. 이것은 또한 전경색은 흰색으로 설정한다. 그리고 이 속성은 각각의 목록과 각각의 링크에 상속된다. 목록 항목에 대한 규칙은 오른쪽 경계를 설정한다. 그러나 경계색을 지정하지는 않는다. 상속된 전경색인 흰색을 사용한다는 의미이다. 링크에 대해서는, color:inherit; 로 강제 상속을 하고, 브라우저의 기본 링크 색을 무시한다.

물론, 경계색을 흰색으로 그리고 링크 텍스트 색도 흰색으로 지정할 수 있다. 그러나 상속이 일어나도록 하는 것의 아름다움은, 나중에 색 구성표를 수정하고자 한다면, 색을 변경하기 위해 한 곳만 수정하면 된다는 것이다.

단계적 상속 (The cascade)

CSS는 Cascading Style Sheets의 약어이다. 단계적 상속이 중요한 개념이라는 것은 놀라운 일이 아니다. 이것은 여러 개의 충돌하는 CSS 선언이 같은 요소에 적용될 때, 최종 결과를 제어하는 방법이다. 적용되는 CSS 선언의 순서를 제어하는 세 가지 주요 개념이 있다:

  1. 중요성 (Importance)
  2. 구체성 (Specificity)
  3. 소스 순서 (Source order)

이 개념은 아래에서 설명된다.

중요성은 가장 중요하다. 두 개의 선언의 중요성이 같다면, 규칙의 구체성으로 적용될 규칙을 결정한다. 규칙의 구체성이 같다면, 소스 순서가 결과를 제어한다.

중요성 (Importance)

CSS 선언의 중요성은 선언이 명시된 위치 에 따라 다르다. 충돌하는 선언은 다음 순서로 적용된다. 나중의 선언이 앞선 선언을 무시(override)한다:

  1. 사용자 에이전트 스타일 시트 (User agent style sheets)
  2. 사용자 스타일 시트의 일반 선언 (Normal declarations in user style sheets)
  3. 작성자 스타일 시트의 일반 선언 (Normal declarations in author style sheets)
  4. 작성자 스타일 시트의 중요 선언 (Important declarations in author style sheets)
  5. 사용자 스타일 시트의 중요 선언 (Important declarations in user style sheets)

사용자 에이전트 스타일 시트 (User agent style sheets)

사용자 에이전트 스타일 시트는 브라우저의 내장 스타일 시트이다. 모든 브라우저는 페이지 사용자 또는 디자이너가 스타일을 지정하지 않을 경우에, 다양한 HTML 요소를 표시하는 방법에 대한 기본 규칙을 가지고 있다. 예를 들어, 방문하지 않은 링크는 보통 파란색이고 밑줄이 있다.

사용자 스타일 시트는 사용자(user) 가 지정한 스타일 시트이다. 모든 브라우저가 사용자 스타일 시트를 지원하지는 않는다. 그러나 특히 특정 장애가 있는 사람에게는 매우 유용하다. 예를 들어, 난독증의 사람은, 더 읽기 쉽도록, 특정 글꼴과 색상을 지정하는 스타일 시트를 가지고 있을 수 있다.

작성자 스타일 시트는 우리가 일반적으로 “스타일 시트”라고 말하는 것이다. 문서의 저자 (또는 아마 웹 사이트 디자이너)가 작성하고, 연결한 (또는 포함시킨) 스타일 시트이다.

일반 선언과 중요 선언 (Normal and important declarations)

일반 선언은 그냥 일반 선언이다.

반대가 중요 선언이다. 뒤에 !important 명령이 있는 선언이다. 예를 들어, 난독성 사용자는 모든 텍스트를, 더 읽기 쉬운 글꼴이라면, Comic Sans MS로 표시하기를 원할 수 있다. 그러면 다음 규칙을 포함하는 사용자 스타일 시트를 가지고 있을 수 있다:

사용자 스타일 시트에 있는 중요 선언은 모든 것에 우선한다. 이것은 논리적이다. 이 경우에, 디자이너가 무슨 글꼴을 지정하였든, 또는 브라우저의 기본 글꼴이 무엇으로 설정되었든지 모든 것은 Comic Sans MS 글꼴로 표시된다. 사용자 스타일 시트 또는 작성자 스타일 시트가 무시하지 않는 선언인 경우에만 브라우저의 기본값이 적용된다. 왜냐하면, 사용자 에이전트 스타일 시트가 가장 낮은 우선권을 가지기 때문이다.

솔직히, 대부분의 디자이너는 중요성(importance)에 관하여 그렇게 많이 생각하지 않는다. 중요성에 관하여 우리가 할 수 있는 일이 아무 것도 없기 때문이다. 우리는 사용자가 CSS를 무시하는 사용자 스타일 시트를 가지고 있는지 알 수 있는 방법이 없다. 그들이 가지고 있다면, 아마도 그렇게 하는 충분한 이유가 있을 것이다. 하지만, 중요성이 무엇인지, 그리고 문서를 표시할 때 어떻게 영향을 미치는지 아는 것이 좋다.

구체성 (Specificity)

구체성은 모든 CSS 작성자가 이해하고 생각해야 하는 일이다. 이것은 규칙의 선택자가 얼마나 구체적인 가를 측정하는 수단으로 생각될 수 있다. 구체성이 낮은 선택자는 많은 요소 (문서의 모든 요소를 지정하는 * 와 같이)를 지정한다. 반면 구체성이 높은 선택자는 페이지에서 단 하나의 요소 (nav 이란 id 를 가지고 있는 요소 만을 지정하는 #nav 같이) 만을 지정한다.

선택자의 구체성은 쉽게 계산된다. 아래에서 살펴볼 것이다. 주어진 요소에 대해 두 개 또는 세 개의 선언이 충돌하고, 모든 선언의 중요성도 같다면, 규칙 중에서 가장 구체적인 선택자가 “지정(win)”된다.

구체성은 네 개의 구성요소를 가진다; 그것들을 a, b, c , d 라고 하자. 구성요소 “a” 가 가장 구체적이고, “d” 가 가장 덜 구체적이다.

  • 구성요소 “a” 는 아주 간단하다: style (인라인 스타일링으로 알려져 있다) 속성에서 선언한 것이면 1, 아니면 0이다.
  • 구성요소 “b” is 는 선택자에 있는 id 선택자 숫자이다 (# 으로 시작한다).
  • 구성요소 “c” 는 속성 선택자 – 클래스 선택자 포함 – 와 가상 클래스의 숫자이다.
  • 구성요소 “d” 선택자에 있는 요소 유형과 가상 요소의 숫자이다.

조금 계산한 후에, 모든 규칙의 구체성을 계산하기 위해 네 개의 구성성분을 문자로 표시한다. style 속성에 있는 CSS 선언에는 선택자가 없다. 그러므로 이것의 구체성은 항상 1,0,0,0 이다.

몇 가지 예를 살펴보자 — 이 후 이것이 어떻게 작동하는지 명확해져야 한다.

Selector a b c d Specificity
h1 1 0,0,0,1
.foo 1 0,0,1,0
#bar 1 0,1,0,0
html>head+body ul#nav *.home a:link 1 2 5 0,1,2,5

마지막 예제를 더 자세히 살펴보자. style 속성에 있는 선언이 아니고, 선택자이므로 a = 0 이다. 하나의 ID 선택자 (#nav) 가 있다. 그러므로 b = 1. 하나의 속성 선택자 (.home) 와 하나의 가상 클래스 (:link ) 가 있다. 그러므로 c = 2. 5개의 요소 유형 (<html>, <head>, <body>, <ul> and <a>) 가 있다. 그러므로 d = 5.

그러므로 최종 구체성은 0,1,2,5 이다.

참고: 연결자 (>, +, 공백과 같은)는 선택자의 구체성에 영향을 미치지 않는다. 일반 선택자 (*) 도 마찬가지로 구체성에 영향을 미치지 않는다.

참고 #2: id 선택자와 id 속성을 참조하는 속성 선택자는 구체성에서 많은 차이가 있다. 이것들이 같은 요소를 지정하지만, 이것들은 구체성이 매우 다르다. #nav 의 구체성은 0,1,0,0 이고, [id="nav"] 은 0,0,1,0 이다.

실제로 어떻게 작동하는지 살펴보자.

  1. 우선, HTML 문서에 문단 하나를 추가한다.

  2. 다음으로, 문단의 텍스트를 다른 색상으로 바꾸기 위해 스타일 시트에 규칙을 추가한다:

  3. 이제 두 파일을 저장하고 브라우저에서 문서를 다시 로드한다; cyan 글꼴의 두 문단이 있어야 한다.

  4. 첫 째 문단에 id 를 넣어, CSS 선택자로 쉽게 목표 대상으로 설정할(target) 수 있게 한다.

  5. 스타일 시트에서 특정 문단에 규칙을 추가한다:

  6. 마지막으로, 두 파일을 저장하고, 브라우저에서 문서를 다시 로드한다. 이제 훨씬 화려하게 보인다.

두 문단에 적용된 선언을 살펴보자.

추가된 첫 번째 규칙은 모든 문단에 cyan 글꼴 색을 설정한다. 두 번째 규칙은 special 이라는 id 를 가지고 있는 하나의 요소에 빨간색 배경과 노란 글꼴 색을 설정한다. 첫 번째 문단은 두 규칙이 모두 지정된다; 이것은 문단이고, special 이라는 id 를 가지고 있다.

빨간색 배경은 문제가 되지 않는다. 이것은 #special 에만 지정되기 때문이다. 두 규칙은 color 속성 선언을 포함하고 있다. 하지만, 이것은 충돌이 있음을 의미한다. 두 규칙은 중요성도 같다 — 이것들은 작성자 스타일 시트에 있는 일반 선언이다 – 그러므로 두 선택자의 구체성을 살펴보아야 한다.

첫 번째 규칙의 선택자는 <p> 이다. 이것은 위 규칙에 따라 구체성이 0,0,0,1 이다. 하나의 요소 유형을 포함하고 있기 때문이다. 두 번째 규칙의 선택자는 #special 이다. 이것은 구체성이 0,1,0,0 이다. id 선택자를 구성하고 있기 때문이다. 0,1,0,0 은 0,0,0,1 보다 훨씬 구체적이다. 그러므로 color: yellow; 선언이 표시(win)되어 빨간색 배경에 노란색 글꼴이 된다.

소스 순서 (Source order)

두 개의 선언이 같은 요소에 영향을 주면서 중요성과 구체성이 같다면, 최종적으로 구별하는 기준은 소스 순서이다. 스타일 시트에서 나중에 나타나는 선언이 앞에 있는 것을 무시(override)하고 “표시(win)”된다.

하나의 외부 스타일 시트를 가지고 있다면, 충돌이 있다면, 그 파일의 끝에 있는 선언이 그 파일 앞에 있는 선언들을 무시한다. 충돌하는 선언은 다른 스타일 시트에서도 있을 수 있다.

이 경우에는, 스타일 시트가 링크되고, 포함되고, 가져온 순서에 의해 어떤 선언이 적용될 지 결정된다. 그러므로 한 문서 <head> 에 링크된 두 개의 스타일 시트를 가지고 있다면, 더 아래 링크된 것이 위에 링크된 것을 무시한다. 이것이 어떻게 작동하는지 실제 예제를 살펴보자.

  1. 이와 같이, 스타일 시트 파일 맨 끝에 새 규칙을 추가한다:

  2. 저장하고 웹 페이지를 다시 로드한다. 이제 모든 문단 지정된 두 개 의 규칙이 있다. 이것들은 중요성과 구체성이 같다 (선택자가 같기 때문이다). 그러므로 어떤 것을 적용할 지를 결정하는 최종 방법은 소스 순서이다. 마지막의 규칙은 color:black 을 지정하고 있고, 이것은 이전의 규칙 color:cyan 을 무시할 것이다.

이 규칙으로 첫 번째 문단이 어떻게 아무런 영향을 받지 않는지를 참고하자.

마지막에 새 규칙이 있지만, 이것의 선택자는 #special 보다 구체성이 낮다. 이것으로 구체성이 소스 순서 보다 우선한다는 것을 명확하게 알 수 있다.

개요

상속과 단계적 상속은 모든 웹 디자이너가 이해해야 하는 기본 개념이다.

상속은 높은 수준의 요소 속성을 선언하게 하고, 이 속성들이 아래로 전달되어 후손 요소들의 스타일에 적용된다. 일부 속성만이 기본으로 상속되지만, 상속은 inherit 키워드로 강제 상속될 수 있다.

단계적 상속은 다수의 선언이 같은 요소에 영향을 미칠 때 모든 충돌요인을 구분해낸다. 중요한 선언은 덜 중요한 선언을 무시한다. 중요성이 같은 선언은 규칙의 구체성으로 어떤 선언을 적용할 지 결정된다.

모든 조건이 같다면, 소스 순서가 최종 결정요인이다.

참고 사항

외부 대상 (External resources)

CSS Cascade and Inheritance 슬라이드

<iframe src=”http://www.slideshare.net/slideshow/embed_code/1658158” width=”427″ height=”356″ frameborder=”0″ marginwidth=”0″ marginheight=”0″ scrolling=”no” style=”border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px” allowfullscreen> </iframe>

<iframe src=”http://www.slideshare.net/slideshow/embed_code/1772232” width=”427″ height=”356″ frameborder=”0″ marginwidth=”0″ marginheight=”0″ scrolling=”no” style=”border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px” allowfullscreen> </iframe>

연습 문제

  • border 속성은 상속되나? 우선 생각해 보자 —말이 되는지? — 그리고 CSS specification 에서 정확한 답을 찾아보자.
  • example style sheet 의 최종 규칙에 있는 color:black 선언에 !important 를 추가한다면, 첫 번째 “special” 문단의 글꼴 색상에 어떤 영향을 미칠까?
  • 어떤 선택자가 더 구체적인가, “#special” 또는 “html>head+body>h1+p”?
  • 작성자 스타일 시트와 관계 없이, 테스트 문서를 흰색 배경에 검은색 Comic Sans MS 글꼴로 표시하려면, 사용자 스타일 시트를 어떻게 작성해야 하나?

답글 남기기