2009년 3월 20일 금요일

CSS 셀렉터 정리

그 동안 CSS셀렉터를 IE6에 맞춰서 작업을 해오다보니 항상 사용하는 셀렉터를 한정 시킬 수 밖에 없었다. 애초 CSS셀렉터가 가지고 있는 많은 기능을 포기하고 사용하지 못했던게 사실(브라우저의 CSS셀렉터의 지원현황을 테스트).
하지만 IE7이 등장하고 (아직 많이 부족하지만) 그동안 지원하지 않던 셀렉터 등을 지원하기 시작했다. 현재 W3C CSS3 Selectors는 Working Draft단계이지만 많은 모던 브라우저에서 어느 정도 구현이 가능하므로 지금부터라도 이해하고 익혀두면 두고두고 많은 도움이 되리라고 생각한다.


나도 아직 피상적으로만 이해하고 있는 부분이 많아서 이번 기회를 빌어서 한번 정리를 해 볼까 한다.(대부분의 내용은 加藤善規(카토 요시키)씨의 CSS セレクタに関するおさらい WWW WATCH을 번역한 내용임)

Chapter1

CSS셀렉터란 무엇인가?


CSS는 “스타일을 지정할 대상(셀렉터:selector)”과 “적용할 내용(선언블록: property : value ;)”, 이렇게 두가지로 구성되어 있다. 선언블록은 다시 프로퍼티(property)와 값(value)으로 나누어 진다.
CSS셀렉터는 스타일을 지정할 대상을 일컫는다.


유니버살 셀렉터(Universal selector)


유니버살 셀렉터는 모든 요소를 대상으로 하는 셀렉터이다. CSS2에 정의되어 있다.
단독으로 사용하여 브라우저의 기본 스타일을 제거한다던지(유니버살 셀렉터를 사용하지 않고 브라우저의 기본 스타일을 제거하는 경우는 YUI를 참고)

* {
margin:0;
padding:0;
}

다른 셀렉터와 조합하여 사용한다.

ul#foo * li {
margin:0;
padding:0;
}

foo라는 id를 가진 ul요소의 직접적인 자식요소는 제외하고 손자요소 이하의 li요소에 스타일을 적용하는 것이 가능하다.

타입 셀렉터(Type selector)

E
타입 셀렉터는 가장 단순한 셀렉터이다. 요소명을 지정하여 그 요소에 스타일을 적용시킨다.

p {
margin:0;
padding:0;
}

속성 셀렉터(Attribute selectors)

E[foo]

어떤 요소 중에서 지정한 속성을 가지고 있는 요소에 스타일을 적용한다. CSS2에 정의되어 있다.

p[class] {
margin:0;
padding:0;
}

위와 같이 class속성을 가진 요소에만 스타일을 적용 시킬 수 있다.
E[foo="bar"]
같은 속성 셀렉터이지만 속성명뿐만이 아니라 그 값도 포함해서 지정한다. CSS2에 정의되어 있다.

a[rel="external"] {
padding-right:15px;
background:(image/external-icon.png) no-repeat right center;
}

예를 들어 위와 같이 외부링크의 a요소에만 rel속성으로 external을 지정해서 외부링크에만 아이콘을 표시하는 것도 가능하다.
E[foo~="bar"]
어떤 요소 중에서 지정한 속성명 및 속성값을 가지고 있는 요소에 스타일을 지정하지만 “~”을 사용하므로써 복수의 속성값이 지정되어 있는 경우에는 지정한 속성값을 포함하고 있으면 적용한다. CSS3에 정의되어 있다.

p[class~="foo"] {
margin:0;
padding:0;
}

class 속성을 가진 p요소 중에서 foo라고 하는 속성값을 포함하고 있는 요소에 스타일을 적용한다.
E[foo^="bar"]
어떤 요소 중에서 지정한 속성명 및 속성값을 가지고 있는 요소에 스타일을 지정하지만 “^”을 사용하므로써 지정한 문자로 시작하는 속성값에 대해서만 스타일을 적용한다. CSS3에 정의되어 있다.

p[class^="ex"] {
margin:0;
padding:0;
}

class속성을 가진 p요소 중에서 ex로 시작하는 속성값을 가진 요소에 스타일을 적용한다.
E[foo$="bar"]
어떤 요소 중에서 지정한 속성명 및 속성값을 가지고 있는 요소에 스타일을 지정하지만 “$”를 사용하므로써 지정한 문자로 끝나는 속성값에 대해서만 스타일을 적용한다. CSS3에 정의되어 있다.

a[href$=".pdf"] {
padding-right:15px;
background:(image/pdf-icon.png) no-repeat right center;
}

예를 들어 위와 같이 파일의 확장자(extension)를 지정하여 PDF파일에 대한 링크에는 PDF를 나타내는 아이콘을 표시하는 사용법도 가능하다.
E[foo*="bar"]
어떤 요소 중에서 지정한 속성명 및 속성값을 가지고 있는 요소에 스타일을 지정하지만 “*”을 사용하므로써 지정한 문자열을 포함한 속성값에 대해서만 스타일을 적용한다. CSS3에 정의되어 있다.

p[class*="ex"] {
margin:0;
padding:0;
}

class속성을 가진 p요소 중에서 ex를 포함한 속성값을 가진 요소에 스타일을 적용한다.
E[hreflang="en"]
hreflang속성을 가진 요소에 사용하는 셀렉터이다. hreflang속성값의 앞부분이 일치하는 요소에 적용한다(E[lang="en"]도 동일).

a[hreflang="en"] {
padding-right:15px;
background:(image/en-icon.png) no-repeat right center;
}

hreflang요소를 가진 a요소 중에서 속성값에 en-US 등 en을 앞부분에 포함한 값을 가진 요소에만 스타일이 적용한다. 위의 예처럼 링크가 걸린 페이지가 영어인 경우에 영어 사이트를 나타내는 아이콘을 표시하는 등의 용도로 사용할 수 있다. CSS2에 정의되어 있다.

Chapter2

유사 클래스(Structural pseudo-classes)
E:root
문서 안의 루트요소인 E라는 요소에 스타일을 적용한다. CSS3에 정의. (X)HTML에 대해서 루트요소는 HTML요소이므로

:root {
margin:0;
padding:0;
}

라고 지정하면 HTML요소에 스타일이 적용된다. XML의 경우에는 DTD로 지정한 루트 요소에 적용된다.
E:nth-child(n)
E라고 하는 요소 중에서 부모요소의 n번째의 자식요소인 E요소에 스타일을 적용한다. CSS3에 정의되어 있다.

div p:nth-child(3) {
margin:0;
padding:0;
}

div요소 안에서 3번째 자식요소로 출현하는 p요소에만 스타일이 적용된다. 또

div p:nth-child(odd) {
margin:0;
padding:0;
}

라고 하면 홀수로 출현하는 요소(첫번째, 세번째, 다섯번째…)에만 적용할 수 있고 동일하게 even을 n에 넣어서 짝수로 출현하는 요소에만 스타일을 적용 할 수 있다.
그 밖에도 an+b라는 형식도 가능하다. a와 b에 정수를 넣으면 n에는 0부터 차례대로 정수를 대입하여 계산한다. 즉, 2n+1이면 홀수(odd)와 같고 2n+0이면 짝수(even)와 같다. 덧붙여 +0은 생략 할 수 있으므로 2n이라고 기술한다.

div p:nth-child(odd) /* div안에 홀수로 출현하는 자식요소인 p요소에 적용 */
div p:nth-child(2n+1) /* 위와 같다 */
div p:nth-child(even) /* div안에 짝수로 출현하는 자식요소인 p요소에 적용 */
div p:nth-child(2n) /* 위와 같다 */
/* 아래와 같이 적으면 4가시 색이 순서대로 반복된다 */
div p:nth-child(4n+1) { color:navy;}
div p:nth-child(4n+2) { color:green;}
div p:nth-child(4n+3) { color:maroon;}
div p:nth-child(4n+4) { color:purple;}

이 방법은 아래의 유사클래스에 등장하는 n에도 동일하게 사용 할 수 있다.
E:nth-last-child(n)
E라고 하는 요소 중에서 부모요소의 마지막부터 세어서 n번째의 자식요소인 E요소에 스타일을 적용한다. CSS3에 정의되어 있다.


div p:nth-last-child(1) {
margin:0;
padding:0;
}

라고 하면 div요소 안에서 가장 마지막에 출현하는 자식요소인 p요소에만 스타일이 적용된다.
E:nth-of-type(n)
E라고 하는 요소 중에서 부모요소 안에서 동렬(형제관계)인 E와 같은 이름을 가진 요소로 n번째에 출현하는 E요소에만 스타일을 지정한다. CSS3에 정의되어 있다.


div p:nth-of-type(5) {
margin:0;
padding:0;
}

라고 하면 div요소 안에서 형제관계에 있는 p요소 중에서 5번째에 출현하는 p요소에만 스타일을 적용한다.
E:nth-last-of-type(n)
E라고 하는 요소 중에서 부모요소 안에서 동렬(형제관계)인 E와 같은 이름을 가진 요소로 끝에서부터 n번째에 출현하는 E요소에만 스타일을 지정한다. CSS3에 정의되어 있다.

div p:nth-last-of-type(3) {
margin:0;
padding:0;
}

라고 하면 div요소 안에서 형제관계에 있는 p요소 중에서 끝에서 3번째에 출현하는 p요소에만 스타일을 적용한다.
E:first-child
E라고 하는 요소 중에서 부모요소에 처음으로 출현하는 자식요소인 E요소에 스타일을 적용한다. CSS2에 정의되어 있다.


div p:first-child {
margin:0;
padding:0;
}

E:last-child
E라고 하는 요소 중에서 부모요소에 마지막으로 출현하는 자식요소인 E요소에 스타일을 적용한다. CSS3에 정의되어 있다.div p:last-child {
margin:0;
padding:0;
}

E:first-of-type
E라고 하는 요소 중에서 부모요소 안에서 동렬(형제관계)의 E와 같은 이름을 가지고 있는 요소로 최초로 출현하는 E요소에 스타일을 적용한다. CSS3에 정의되어 있다.

div p:first-of-type {
margin:0;
padding:0;
}

라고 하면 div요소 안에서 형제관계에 있는 p요소 중에서 최초로 출현하는 p요소에만 스타일을 적용한다.
E:last-of-typeE라고 하는 요소 중에서 부모요소 안에서 동렬(형제관계)의 E와 같은 이름을 가지고 있는 요소로 마지막에 출현하는 E요소에 스타일을 적용한다. CSS3에 정의되어 있다.


div p:last-of-type {
margin:0;
padding:0;
}

라고 하면 div요소 안에서 형제관계에 있는 p요소 중에서 가장 나중에 출현하는 p요소에만 스타일을 적용한다.

E:only-child
E라고 하는 요소 중에서 부모요소 안에서 유일한 자식요소인(형제를 가지지 않는다) E요소에 스타일을 적용한다. CSS3에 정의되어 있다.

E:only-of-type
E라고 하는 요소 중에서 부모요소 안에서 유일한 E요소에 스타일을 지정한다. CSS3에 정의되어 있다.

E:empty
E라고 하는 요소 중에서 자식요소(텍스트 노드도 포함해서)를 전혀 가지고 있지 않은 E요소에만 스타일을 적용한다. CSS3에 정의되어 있다.

링크 유사클래스(The link pseudo-classes)

E:linkE:visited
문서안의 하이퍼 링크 중에서 유저가 아직 방문하지 않은 링크인가(:link), 또는 방문을 한 링크인가(:visited)에 따라 각각의 스타일을 적용한다. CSS1부터 존재한다.

유저 액션 유사클래스(The user action pseudo-classes)

E:activeE:hoverE:focus
유저의 조작에 따라 스타일을 적용한다. :active는 유저에 의해서 대상 요소가 액티브하게 되었을 때. 예를 들어 마우스로 클릭하고 버튼에서 손을 땠을때 적용된다. :hover는 유저에 의해서 대상 요소가 가리켜지고 있을 때. 롤 오버 등. 이 두가지는 CSS1부터 존재. :focus는 대상 요소가 포커스 되었을때 스타일이 적용된다. 예를 들면 입력 대기가 되어 있는 input요소 등. :focus는 CSS2에 정의되어 있다.

타겟 유사클래스 (The target pseudo-class)
E:target
하이퍼링크 중에서 URI에 앵커링크가 지정되어 있는 링크를 액티브하게 했을 때 그 타겟이 되는 요소에 스타일을 적용한다. 앵커링크란
http://example.com/example.html#section_3
와 같이 fragment식별자로 URI가 끝나는 링크이다.

*:target {
padding-right:15px;
background:(image/target-icon.png) no-repeat right center;
}

이것으로 fragment식별자 링크를 클릭했을 때 그 타겟 요소에 아이콘을 표시하는 것이 가능하다. fragment식별자 링크로 이동할때 어디를 타겟으로 이동했는지를 알기쉽게 하는 등의 용도로 사용 할 수 있다. CSS3에 정의되어 있다.

언어 유사클래스(The :lang() pseudo-class)

E:lang(fr)
E라고 하는 요소 중에서 앞부분이 fr과 일치하는 lang속성값을 가진 요소에 스타일을 적용한다. CSS2에 정의되어 있다.

p:lang(en) {
padding-right:15px;
background:(image/en-icon.png) no-repeat right center;
}

라고 지정하면english text
라고 기술한 p요소에만 스타일을 적용한다.
UI 요소 상태 유사클래스 (The UI element states pseudo-classes)
E:enabledE:disabled
E라고 하는 요소 중에서 유효한 것(:enabled), 무효한 것(:disabled)에 대해서 각각 스타일을 지정한다. 예를 들면 textarea요소 등은 통상 포커스입력이 가능(액티브)하기 때문에 유효한 요소이고 약관 등의 표시로 유저가 포커스해도 입력 할 수 없는 textarea는 무효한 것이 된다. CSS3에 정의되어 있다.
E:checked
라디오버튼, 체크박스가 체크된 상태의 스타일을 지정한다. CSS3에 정의되어 있다.

Chapter3

유사요소(pseudo-element)


E::first-line
E라고 하는 요소의 첫번째 행에만 스타일을 적용한다. CSS1에 정의되어 있다. 첫번째 행은 font size나 브라우저의 윈도우 사이즈 등 다양한 조건에 따라 바뀌기 때문에 주의가 필요하다. 덧붙여 블록요소에만 사용 할 수 있고 지정 할 수 있는 프로퍼티에도 제한이 있다.

p {
margin-left:1em;
}
p::first-line {
margin-left:-1em;
}

예를 들어 “※”등을 사용한 주석문에서 첫번째 행에 사용된 “※”만큼 두번째 행도 인덴트하고 싶은 경우에도 사용 할 수 있다.
E::first-letter
E라고 하는 요소에 최초에 등장하는 첫문자에만 스타일을 지정한다. CSS1에 정의되어 있다. 첫번째 문자가 특정문자(인용부호나 괄호등)인 경우 그 다음 문자와 함께 스타일을 적용한다. ::first-line 유사요소와 같이 블록요소에만 사용 할 수 있고 지정 할 수 있는 프로퍼티에도 제한이 있다.
E::selection
유저가 선택한 문서에 스타일을 적용한다. 예를 들면 텍스트를 마우스로 드랙 했을 때의 외형을 바꿀 수 있다. CSS3에 정의되어 있다.

p::selection {
background:#f00;
color:#fff;
}

E::beforeE::after
E라고 하는 요소에 포함된 내용의 앞(::before), 뒤(::after)에 지정한 내용을 생성한다. content프로퍼티와 함께 사용해서 텍스트나 이미지 등을 추가한다. CSS2에 정의되어 있다.

p.note::before {
content:url(image/note-icon.png);
margin:0 2px;
}

li.new::after {
content:"new!";
color:#f00;
}

클래스 셀렉터(Class selectors)

E.warning
class속성 값에 따라 스타일을 적용한다. CSS1에 정의되어 있다.

ID 실렉터(ID selectors)

E#myid
id속성 값에 따라 스타일을 적용한다. CSS1에 정의되어 있다.
부정 유사클래스(Negation pseudo-class)
E:not(s)
E라고 하는 요소중에서 “s”가 아닌 것에 스타일을 적용한다. CSS3에 정의되어 있다.

input {
vertical-align:middle;
}
input:not([type="text"]) {
vertical-align:top;
}

라고 하여 type=”text” 이외의 input요소에만 다른 스타일을 지정하는 것도 가능하다.

자손 셀렉터(Descendant combinator)

E F
복수의 실렉터를 조합해 사용하는 방법이다. 자손 셀렉터는 부모요소에 포함된 모든 자손 요소에 스타일을 적용한다. 유니버살 셀렉터나 속성 셀렉터등과 조합해서 사용할 수 있다. CSS1에 정의되어 있다.

p span.note {
color:red;
}
ul li * li {
margin-left:2em;
}

자식 셀렉터(Child combinator)

E > F
자식 실렉터는 부모 요소의 직접적인 자식요소에 스타일을 적용한다. 손자 요소 이하에는 적용 되지 않는다. CSS2에 정의되어 있다.

인접 셀렉터(Adjacent sibling combinator)

E + F
E라고 하는 요소 중에서 직접적인 동생 요소인 F라고 하는 요소에 스타일을 적용한다. CSS2에 정의되어 있다.
형제 요소란 어떤 부모 요소안에서 동렬로 존재하는 요소 가운데 앞(형), 뒤(동생)에 존재하는 요소를 가리킨다. 직접적인 동생 요소란 E라고 하는 요소와 동렬로, E라고 하는 요소의 바로 뒤에 인접해 존재하는 요소를 가리킨다. 예를 들면 다음과 같은 경우 h2요소는 h1요소의 직접적인 동생 요소이다.

title

sub title

하지만 아래와 같은 경우에는 h2는 h1의 직접적인 동생 요소가 아니다.

title

text

sub title

간접 셀렉터(General sibling combinator)

E ~ F
E라고 하는 요소의 뒤에 출현하는 F라고 하는 요소에 스타일을 지정한다. 즉, E라고 하는 요소의 동생 요소가 대상이 된다. CSS3에 정의되어 있다.
CSS3에서는 큰폭으로 셀렉터가 확장 되었고 브라우저에서 구현이 된다면 불필요한 class속성이나 id속성을 줄일 수 있을 것 같다. 또 표현의 폭이 그만큼 넓어지고 JavaScript로 구현 하던 부분들도 CSS만으로도 표현이 가능한 부분이 늘어날 것 같다.
현재 CSS3가 Working Draft 상태이기 때문에 변경될 가능성도 있고 역시 IE가 발목을 잡는 부분도 많이 있을 것 같다. 브라우저에 따라 표시되지 않더라도 크게 영향을 끼치지 않는 부분이라면 지금이라도 사용이 가능한 부분도 많이 있지만 클라이언트가 모든 브라우저에서 전부 똑같이 해달라고 하는 대략 난감한 경우도 생길 수도 있다(실제로 예전에 그런 경우가 있었음..;). 그래도 클라이언트가 해달라면 해줘야 한다!
참고:css셀렉터에 관해 css3.info에서 좋은 정보를 많이 제공하고 있다.

댓글 없음: