CSS 이야기: 속성 정의(property definitions)

W3C가 제정한 CSS 권고안(규격)의 핵심이 바로 속성 정의와 그에 따른 설명입니다. 각각의 속성들이 어떻게 해석되고 적용되는지를 알기 위해서 속성 정의를 살펴볼 때가 많은데 CSS 권고안이 기본적으로 CSS를 작성하는 웹 제작자와 CSS를 구현하는 사용자 에이전트 제작자 모두를 대상으로 작성되었기 때문에 해석하기 까다로운 부분이 있습니다. CSS 2.1 권고안CSS 2.1을 소개하면서 속성 정의를 해석하는 방법을 설명하고 있는데 이 문서를 간략하게 설명해보겠습니다.

속성 정의 형식

속성 정의는 다음과 같은 형식으로 구성되어 있습니다.

'property-name'
   Value:		허용되는 값이나 문법
   Initial:		초기 값
   Applies to:		적용 대상
   Inherited:		상속 여부
   Percentages:		퍼센트 값 해석 방식
   Media:		속성이 적용되는 media 유형
   Computed value:	산출 값

Value (허용되는 값이나 문법)

속성에 사용될 수 있는 유효한(valid) 값을 의미합니다. 아래처럼 값의 유형에 따라서 표기 형식이 약간씩 다릅니다.

  1. 키워드 값 (auto, disc 등)
  2. 기본 자료형 (<length>, <percentage> 등)
  3. 특정 속성과 동일한 허용 값을 갖고 이름도 같은 값 유형 (<'border-width'> 등)
  4. 특정 속성을 직접 나타내지 않고 적용되는 값만 정의하는 값 유형(<border-width> 등)

3번과 4번 유형은 비슷하게 표현되지만 차이가 있습니다. 즉, <border-width>는 특정한 속성 값(thin, medium, thick, <length>)만을 정의하는 독자적인 값 유형입니다. 반면에 <'border-width'>CSS border-width 속성에 허용되는 값과 동일한 값을 나타내는 값 유형으로 <border-width>를 값으로 갖습니다(inherit는 포함되지 않습니다).

비슷한 값 유형을 이렇게 따로 정의한 이유는 속성 정의를 최대한 간단히 표현하기 위해서라고 생각합니다. XML DTD에 사용되는 파라미터 엔티티(Parameter Entity) 선언처럼이요. 예를 들어서 CSS에는 border-width 뿐 아니라 border-top-width, border-right-width, border-bottom-width, border-left-width 속성이 따로 있습니다. 이 각각의 속성마다 앞서 열거한 값(thin 등) 대신 <border-width>를 쓰면 중복을 줄일 수 있고 각각의 값에 대한 설명도 반복할 필요가 없습니다. 또한, border-width 속성은 최소 1개부터 최대 4개까지의 값(각각 top, right, bottom, left를 의미)을 가질 수 있기 때문에 의미상으로도 <border-width>와 일치하지 않습니다.

온라인 CSS 권고안에서 <'border-width'><border-width> 부분을 클릭해서 관련 속성이나 속성 값 유형을 직접 확인해보면 차이를 쉽게 알 수 있습니다.

값 나열 방식

값이 나열되는 방식에 따라서 허용되는 값이 달라집니다. 아래 네 가지 경우가 있습니다.

  • 값을 공백으로 구분해서 나열하면 모든 값을 순서대로 지정해야 합니다.
  • 값을 바(bar) 기호(|)로 구분해서 나열하면 나열된 값 중 한 개만 지정해야 합니다.
  • 값을 더블 바(double bar) 기호(||)로 나열하며 순서와 상관 없이 한 개 이상의 값을 지정해야 합니다.
  • 대괄호([])는 그룹을 나타냅니다.

border-top 속성을 예로 들면 다음과 같이 나열되어 있습니다.

'border-top'
    Value:  	[ <border-width> || <border-style> || <'border-top-color'> ] | inherit

[ <border-width> || <border-style> || <'border-top-color'> ] 그룹과 inherit가 |로 구분되어 있으므로 그룹이나 inherit 중 하나를 지정해야 합니다. 그룹은 ||로 나열되었기 때문에 <border-width>, <border-style>, <'border-top-color'> 중 한 개 이상이 반드시 지정되어야 합니다. 또 <border-width>이 실제로는 [ thin | medium | thick | <length> ]을 의미하기 때문에 그룹을 다시 세 개의 그룹으로 나누어서 해석할 수도 있습니다.

빈도 표현

값이 몇 번 지정되어야 하는지도 확인할 수 있는데 역시 네 가지 형식이 있습니다.

  • 별표(asterisk: *)는 값을 0번 이상 지정할 수 있음을 나타냅니다.
  • 더하기(plus: +)는 값을 한 번 이상 지정할 수 있음을 나타냅니다.
  • 물음표(question mark: ?)는 값이 선택 사항(0번이나 1번)이라는 것을 나타냅니다.
  • 줄괄호에 숫자 두 개를 지정하면({A,B}) 최소 A번, 최대 B번 지정할 수 있음을 나타냅니다.

border-width 속성과 font-family 속성을 예로 들어보겠습니다.

'border-width'
    Value:  	<border-width>{1,4} | inherit

'font-family'
    Value:  	[[ <family-name> | <generic-family> ] [, <family-name>| <generic-family>]* ] | inherit

border-width 속성은 <border-width> 값을 최소 한 개에서 최대 네 개까지 가질 수 있습니다(네 개인 경우 각각 top, right, bottom, left). 그리고 font-family 속성에는 세 개의 그룹이 있는데 가장 바깥쪽 그룹은 inherit와 그룹 중에서 하나를 지정해야 한다는 의미이고, 내부의 두 그룹은 각각 <font-name>이나 <generic-family> 중 하나가 지정된다는 뜻입니다. 그런데 두 번째 그룹에는 쉼표(,)가 앞에 있고, 끝에는 별표(*)가 있습니다. 또한, 두 그룹은 |나 || 없이 공백으로만 연결되어 있습니다. 따라서 두 그룹이 반드시 순서대로 나열되어야 하는데 첫 번째 그룹은 한 번만, 두 번째 그룹은 0번 이상 나열된다는 의미입니다. 결국 다음과 같은 형식이 모두 가능하다는 얘기입니다.

p { font-family: serif; }
p { font-family: Arial, serif; }
p { font-family: Arial, serif, sans-serif; }
p { font-family: serif, Arial, sans-serif; }

마지막 CSS 규칙도 허용되기는 하지만 특정 폰트를 이용할 수 없을 경우의 대체 목적으로 범용 폰트 패밀리를 지정하기 때문에 좋은 방법은 아닙니다. CSS 권고안도 범용 폰트 패밀리(generic-family)를 마지막 대체 폰트로 제공할 것을 권장하고 있습니다.

Initial (초기 값)

속성에 적용되는 초기 값을 나타냅니다. 초기 값은 캐스케이드(Cascade)나 상속(Inheritance)에서 이용되는데 자세한 내용은 다음 글에서 다루겠습니다.

Applies to (적용 대상)

속성이 어떤 요소에 적용되는지를 알려줍니다. HTML에서는 요소마다 사용할 수 있는 속성이 정해져 있지만 CSS에서는 각각의 요소가 모든 속성을 가질 수 있습니다. 예를 들어서 span 요소에는 기본적으로 height 속성이 적용되지 않습니다. 하지만 height 속성을 지정했다고 해서 문법에 어긋나는 것은 아닙니다. CSS 2.1 권고안은 clear 속성을 예로 드는데 block 요소에만 적용됩니다.

Inherited (상속 여부)

속성 값이 없을 때 조상(ancestor) 요소의 속성 값을 상속받는지를 알려줍니다. 속성 값이 없고, 값을 상속받지도 않는 요소는 위에 설명한 초기 값이 지정됩니다. 여기서 속성 값이 없다는 표현은 캐스케이딩을 통해서 값이 지정되지 않았다는 의미입니다.

Percentage values (퍼센트 값 해석 방식)

퍼센트 값을 허용할 경우에 이 퍼센트 값이 어떻게 해석되는지를 알려줍니다. 예를 들어서 font-size 속성은 “부모 요소의 font-size를 기준으로 한다.”고 정의되어 있습니다. 퍼센트 값을 허용하지 않는 속성에는 “사용할 수 없음(N/A(Not Available))”으로 표시됩니다.

Media (속성이 적용되는 media 유형)

해당 속성이 적용될 media 유형을 알려줍니다. 대부분은 visual이지만, 문서를 프린트할 때 주로 사용하는 page-break-before 속성 같은 경우 visual, paged로 지정되어 있습니다.

Computed value (산출 값)

속성 값이 어떻게 변환되는지를 알려줍니다. 산출 값은 사용자 에이전트가 이용하는 최종 값이 아니고 중간 단계의 계산 값인데 캐스케이딩과 상속, 퍼센트 값 과의 상호 작용을 통해서 계산됩니다. 이 부분은 CSS 제작자보다는 CSS 구현자를 위한 정보라고 생각하는데 자세한 사항은 다음 글에서 알아보도록 하겠습니다.

단축 속성을 사용할 경우

추가로 단축 속성을 사용할 때 값이 어떻게 지정되는지도 설명하고 있습니다. 예를 들어서 font 속성은 font-style, font-variant, font-weight, font-size, line-height, font-family를 한꺼번에 지정할 때 사용하는 단축 속성입니다. 이런 단축 속성에서 속성을 모두 지정하지 않을 경우 누락된 속성에는 각 속성의 초기 값이 자동으로 지정됩니다. 예를 들어서 다음과 같은 규칙은

h1 { font: bold 12pt/14pt Helvetica; }

실제로 아래 규칙과 동일합니다.

h1 { 
  font-weight: bold; 
  font-size: 12pt;
  line-height: 14pt; 
  font-family: Helvetica; 
  font-variant: normal;
  font-style: normal;
}

누락된 font-variantfont-style의 초기 값이 normal이기 때문입니다.

마치며

CSS의 속성 정의는 속성에 대한 기본적인 설명을 요약적으로 담고 있습니다. 실제로 속성이 하는 역할을 알려면 속성 정의와 함께 설명을 확인해봐야 합니다. 그런데 이런 속성 설명은 여러 책에 수록되어 있습니다. 예를 들어서 “웹표준 교과서”에는 CSS 속성이 거의 완벽하게 정리되어 있습니다. 하지만 속성 정의 자체에 대해서는 특별한 설명이 없는데(혹시 있는지도 모르겠습니다. 좋은 책이지만 필요할 때만 조금씩 보거든요^^;) 그 이유가 “결정적으로 중요하지 않기 때문”이라고 생각합니다. 상세한 설명이 있고, 혹시 CSS 문법 오류가 있더라고 CSS Validator가 정확하게 찾아 주니까요.

하지만 바탕이 되는 개념이나 용어를 잘 알면 CSS를 더 잘 이해할 수 있으리라 생각합니다. 전에는 CSS 권고안의 속성 설명 부분, 특히 시각적인 서식 모델(Visual Formatting Model)을 중점적으로 봤는데 그 밖에도 중요한 내용이 많다는 것을 갈수록 느끼거든요. 앞으로는 이런 부분을 설명하는데 초점을 맞춰서 글을 쓰려고 합니다.

댓글 4개가 달렸습니다. 태그: , ,

  1. mkyoon | 2008-07-31 09:42

    속성의 값들에 있는 괄호가 너무 궁금했었습니다.
    영문을 읽어도 아리까리했었는데 이 글을 보니 단번에 이해가 되네요^^감사합니다.

  2. wystan | 2008-08-02 13:13

    글 남겨주셔서 고맙습니다. ^^

  3. maylily72 | 2008-10-09 13:13

    hasLayout 개념 찾다가 여기까지 왔는데요..
    읽다가 밑에서부터 쭉 읽고 있어요..
    님의 깊이있고 다각적인 내용이 너무너무 많은 도움이 되고
    그동안의 궁금중이 해결이 되네요..

    감사합니다.^^

  4. wystan | 2008-10-13 01:23

    도움이 된다고 말씀해주셔서 참 기쁘네요~

    고맙습니다. ^^

댓글이 닫혔습니다.