1. 소개
이 섹션은 규범적이지 않습니다.
셀렉터란 트리 구조의 요소를 받아 그 요소가 셀렉터와 일치하는지 여부를 검사하는 불리언 판정식입니다.
이러한 표현식은 다양한 용도로 사용될 수 있습니다:
- 요소에 직접 적용하여 특정 기준에 부합하는지 검사할 때, 예를 들어
element.matches()
함수 ([DOM]에서 정의) - 요소 트리 전체에 적용하여 기준에 부합하는 요소들의 집합을 필터링할 때, 예를 들어
document.querySelectorAll()
함수 ([DOM]에서 정의) 또는 CSS 스타일 규칙의 셀렉터 등 - "역방향"으로 사용하여 주어진 셀렉터와 일치하는 마크업을 생성할 때, 예를 들어 HAML 또는 Emmet 등
Selectors Level 1, 2, 3은 각각 CSS1, CSS2.1, Selectors Level 3 명세에 정의된 셀렉터 기능의 부분집합으로 정의됩니다. 이 모듈은 Selectors Level 4를 정의합니다.
1.1. 모듈 상호작용
이 모듈은 [SELECT] 및 [CSS21]에서 CSS용으로 정의된 셀렉터 집합을 대체하고 확장합니다.
렌더링 트리에서 추상 요소를 정의하는 의사 요소 셀렉터는 이 명세에 포함되지 않습니다. 그들의 일반적인 문법만 본서에서 다루며, 렌더링 모델과 밀접하게 통합되어 있고 DOM 쿼리 등 다른 활용에는 관련성이 낮기 때문에 별도의 모듈에서 정의됩니다.
2. 셀렉터 개요
이 섹션은 규범적이지 않으며, 다음 섹션들의 요약만을 제공합니다.
셀렉터는 구조를 표현합니다. 이 구조는 조건(예: CSS 규칙에서)으로 사용되어 문서 트리에서 어떤 요소가 셀렉터와 일치하는지 결정하거나, 해당 구조에 대응되는 HTML 또는 XML 조각의 평면적 기술로 사용할 수 있습니다.
셀렉터는 단순한 요소 이름부터 복잡한 문맥적 표현까지 다양합니다.
다음 표는 셀렉터 문법을 요약한 것입니다:
패턴 | 의미 | 섹션 | 레벨 |
---|---|---|---|
*
| 모든 요소 | § 5.2 범용 셀렉터 | 2 |
E
| E 타입의 요소 | § 5.1 타입(태그명) 셀렉터 | 1 |
E:not(s1, s2, …)
| 복합 셀렉터 s1 또는 복합 셀렉터 s2와 일치하지 않는 E 요소 | § 4.3 부정(일치 없음) 의사 클래스: :not() | 3/4 |
E:is(s1, s2, …)
| 복합 셀렉터 s1 또는 복합 셀렉터 s2와 일치하는 E 요소 | § 4.2 매칭-임의 의사 클래스: :is() | 4 |
E:where(s1, s2, …)
| 복합 셀렉터 s1 또는 복합 셀렉터 s2와 일치하지만 특이성을 부여하지 않는 E 요소 | § 4.4 특이성 조정 의사 클래스: :where() | 4 |
E:has(rs1, rs2, …)
| E 요소를 기준(anchor)으로 평가 시 상대 셀렉터 rs1 또는 rs2와 일치하는 요소가 존재하면 일치하는 E 요소 | § 4.5 관계형 의사 클래스: :has() | 4 |
E.warning
| 클래스 warning 을 가진 E 요소 (문서 언어가 클래스 결정 방법 정의)
| § 6.6 클래스 셀렉터 | 1 |
E#myid
| ID가 myid 인 E 요소
| § 6.7 ID 셀렉터 | 1 |
E[foo]
| foo 속성이 있는 E 요소
| § 6.1 속성 존재 및 값 셀렉터 | 2 |
E[foo="bar"]
| foo 속성 값이 bar 와 정확히 일치하는 E 요소
| § 6.1 속성 존재 및 값 셀렉터 | 2 |
E[foo="bar" i]
| foo 속성 값이 bar 의 (ASCII 범위) 대소문자 변형과 정확히 일치하는 E 요소
| § 6.3 대소문자 구분 | 4 |
E[foo="bar" s]
| foo 속성 값이 동일한
bar 인 E 요소
| § 6.3 대소문자 구분 | 4 |
E[foo~="bar"]
| foo 속성 값이 공백 구분 목록이고, 그 중 하나가 bar 와 정확히 일치하는 E 요소
| § 6.1 속성 존재 및 값 셀렉터 | 2 |
E[foo^="bar"]
| foo 속성 값이 bar 문자열로 정확히 시작하는 E 요소
| § 6.2 하위 문자열 매칭 속성 셀렉터 | 3 |
E[foo$="bar"]
| foo 속성 값이 bar 문자열로 정확히 끝나는 E 요소
| § 6.2 하위 문자열 매칭 속성 셀렉터 | 3 |
E[foo*="bar"]
| foo 속성 값에 bar 부분 문자열이 포함된 E 요소
| § 6.2 하위 문자열 매칭 속성 셀렉터 | 3 |
E[foo|="en"]
| foo 속성 값이 en 으로 시작하는 하이픈(-) 구분 목록인 E 요소
| § 6.1 속성 존재 및 값 셀렉터 | 2 |
E:dir(ltr)
| 왼쪽에서 오른쪽 방향성을 가진 E 타입 요소 (문서 언어가 방향성 결정 방법 정의) | § 7.1 방향성 의사 클래스: :dir() | 4 |
E:lang(zh, "*-hant")
| 중국어(어떤 방언, 문자체계든) 또는 전통 중국 문자로 작성된 것으로 태그된 E 타입 요소 | § 7.2 언어 의사 클래스: :lang() | 2/4 |
E:any-link
| 하이퍼링크의 소스 앵커인 E 요소 | § 8.1 하이퍼링크 의사 클래스: :any-link | 4 |
E:link
| 목적지가 아직 방문되지 않은 하이퍼링크의 소스 앵커인 E 요소 | § 8.2 링크 히스토리 의사 클래스: :link, :visited | 1 |
E:visited
| 목적지가 이미 방문된 하이퍼링크의 소스 앵커인 E 요소 | § 8.2 링크 히스토리 의사 클래스: :link, :visited | 1 |
E:local-link
| 현재 URL을 목적지로 하는 하이퍼링크의 소스 앵커인 E 요소 | § 8.3 로컬 링크 의사 클래스: :local-link | 4 |
E:target
| 현재 URL의 타겟인 E 요소 | § 8.4 타겟 의사 클래스: :target | 3 |
E:target-within
| 현재 URL의 타겟이거나 해당 타겟을 포함하는 E 요소 | § 8.5 타겟 컨테이너 의사 클래스: :target-within | 4 |
E:scope
| 스코프 루트인 E 요소 | § 8.6 참조 요소 의사 클래스: :scope | 4 |
E:current
| 시간 차원 캔버스에서 현재 표시된 E 요소 | § 10.1 현재 요소 의사 클래스: :current | 4 |
E:current(s)
| 셀렉터 s와 일치하는 가장 깊은 :current E 요소 | § 10.1 현재 요소 의사 클래스: :current | 4 |
E:past
| 시간 차원 캔버스에서 과거에 해당하는 E 요소 | § 10.2 과거 요소 의사 클래스: :past | 4 |
E:future
| 시간 차원 캔버스에서 미래에 해당하는 E 요소 | § 10.3 미래 요소 의사 클래스: :future | 4 |
E:active
| 활성 상태인 E 요소 | § 9.2 활성화 의사 클래스: :active | 1 |
E:hover
| 커서 아래에 있거나 자손 중 커서 아래에 있는 요소가 있는 E 요소 | § 9.1 포인터 호버 의사 클래스: :hover | 2 |
E:focus
| 사용자 입력 포커스를 가진 E 요소 | § 9.3 입력 포커스 의사 클래스: :focus | 2 |
E:focus-within
| 사용자 입력 포커스가 있거나 포커스가 있는 요소를 포함하는 E 요소 | § 9.5 포커스 컨테이너 의사 클래스: :focus-within | 4 |
E:focus-visible
| 사용자 입력 포커스를 가지고 있고, UA가 해당 요소에 포커스 링 또는 기타 표시자를 그려야 한다고 판단한 E 요소 | § 9.4 포커스 표시 의사 클래스: :focus-visible | 4 |
E:enabled
| 사용자 인터페이스 요소 E가 활성/비활성 상태 | § 13.1.1 :enabled, :disabled 의사 클래스 | 3 |
E:read-write E:read-only
| 사용자가 변경 가능한/변경 불가능한 인터페이스 요소 E | § 13.1.2 변경 가능성 의사 클래스: :read-only, :read-write | 3-UI/4 |
E:placeholder-shown
| 현재 플레이스홀더 텍스트를 표시 중인 입력 컨트롤 | § 13.1.3 플레이스홀더 표시 의사 클래스: :placeholder-shown | 3-UI/4 |
E:default
| 관련 선택 그룹에서 기본 항목인 사용자 인터페이스 요소 E | § 13.1.5 기본 옵션 의사 클래스: :default | 3-UI/4 |
E:checked
| 체크됨/선택됨 상태인 사용자 인터페이스 요소 E (예: 라디오 버튼, 체크박스 등) | § 13.2.1 선택 옵션 의사 클래스: :checked | 3 |
E:indeterminate
| 불확정 상태(체크됨도 아니고 체크 해제도 아닌)인 사용자 인터페이스 요소 E | § 13.2.2 불확정 값 의사 클래스: :indeterminate | 4 |
E:valid E:invalid
| 입력값의 유효성 기준을 만족하거나 만족하지 않는 사용자 입력 요소 E | § 13.3.2 유효성 의사 클래스: :valid, :invalid | 3-UI/4 |
E:in-range E:out-of-range
| 값이 범위 내/범위 외에 있는 사용자 입력 요소 E | § 13.3.3 범위 의사 클래스: :in-range, :out-of-range | 3-UI/4 |
E:required E:optional
| 입력이 필요/불필요한 사용자 입력 요소 E | § 13.3.4 선택 가능성 의사 클래스: :required, :optional | 3-UI/4 |
E:blank
| 값이 비어 있는(공백/누락) 사용자 입력 요소 E | § 13.3.1 빈 값 의사 클래스: :blank | 4 |
E:user-invalid
| 사용자가 변경한 입력값이 잘못된(유효하지 않거나, 범위를 벗어나거나, 필수 입력 누락 등) 사용자 입력 요소 E | § 13.3.5 사용자 상호작용 의사 클래스: :user-valid, :user-invalid | 4 |
E:root
| 문서의 루트인 E 요소 | § 14.1 :root 의사 클래스 | 3 |
E:empty
| 자식(요소/텍스트)이 없고, 공백만 있을 수 있는 E 요소 | § 14.2 :empty 의사 클래스 | 3 |
E:nth-child(n [of S]?)
| 부모 중 S와 일치하는 n번째 자식인 E 요소 | § 14.3.1 :nth-child() 의사 클래스 | 3/4 |
E:nth-last-child(n [of S]?)
| 부모 중 S와 일치하는 마지막에서 n번째 자식인 E 요소 | § 14.3.2 :nth-last-child() 의사 클래스 | 3/4 |
E:first-child
| 부모의 첫 번째 자식인 E 요소 | § 14.3.3 :first-child 의사 클래스 | 2 |
E:last-child
| 부모의 마지막 자식인 E 요소 | § 14.3.4 :last-child 의사 클래스 | 3 |
E:only-child
| 부모의 유일한 자식인 E 요소 | § 14.3.5 :only-child 의사 클래스 | 3 |
E:nth-of-type(n)
| 동일 타입 중 n번째 형제인 E 요소 | § 14.4.1 :nth-of-type() 의사 클래스 | 3 |
E:nth-last-of-type(n)
| 동일 타입 중 마지막에서 n번째 형제인 E 요소 | § 14.4.2 :nth-last-of-type() 의사 클래스 | 3 |
E:first-of-type
| 동일 타입 중 첫 번째 형제인 E 요소 | § 14.4.3 :first-of-type 의사 클래스 | 3 |
E:last-of-type
| 동일 타입 중 마지막 형제인 E 요소 | § 14.4.4 :last-of-type 의사 클래스 | 3 |
E:only-of-type
| 동일 타입 중 유일한 형제인 E 요소 | § 14.4.5 :only-of-type 의사 클래스 | 3 |
E F
| E 요소의 자손인 F 요소 | § 15.1 자손 결합자 ( ) | 1 |
E > F
| E 요소의 자식인 F 요소 | § 15.2 자식 결합자 (>) | 2 |
E + F
| E 요소 바로 뒤에 오는 F 요소 | § 15.3 인접 형제 결합자 (+) | 2 |
E ~ F
| E 요소 앞에 위치한 F 요소 | § 15.4 일반 형제 결합자 (~) | 3 |
F || E
| F 요소가 대표하는 열에 속한 셀을 나타내는 E 요소 (그리드/테이블에서) | § 16.1 열 결합자 (||) | 4 |
E:nth-col(n)
| 그리드/테이블에서 n번째 열에 속한 셀을 나타내는 E 요소 | § 16.2 :nth-col() 의사 클래스 | 4 |
E:nth-last-col(n)
| 그리드/테이블에서 마지막에서 n번째 열에 속한 셀을 나타내는 E 요소 | § 16.3 :nth-last-col() 의사 클래스 | 4 |
참고: 일부 Level 4 셀렉터(위에서 "3-UI"로 표시됨)는 [CSS3UI]에서 도입되었습니다.
3. 셀렉터 문법 및 구조
3.1. 구조 및 용어
셀렉터는 트리 구조에서 특정 요소 패턴을 나타냅니다. 셀렉터라는 용어는 단순 셀렉터, 복합 셀렉터, 복잡 셀렉터, 또는 셀렉터 리스트를 의미할 수 있습니다. 셀렉터의 주체는 셀렉터가 정의된 대상 요소를 의미합니다; 즉, 해당 셀렉터와 일치하는 셀렉터의 모든 요소입니다.
단순 셀렉터는 요소에 대한 단일 조건입니다. 타입 셀렉터, 범용 셀렉터, 속성 셀렉터, 클래스 셀렉터, ID 셀렉터, 또는 의사 클래스가 단순 셀렉터입니다. (<simple-selector>로 셀렉터 문법에서 표현됩니다.) 특정 요소가 일치한다고 할 때, 명세에서 정의된 대로 단순 셀렉터가 해당 요소를 정확하게 설명하면 단순 셀렉터와 일치한다고 합니다.
복합 셀렉터는 단순 셀렉터들의 연속으로, 결합자로 분리되지 않습니다. 하나의 요소에 대한 여러 조건을 동시에 나타냅니다. 타입 셀렉터 또는 범용 셀렉터가 포함된다면, 반드시 시퀀스의 첫 번째에 위치해야 합니다. 시퀀스에는 타입 셀렉터 또는 범용 셀렉터가 하나만 허용됩니다. (복합 셀렉터는 <compound-selector>로 셀렉터 문법에서 표현됩니다.) 특정 요소가 일치한다고 할 때, 복합 셀렉터 안의 모든 단순 셀렉터와 일치하면 복합 셀렉터와 일치한다고 합니다.
참고: 공백은 자손 결합자를 나타내므로, 복합 셀렉터의 단순 셀렉터 사이에는 공백이 허용되지 않습니다.
결합자는 양쪽의 복합 셀렉터가 나타내는 두 요소 간의 관계 조건입니다.
셀렉터 Level 4의 결합자에는
자손 결합자(공백),
자식 결합자(U+003E,
>
),
인접 형제
결합자(U+002B, +
),
일반
형제 결합자(U+007E, ~
)
등이 있습니다.
두 요소 간의 관계 조건이 참이면 결합자와 일치한다고 합니다.
복잡 셀렉터는 결합자로 분리된 하나 이상의 복합 셀렉터의 연속입니다. 이는 특정 관계 조건에 따라 여러 요소 집합에 동시에 적용되는 조건 집합을 나타냅니다. (복잡 셀렉터는 <complex-selector>로 셀렉터 문법에서 표현됩니다.) 특정 요소가 복잡 셀렉터와 일치한다는 것은, 각 복합 셀렉터와 일치하는 요소 리스트가 존재하며, 리스트 내 연속적인 요소 쌍이 각 결합자 조건을 만족하고, 마지막 요소가 해당 요소임을 의미합니다.
참고: 단일 복합 셀렉터로 구성된 셀렉터는 그에 포함된 단순 셀렉터 조건을 만족하는 모든 요소와 일치합니다. 시퀀스 앞에 또 다른 복합 셀렉터와 결합자를 추가하면 매칭 제약이 추가되어, 복잡 셀렉터의 주체는 항상 마지막 복합 셀렉터가 나타내는 요소의 부분집합이 됩니다.
단순/복합/복잡 셀렉터 리스트는 단순, 복합, 또는 복잡 셀렉터의 쉼표로 구분된 목록입니다. 유형이 중요하지 않거나 주변 텍스트에서 지정된 경우, 단순히 셀렉터 리스트라 부릅니다. 유형이 중요하지만 지정되지 않은 경우 기본적으로 복잡 셀렉터 리스트를 의미합니다. (§ 4.1 셀렉터 리스트에서 셀렉터 리스트 및 문법의 <*-selector-list> 생성식에 대해 추가 정보를 확인할 수 있습니다.) 특정 요소가 셀렉터 리스트의 셀렉터 중 하나라도 일치하면 셀렉터 리스트와 일치한다고 합니다.
3.2. 데이터 모델
셀렉터는 DOM과 같은 요소 트리에 대해 평가됩니다. [DOM] 이 명세에서는 이를 "문서 트리" 또는 "소스 문서"라 부를 수 있습니다.
각 요소는 다음 다섯 가지 측면을 가질 수 있으며, 모두 문자열로 매칭됩니다:
- 요소의 타입(태그명)
- 요소의 네임스페이스
- ID
- 소속된 클래스(이름있는 그룹)
- 속성(이름-값 쌍)
개별 요소가 위의 특징 중 일부를 가지지 않을 수도 있지만, 어떤 요소는 무특성(featureless)일 수 있습니다. 무특성 요소는 명시적으로 정의된 경우를 제외하고 어떤 셀렉터와도 일치하지 않습니다. 특정 셀렉터가 무특성 요소와 일치하도록 허용된 경우, 반드시 기본 네임스페이스를 무시해야 합니다. [CSS3NAMESPACE]
많은 셀렉터는 문서 언어(즉, 문서 트리의 언어 및 의미) 또는 호스트 언어(즉, 셀렉터 문법을 사용하는 언어)의 의미에 의존합니다. 예를 들어, :lang() 셀렉터는 문서 언어(예: HTML)가 요소와 언어를 어떻게 연결하는지 규정합니다. 또 다른 예로, ::first-line 의사 요소는 호스트 언어(예: CSS)가 ::first-line 의사 요소가 무엇을 나타내고, 어떤 역할을 하는지 정의합니다.
3.3. 스코프 셀렉터
일부 호스트 애플리케이션은 셀렉터를 특정 문서의 서브트리나 조각에 스코프하여 사용할 수 있습니다. 스코프 서브트리의 루트를 스코프 루트라 합니다.
셀렉터가 스코프됨이라면, 해당 요소가 스코프 루트의 자손일 때만 일치합니다. (셀렉터의 나머지 부분은 제한 없이 일치할 수 있으며, 최종적으로 일치하는 요소만 스코프 내에 있어야 합니다.)
querySelector()
메서드([DOM]에 정의)는 셀렉터를 호출된 요소 기준으로 스코프하여 평가할 수 있습니다.
widget
와 같은
호출은
a
요소를 widget
요소 내부에서만 찾으며,
문서 전체의 다른
a
요소는 무시합니다.
3.4. 상대 셀렉터
특정 컨텍스트에서는 상대 셀렉터가 허용될 수 있습니다. 이는 하나 이상의 앵커 요소를 기준으로 요소를 나타내는 셀렉터의 축약형입니다. 상대 셀렉터는 결합자로 시작하며, 셀렉터 시작 부분에 앵커 요소를 암시합니다. (결합자가 없으면 자손 결합자가 암시됩니다.)
상대 셀렉터는 <relative-selector>로 셀렉터 문법에서 표현되며, 그 목록은 <relative-selector-list>로 표현됩니다.
3.5. 의사 클래스
의사 클래스는 단순 셀렉터로, 문서 트리 외부의 정보나 다른 단순 셀렉터로 표현하기 어렵거나 불가능한 조건을 기반으로 선택을 허용합니다. 또한 동적일 수 있어, 사용자가 문서와 상호작용하는 동안 요소가 의사 클래스를 획득하거나 잃을 수 있지만 문서 자체는 변경되지 않습니다. 의사 클래스는 문서 소스나 트리를 수정하거나 나타나지 않습니다.
의사 클래스 문법은 ":"(U+003A COLON) 뒤에 의사 클래스 이름(CSS 식별자)이 오며, 함수형 의사 클래스의 경우 괄호 안에 인자가 포함됩니다.
예를 들어, :valid는 일반 의사 클래스이고, :lang()는 함수형 의사 클래스입니다.
모든 CSS 키워드와 마찬가지로 의사 클래스 이름은 ASCII 대소문자 구분 없음입니다. 의사 클래스 이름 앞의 콜론과 이름 사이, 혹은 함수형 의사 클래스 이름과 괄호 사이에는 공백이 허용되지 않습니다. 함수형 의사 클래스 괄호 내부의 인자 주위에는, 별도 지정이 없는 한, 공백이 허용됩니다.
다른 단순 셀렉터와 마찬가지로, 의사 클래스는 셀렉터 안의 모든 복합 셀렉터에 포함될 수 있으며, 타입 셀렉터나 범용 셀렉터가 있을 경우 그 뒤에 와야 합니다.
참고: 일부 의사 클래스는 상호 배타적입니다 (즉, 복합 셀렉터에 둘 다 포함되면 유효하지만 일치하는 요소는 없습니다), 반면 일부는 동일 요소에 동시에 적용될 수 있습니다.
3.6. 의사 요소
일부 의사 클래스가 문서 트리에 직접 존재하지 않는 추가 상태 정보를 나타내듯이, 의사 요소는 문서 트리에 직접 존재하지 않는 요소를 나타냅니다. 이는 문서 트리 외의 추상화를 제공하기 위해 사용됩니다. 예를 들어, 의사 요소를 통해 문서 트리의 요소와 일치하지 않는 범위(요소 경계와 일치하지 않거나 트리 구조에 맞지 않는)를 선택하거나, 문서 트리에 없는 콘텐츠, 대체 투영 트리의 콘텐츠, 스타일, 레이아웃, 사용자 상호작용 등 문서 트리에 반영되지 않는 정보에 의존하는 부분을 선택할 수 있습니다.
의사 요소는 소스 문서에 전혀 존재하지 않는 콘텐츠도 나타낼 수 있습니다. 예를 들어 ::before, ::after 의사 요소는 임의의 요소 내용 앞뒤에 추가 콘텐츠를 삽입할 수 있게 해줍니다.
의사 클래스와 마찬가지로 의사 요소도 문서 소스나 트리에 나타나거나 변경하지 않습니다. 따라서 구조적 의사 클래스나 기원 요소 또는 트리와 관련된 다른 셀렉터의 해석에도 영향을 주지 않습니다.
호스트 언어는 어떤 의사 요소가 존재하는지, 그 타입과 기능을 정의합니다. CSS에서 존재하는 의사 요소는 [CSS21](Level 2), [SELECT](Level 3), [CSS-PSEUDO-4](Level 4)에서 각각 정의됩니다.
3.6.1. 문법
의사 요소의 문법은 "::"(U+003A 콜론 문자 두 개) 뒤에 의사 요소의 이름(식별자)이 옵니다. 의사 요소 이름은 ASCII 대소문자 구분 없음입니다. 두 콜론 사이 또는 콜론과 이름 사이에는 공백이 허용되지 않습니다.
CSS Level 1과 CSS Level 2에서는 의사 요소와 의사 클래스를 단일 콜론 문법으로 혼용했기 때문에, 사용자 에이전트는 Level 1 & 2 의사 요소 (::before, ::after, ::first-line, ::first-letter)에 대해 이전 단일 콜론 표기법도 허용해야 합니다. 이 호환성 표기법은 다른 의사 요소에는 사용할 수 없습니다. 하지만 이 문법은 더 이상 권장되지 않으므로, 작성자는 Level 3 이상의 의사 요소에는 반드시 이중 콜론 문법을 사용해야 합니다.
의사 요소는 무특성 요소이므로, 다른 셀렉터로 매칭할 수 없습니다.
3.6.2. 문서 트리에 바인딩
의사 요소는 트리에서 독립적으로 존재하지 않으며, 항상 페이지의 다른 요소에 바인딩됩니다. 이 요소를 기원 요소라고 합니다. 문법적으로, 의사 요소는 자신의 기원 요소를 나타내는 복합 셀렉터 바로 뒤에 옵니다. 만약 복합 셀렉터가 생략되면, 범용 셀렉터 *로 간주합니다.
::first-line 셀렉터는 *::first-line과 동일하며, 문서 내 모든 요소의 ::first-line 의사 요소를 선택합니다.
셀렉터에서 의사 요소가 등장하면, 해당 의사 요소 앞의 셀렉터 부분이 기원 요소를 선택하고, 그 뒤의 셀렉터 부분(있다면)은 의사 요소 자체에 적용됩니다. (아래 참고)
3.6.3. 의사 요소의 의사 클래스 적용
의사 요소 뒤에는 사용자 동작 의사 클래스를 조합할 수 있습니다. 이 경우 의사 요소가 해당 상태에 있을 때만 나타납니다. 이러한 의사 클래스가 의사 요소에서 매칭 가능한지는 의사 클래스 및 의사 요소의 정의에 따라 달라집니다: 별도 지정이 없는 한, 이러한 의사 클래스는 의사 요소에서 매칭되지 않습니다.
:not() 및 :is()가 위의 의사 클래스들과 함께 사용할 수 있음을 명확히 할 것.
::first-line:not(:focus)는 어떤 요소와 매칭되는가?
::first-line:hover와 :hover::first-line은 매우 다릅니다. :hover::first-line은 마우스가 올라간 모든 기원 요소의 첫 줄을 매칭합니다! 예를 들어, :hover::first-line은 단락의 두 번째 줄에 마우스를 올려도 첫 줄을 매칭하지만, ::first-line:hover는 실제로 첫 줄에 마우스를 올렸을 때만 매칭됩니다.
참고: 향후 명세에서 별도 지정이 없는 한, 사용자 동작 의사 클래스를 제외한 의사 클래스는 의사 요소에 조합할 수 없습니다. 예를 들어, ::before:first-child는 올바르지 않은 셀렉터입니다.
3.6.4. 하위 의사 요소
일부 의사 요소는 다른 의사 요소의 기원 요소가 될 수 있습니다. 이를 해당 하위 의사 요소, 그리고 기원 의사 요소라 합니다. 예를 들어, ::before에 list-item display 타입을 주면, ::before::marker 하위 의사 요소의 기원 의사 요소가 됩니다.
명확한 구분이 필요할 때, 최종 기원 요소란 의사 요소의 실제(비의사) 요소를 의미합니다.
해당 하위 의사 요소가 다른 명세에서 명시적으로 정의되어 있지 않다면, 의사 요소 셀렉터를 또 다른 의사 요소 셀렉터에 조합하는 것은 유효하지 않습니다. 예를 들어 ::before::before는 올바르지 않은 셀렉터이지만, ::before::marker는 유효합니다 (::before::marker 하위 의사 요소를 지원하는 구현에서).
3.6.5. 내부 구조
일부 의사 요소는 내부 구조를 가집니다. 이러한 의사 요소 뒤에는 자식/자손 결합자를 붙여 관계를 표현할 수 있습니다. 의사 요소 뒤에 결합자가 오는 셀렉터는 그 외에는 올바르지 않습니다.
참고: 향후 명세에서 기존 의사 요소의 기능이 확장될 수 있으므로, 현재는 올바르지 않지만 앞으로는 유효해질 수 있는 셀렉터(::first-line :any-link 등)도 있습니다.
이러한 의사 요소의 자식은 동시에 다른 요소의 자식이 될 수도 있습니다. 하지만 적어도 CSS에서는 렌더링이 박스 트리의 트리 구조를 유지하도록 정의되어야 합니다.
<div> <span>foo</span> <"shadow root"> <content></content> </"shadow root"> </div>
이때 div > span과 div::shadow ::slotted > span은 각각 다른 경로로 같은 요소를 선택합니다.
하지만 렌더링 시,
<span>
요소는 <content>
요소의 자식처럼 박스를 생성하며,
<div>
의 자식처럼 보이지 않습니다.
따라서 박스 트리의 트리 구조가 유지됩니다.
3.7. 문자 및 대소문자 구분
모든 셀렉터 문법은 ASCII 대소문자 구분 없음(즉, [a-z]와 [A-Z]가 동일)입니다. 단, 셀렉터에서 제어하지 않는 부분, 즉 문서 언어의 요소명, 속성명, 속성값의 대소문자 구분 여부는 문서 언어에 따라 다릅니다.
네임스페이스 접두사의 대소문자 구분 여부는 [CSS3NAMESPACE]에서 정의합니다. 언어 범위의 대소문자 구분 여부는 :lang() 섹션에서 정의합니다.
공백은 셀렉터에서 다음 코드 포인트를 의미합니다: SPACE(U+0020), TAB(U+0009), LINE FEED(U+000A), CARRIAGE RETURN(U+000D), FORM FEED(U+000C). EM SPACE(U+2003), IDEOGRAPHIC SPACE(U+3000) 등 다른 공백 유사 코드는 문법적 공백으로 간주하지 않습니다.
셀렉터 내 코드 포인트는 CSS와 동일한 이스케이프 규칙에 따라 역슬래시로
이스케이프할 수 있습니다. [CSS21] 이스케이프하면 해당 코드 포인트의 셀렉터 내 특별 의미가
사라집니다.
예를 들어, #foo>a는 결합자가 포함되지만,
#foo\>a는 id가 foo>a
인 요소를 선택합니다.
3.8. 네임스페이스 접두사 선언
특정 셀렉터는 네임스페이스 접두사를 지원합니다. 네임스페이스 접두사를 선언하는 방법은 셀렉터를 사용하는 언어가 지정해야 합니다. 언어에서 접두사 선언 방식을 지정하지 않으면, 접두사는 선언되지 않은 것으로 간주합니다. CSS에서는 @namespace 규칙으로 네임스페이스 접두사를 선언합니다. [CSS3NAMESPACE]
3.9. 잘못된 셀렉터 및 오류 처리
사용자 에이전트는 잘못된 셀렉터 처리 규칙을 따라야 합니다:
- 셀렉터 구문 오류(예: 인식할 수 없는 토큰, 현재 구문 위치에서 허용되지 않는 토큰 등, § 18 문법 및 각 셀렉터 문법 참고)는 잘못된 셀렉터가 됩니다.
- 선언되지 않은 네임스페이스 접두사가 포함된 단순 셀렉터는 잘못된 셀렉터입니다.
- 잘못된 단순 셀렉터, 잘못된 결합자, 잘못된 토큰이 포함된 셀렉터는 잘못된 셀렉터입니다.
- 잘못된 셀렉터가 포함된 셀렉터 리스트는 잘못된 셀렉터입니다.
- 빈 셀렉터(즉, 복합 셀렉터가 전혀 없는 셀렉터)는 잘못된 셀렉터입니다.
참고: CSS의 미래 대응 구문 원칙과 일치하게, UA는 지원하지 않는 의사 클래스, 의사 요소, 결합자, 기타 문법 구조를 반드시 잘못된 셀렉터로 처리해야 합니다. 부분 구현 참고.
잘못된 셀렉터는 어떤 것도 나타내지 않으므로, 아무것도 매칭하지 않습니다.
3.10. 레거시 별칭
일부 셀렉터는 레거시 셀렉터 별칭을 가집니다. 이는 파싱 시 표준 이름으로 변환되는 이름이며, 셀렉터를 나타내는 어떤 오브젝트 모델에도 나타나지 않습니다.
4. 논리 조합
4.1. 셀렉터 리스트
쉼표로 구분된 셀렉터 리스트는 셀렉터 리스트의 각 셀렉터로 선택된 모든 요소의 합집합을 나타냅니다. (쉼표는 U+002C) CSS에서는 여러 셀렉터가 동일한 선언을 공유할 때 쉼표 구분 리스트로 그룹화할 수 있습니다. 쉼표 앞뒤에는 공백이 올 수 있습니다.
h1 { font-family: sans-serif } h2 { font-family: sans-serif } h3 { font-family: sans-serif }
이는 다음과 동일합니다:
h1, h2, h3 { font-family: sans-serif }
경고: 이 예시에서 모든 셀렉터가 올바른 셀렉터이기 때문에 동일합니다. 만약 셀렉터 중 하나라도 잘못된 셀렉터라면 전체 셀렉터 리스트가 잘못된 셀렉터가 됩니다. 그러면 세 개 제목 요소에 대한 규칙 전체가 무효가 되지만, 분리된 경우에는 개별 규칙만 무효가 됩니다.
h1 { font-family: sans-serif } h2..foo { font-family: sans-serif } h3 { font-family: sans-serif }
이는 다음과 동일하지 않습니다:
h1, h2..foo, h3 { font-family: sans-serif }
위 h1, h2..foo, h3 셀렉터는 전체가 잘못된 셀렉터이므로 전체 스타일 규칙이 무시됩니다. (그룹화하지 않으면 h2..foo 규칙만 무효가 됩니다.)
4.2. 매칭-임의 의사 클래스: :is()
매칭-임의 의사 클래스 :is()는 <forgiving-selector-list>를 인자로 받는 함수형 의사 클래스입니다.
파싱 후 인자가 빈 리스트이면, 의사 클래스는 유효하지만 아무것도 매칭하지 않습니다. 그렇지 않으면, 리스트의 셀렉터 중 하나라도 매칭하는 요소에 매칭됩니다.
참고: :is() 의사 클래스의 특이성은 인자 중 가장 특이성이 높은 값으로 대체됩니다.
즉, :is()를 사용한 셀렉터는
:is() 없이 쓴 셀렉터와 특이성이 반드시 같지는 않습니다. 예를 들어 :is(ul, ol, .list) > [hidden]과 ul >
[hidden], ol > [hidden], .list > [hidden]에서 [hidden] 자식이
ol
요소라면
첫 번째 셀렉터는 특이성이 (0,2,0)이고,
두 번째 셀렉터는 (0,1,1)입니다.
§ 17 셀렉터의 특이성 계산 참고.
의사 요소는 매칭-임의 의사 클래스에서 사용할 수 없으며, :is() 내에서 사용할 수 없습니다.
기본 네임스페이스 선언은 복합 셀렉터의 주체를 :is() 의사 클래스 내에서 나타내더라도, 해당 복합 셀렉터에 범용 셀렉터나 타입 셀렉터가 명시적으로 포함되지 않는 한 영향을 주지 않습니다.
*|*:is(:hover, :focus)
다음 셀렉터는 :is() 표기법 내에 명시적 범용 셀렉터를 사용했으므로, 기본 네임스페이스의 hover 또는 focus된 요소만 나타냅니다:
*|*:is(*:hover, *:focus)
이 명세의 이전 초안에서는 이 의사 클래스에 :matches()라는 이름을 썼으므로, UA는 필요하다면 레거시 셀렉터 별칭으로 :is() 대신 구현할 수 있습니다.
4.3. 부정(일치 없음) 의사 클래스: :not()
부정 의사 클래스 :not()는 셀렉터 리스트를 인자로 받는 함수형 의사 클래스입니다. 인자로 나타낸 요소가 아닌 요소를 나타냅니다.
참고: Selectors Level 3에서는 :not()의 인자로 단일 단순 셀렉터만 허용했습니다.
참고: :not() 의사 클래스의 특이성은 인자 중 가장 높은 셀렉터의 특이성으로 대체됩니다; 즉 :not(:is(argument))와 정확히 동일하게 동작합니다. § 17 셀렉터의 특이성 계산 참고.
의사 요소는 부정 의사 클래스에서 사용할 수 없으며, :not() 내에서 사용할 수 없습니다.
button:not([DISABLED])
다음 셀렉터는 FOO 요소를 제외한 모든 요소를 나타냅니다.
*:not(FOO)
다음 복합 셀렉터는 HTML 요소 중 링크가 아닌 모든 요소를 나타냅니다.
html|*:not(:link):not(:visited)
:is()와 마찬가지로, 기본 네임스페이스 선언은 복합 셀렉터의 주체를 :not() 의사 클래스 내에서 나타내더라도, 해당 복합 셀렉터에 범용 셀렉터나 타입 셀렉터가 명시적으로 포함되지 않는 한 영향을 주지 않습니다. (:is() 예시 참고.)
참고: :not() 의사 클래스는 쓸모없는 셀렉터도 작성할 수 있습니다. 예를 들어 :not(*|*)는 아무 요소도 나타내지 않으며, div:not(span)은 div와 본질적으로 같지만 특이성은 더 높습니다.
4.4. 특이성 조정 의사 클래스: :where()
특이성 조정 의사 클래스 :where()는
:is()와 동일한
문법과 기능을 갖는 함수형 의사 클래스입니다.
:is()와 달리, :where() 의사 클래스와
그 인자는
셀렉터의 특이성에 어떠한 영향도 주지 않습니다—
이는 셀렉터에 필터를 도입하면서도 연결된 스타일 선언을 쉽게 오버라이드할 수 있도록 하는 데 유용합니다.
a:not(:hover) { text-decoration: none; } nav a { /* 효과 없음 */ text-decoration: underline; }
하지만 :where()를 사용하면 작성자가 명확하게 의도를 선언할 수 있습니다:
a:where(:not(:hover)) { text-decoration: none; } nav a { /* 이제 동작함! */ text-decoration: underline; }
참고: 향후 셀렉터 레벨에서는 해당 의사 클래스 인스턴스의 특이성을 명시적으로 지정할 수 있는 추가 인자를 도입할 수 있습니다.
4.5. 관계형 의사 클래스: :has()
관계형 의사 클래스 :has()는 <forgiving-relative-selector-list>를 인자로 받는 함수형 의사 클래스입니다. 상대 셀렉터들이 이 요소를 앵커로 평가할 때, 최소 하나의 요소와 매칭된다면 해당 요소를 나타냅니다.
:has() 의사 클래스는 중첩될 수 없습니다; :has() 안에 :has()를 포함하는 것은 유효하지 않습니다. 또한 명시적으로 :has-허용 의사 요소로 정의되지 않는 한, 의사 요소는 :has() 내에서 유효한 셀렉터가 아닙니다. (이 명세에서는 :has-허용 의사 요소를 정의하지 않지만, 다른 명세에서 정의될 수 있습니다.)
참고: 많은 의사 요소가 상위 요소의 스타일에 따라 조건부로 존재하므로, :has()에서 이를 쿼리하도록 허용하면 사이클이 발생할 수 있으므로 일반적으로 제외됩니다.
<a>
요소 중
<img>
자식을 포함하는 것만 매칭합니다:
a:has(> img)
다음 셀렉터는 <dt>
요소 바로 뒤에 또 다른 <dt>
요소가 올 때 매칭합니다:
dt:has(+ dt)
다음 셀렉터는 어떤 heading 요소도 포함하지 않는 <section>
요소에 매칭합니다:
section:not(:has(h1, h2, h3, h4, h5, h6))
위 셀렉터에서 순서가 중요합니다. 두 의사 클래스의 중첩을 바꾸면 다음과 같이 됩니다:
section:has(:not(h1, h2, h3, h4, h5, h6))
...이 경우 heading 요소가 아닌 것을 포함하는 모든 <section>
요소를 매칭하게 됩니다.
5. 요소 셀렉터
5.1. 타입(태그명) 셀렉터
타입 셀렉터는 문서 언어 요소 타입의 이름이며, 문서 트리 내 해당 요소 타입의 인스턴스를 나타냅니다.
타입 셀렉터는 CSS 자격 이름(qualified name)으로 작성합니다: 네임스페이스 접두사가 선택적으로 붙은 식별자입니다. [CSS3NAMESPACE] (§ 5.3 요소 셀렉터의 네임스페이스 참고.)
5.2. 범용 셀렉터
범용 셀렉터는 모든 요소 타입을 나타내는 특별한 타입 셀렉터입니다.
이는 CSS 자격 이름 형태로, 로컬 이름에 별표(*
U+002A)를 사용합니다.
타입 셀렉터와 마찬가지로,
범용 셀렉터도 네임스페이스로 한정할
수 있으며,
해당 네임스페이스에 속한 요소만 선택할 수 있습니다.
기본 네임스페이스의 영향을 받습니다(§ 5.3 요소 셀렉터의 네임스페이스 참고).
요소가 무특성이 아니라면, 범용 셀렉터의 존재는 요소가 셀렉터와 일치하는지에 아무런 영향을 주지 않습니다. (무특성 요소는 범용 셀렉터를 포함한 어떤 셀렉터와도 일치하지 않습니다.)
범용 셀렉터는 다른 타입 셀렉터와 동일한 문법 규칙을 따릅니다: 복합 셀렉터마다 하나만 나타날 수 있고, 복합 셀렉터에서 첫 번째 단순 셀렉터여야 합니다.
참고: 경우에 따라 범용 셀렉터를 추가하면 매칭 동작에는 영향이 없어도 셀렉터를 더 읽기 쉽게 만들 수 있습니다. 예를 들어 div :first-child와 div:first-child는 빠르게 보면 구분이 어렵지만, 전자는 div *:first-child로 쓰면 차이가 명확해집니다.
5.3. 요소 셀렉터의 네임스페이스
타입 셀렉터와 범용 셀렉터는 선택적 네임스페이스 컴포넌트를 허용합니다:
앞서 선언된 네임스페이스 접두사를 요소 이름 앞에 네임스페이스 구분자 "vertical
bar"(|
U+007C)로 붙일 수 있습니다.
(XML에서 네임스페이스 사용 예시는 [XML-NAMES] 참고.)
각각의 형태는 다음 의미를 갖습니다:
ns|E
- ns 네임스페이스에 속한 이름 E 요소
*|E
- 모든 네임스페이스(네임스페이스 없는 것 포함)에 속한 이름 E 요소
|E
- 네임스페이스 없는 이름 E 요소
E
- 셀렉터에 대해 기본 네임스페이스가 선언되지 않았다면 *|E와 동일, 그렇지 않으면 기본 네임스페이스 ns의 ns|E와 동일
@namespace foo url(http://www.example.com); foo|h1 { color: blue } /* 첫 번째 규칙 */ foo|* { color: yellow } /* 두 번째 규칙 */ |h1 { color: red } /* ...*/ *|h1 { color: green } h1 { color: green }
첫 번째 규칙(@namespace at-rule 제외)은 "http://www.example.com" 네임스페이스의 h1 요소만 매칭합니다.
두 번째 규칙은 "http://www.example.com" 네임스페이스의 모든 요소를 매칭합니다.
세 번째 규칙은 네임스페이스 없는 h1 요소만 매칭합니다.
네 번째 규칙은 모든 네임스페이스(네임스페이스 없는 것 포함)의 h1 요소를 매칭합니다.
마지막 규칙은 기본 네임스페이스가 정의되지 않았으므로 네 번째 규칙과 동일합니다.
기본 네임스페이스가 선언되어 있으면, 복합 셀렉터 내에 타입 셀렉터가 없어도 기본 네임스페이스의 요소만 매칭합니다.
@namespace url("http://example.com/foo"); .special { ... }
.special 셀렉터는 "http://example.com/foo" 네임스페이스의 요소만 매칭합니다. 타입 이름(네임스페이스와 DOM에서 쌍을 이루는)이 명시적으로 참조되지 않아도 마찬가지입니다.
타입 셀렉터나 범용 셀렉터에 앞서 선언되지 않은 네임스페이스 접두사가 포함되어 있다면, 이는 잘못된 셀렉터입니다.
5.4. 정의됨 의사 클래스: :defined
일부 호스트 언어에서는 요소가 "정의됨"/"생성됨" 상태인지 아닌지를 구분할 수 있습니다. :defined 의사 클래스는 호스트 언어가 규정한 바에 따라 완전히 정의된 요소에 매칭됩니다.
호스트 언어가 이런 구분을 지원하지 않는 경우, 해당 언어의 모든 요소가 :defined와 매칭됩니다.
p : defined{ ...}
커스텀 요소는 반대로 처음에는 정의되지 않은 상태로 시작하며, 올바르게 등록되어야만 정의됩니다. 따라서 :defined 의사 클래스를 사용해 커스텀 요소가 등록되기 전까지 숨길 수 있습니다:
custom-element { visibility: hidden }
custom-element:defined { visibility: visible }
6. 속성 셀렉터
셀렉터는 요소의 속성을 표현할 수 있습니다. 셀렉터가 요소에 대해 매칭 표현식으로 사용될 때, 속성 셀렉터는 해당 요소가 속성 셀렉터가 나타내는 속성과 일치하는 속성을 가지고 있으면 매칭되는 것으로 간주해야 합니다.
다중 값 매칭을 위한 쉼표 구분 문법 추가? 예: [rel ~= next, prev, up, first, last]
6.1. 속성 존재 및 값 셀렉터
CSS2에서는 네 가지 속성 셀렉터가 도입되었습니다:
- [att]
-
att
속성이 있는 요소를 나타냅니다. 값이 무엇이든 상관 없습니다. - [att=val]
-
att
속성 값이 정확히 "val"인 요소를 나타냅니다. - [att~=val]
-
att
속성 값이 공백으로 구분된 단어 목록이며, 그 중 하나가 정확히 "val"인 요소를 나타냅니다. "val"에 공백이 포함되어 있으면 아무것도 나타내지 않습니다(단어가 공백으로 분리되기 때문). 또한 "val"이 빈 문자열이면 아무것도 나타내지 않습니다. - [att|=val]
-
att
속성이 있고, 값이 정확히 "val"이거나 "val"로 시작하고 바로 뒤에 "-"(U+002D)가 오는 요소를 나타냅니다. 주로 언어 하위 코드 매칭(e.g. HTML의hreflang
속성)에 쓰이며, BCP 47 ([BCP47]) 또는 그 후속 규격에 설명되어 있습니다.lang
(또는xml:lang
) 언어 하위 코드 매칭은 :lang() 의사 클래스를 참고하세요.
속성 값은 <ident-token> 또는 <string-token>이어야 합니다. [CSS3SYN]
다음 속성 셀렉터는 h1 요소 중 title
속성이 있는 요소(값 무관)를 나타냅니다:
h1[title]
다음 예시는 span 요소 중 class
속성 값이 정확히 "example"인 요소를 나타냅니다:
span[class="example"]
속성 셀렉터를 여러 개 사용하여 요소의 여러 속성 또는 동일 속성에 여러 조건을 나타낼 수 있습니다. 아래 셀렉터는 span 요소 중
hello
속성 값이 "Cleveland"이고 goodbye
속성 값이 "Columbus"인 요소를 나타냅니다:
span[hello="Cleveland"][goodbye="Columbus"]
다음 CSS 규칙은 "="와 "~="의 차이를 보여줍니다. 첫 번째 셀렉터는 a 요소의 rel
속성 값이 "copyright copyleft
copyeditor"인 경우 매칭합니다. 두 번째 셀렉터는 a 요소의 href
속성 값이 정확히 "http://www.w3.org/"인 경우만 매칭합니다.
a[rel~="copyright"] { ... } a[href="http://www.w3.org/"] { ... }
다음 셀렉터는 a 요소 중
hreflang
속성 값이 정확히 "fr"인 요소를 나타냅니다.
a[hreflang=fr]
다음 셀렉터는 a 요소 중
hreflang
속성 값이 "en"으로 시작하는 모든 경우(예: "en", "en-US", "en-scouse")를 나타냅니다:
a[hreflang|="en"]
다음 셀렉터들은 DIALOGUE 요소의 character
속성 값이 각각 "romeo" 또는
"juliet"일 때 매칭합니다:
DIALOGUE[character=romeo] DIALOGUE[character=juliet]
6.2. 부분 문자열 매칭 속성 셀렉터
속성 값에서 부분 문자열을 매칭하기 위한 추가 속성 셀렉터 세 가지가 제공됩니다:
- [att^=val]
-
att
속성 값이 "val" 접두어로 시작하는 요소를 나타냅니다. "val"이 빈 문자열이면 아무것도 나타내지 않습니다. - [att$=val]
-
att
속성 값이 "val" 접미어로 끝나는 요소를 나타냅니다. "val"이 빈 문자열이면 아무것도 나타내지 않습니다. - [att*=val]
-
att
속성 값에 "val" 부분 문자열이 하나 이상 포함된 요소를 나타냅니다. "val"이 빈 문자열이면 아무것도 나타내지 않습니다.
속성 값은 <ident-token> 또는 <string-token>이어야 합니다.
object[type^="image/"]
다음 셀렉터는 HTML a 요소 중 href
속성 값이 ".html"로 끝나는 경우를 나타냅니다.
a[href$=".html"]
다음 셀렉터는 HTML 단락 중 title
속성 값에 "hello" 부분 문자열이 포함된 경우를 나타냅니다.
p[title*="hello"]
6.3. 대소문자 구분
기본적으로 셀렉터에서 속성 이름과 값의 대소문자 구분 여부는 문서 언어에 따라 다릅니다.
문서 언어 규칙과 관계없이 속성 값을 ASCII 대소문자 구분 없이 매칭하려면,
속성 셀렉터 끝 닫는 괄호(]
) 앞에 i
식별자를 포함할 수 있습니다.
이 플래그가 있으면,
UA는 속성 값을 ASCII 대소문자 구분 없이([a-z]와 [A-Z]가 동일) 매칭해야 합니다.
또는, 속성 셀렉터에 s
식별자를 포함시키면,
UA는 값이 대소문자를 구분하여 "동일"한지 판단하며, 문서 언어 규칙과 관계없이 대소문자를 구분합니다.
셀렉터 문법 전체와 마찬가지로,
i
와 s
식별자 자체는 ASCII
대소문자 구분 없음입니다.
frame
속성 값이 hsides
일 때
스타일을 적용합니다. 값이 hsides
, HSIDES
, hSides
등이어도 XML 환경에서 속성값이 대소문자를 구분하더라도
적용됩니다.
[frame=hsides i] { border-style: solid none; }
type="a"
속성을 가진 리스트와
type="A"
속성을 가진 리스트를 HTML에서 type
속성이 대소문자 구분 없이 정의되어 있어도 각각 다르게 스타일합니다.
[type="a" s] { list-style: lower-alpha; } [type="A" s] { list-style: upper-alpha; }
참고: 일부 문서 모델은 파싱 시 대소문자 구분 없이 속성값을 정규화하므로, 대소문자 구분 매칭이 불가능합니다.
s
플래그로 대소문자 구분 매칭은 원본 대소문자를 보존하는 시스템에서만 가능합니다.
6.4. 속성 셀렉터와 네임스페이스
속성 셀렉터에서 속성 이름은 CSS 자격 이름으로 주어집니다. 앞서 선언된 네임스페이스 접두사를 속성 이름 앞에 "vertical bar"(|
)로 붙일 수 있습니다. XML 네임스페이스
권고에 따라, 기본 네임스페이스는 속성에 적용되지 않으므로 네임스페이스 없이 지정된 속성 셀렉터는 네임스페이스 없는 속성(즉, |attr)에만
적용됩니다. 네임스페이스 접두사로 별표(*)를 쓰면 속성 네임스페이스와 관계없이 모든 속성 이름에 대해 셀렉터가 동작합니다.
앞서 선언되지 않은 네임스페이스 접두사가 포함된 속성 이름 셀렉터는 잘못된 셀렉터입니다.
@namespace foo "http://www.example.com"; [foo|att=val] { color: blue } [*|att] { color: yellow } [|att] { color: green } [att] { color: green }
첫 번째 규칙은 "http://www.example.com" 네임스페이스의 att
속성이 있고 값이 "val"인 요소만 매칭합니다.
두 번째 규칙은 속성 네임스페이스와 관계없이 att
속성이 있는 요소만 매칭합니다(네임스페이스 없는 속성 포함).
마지막 두 규칙은 동등하며, 네임스페이스 없는 att
속성이 있는 요소만 매칭합니다.
6.5. DTD의 기본 속성 값
속성 셀렉터는 문서 트리의 속성 값을 나타냅니다. 문서 트리가 어떻게 구성되는지는 셀렉터의 범위 밖입니다. 일부 문서 포맷에서는 DTD나 기타에서 기본 속성 값을 정의할 수 있지만, 문서 트리에 해당 값이 실제로 나타나야만 속성 셀렉터로 선택할 수 있습니다. 셀렉터는 기본값이 문서 트리에 포함되는지 여부와 관계없이 동작하도록 설계해야 합니다.
예를 들어, XML UA는 "외부 서브셋" DTD를 읽을 수도 있지만 필수는 아니며, "내부 서브셋"의 기본 속성 값은 반드시 확인해야 합니다. (이 서브셋 정의는 [XML10] 참고.) UA에 따라 외부 서브셋에 정의된 기본 속성 값이 문서 트리에 나타날 수도, 나타나지 않을 수도 있습니다.
XML 네임스페이스를 인식하는 UA는, 필수는 아니지만 해당 네임스페이스의 기본 속성 값을 실제로 문서에 있는 것처럼 처리할 수도 있습니다. (예: XHTML UA는 XHTML DTD에 대한 내장 지식을 반드시 사용할 필요가 없습니다. XML 1.0의 네임스페이스에 관한 자세한 내용은 [XML-NAMES] 참고.)
참고: 일반적으로 구현체는 외부 서브셋을 무시합니다. 이는 XML 명세에서 정의된 비검증 처리기(non-validating processor)의 동작과 일치합니다.
radix
속성의 기본값이 "decimal"
인 EXAMPLE
요소가 있다고 가정해 봅니다. DTD 조각은 다음과 같을
수 있습니다.
<!ATTLIST EXAMPLE radix (decimal,octal) "decimal">
스타일 시트가 아래 규칙을 포함한다면
EXAMPLE[radix=decimal] { /*... 기본 프로퍼티 설정 ...*/ } EXAMPLE[radix=octal] { /*... 기타 설정 ...*/ }
첫 번째 규칙이 기본값(즉, 명시적으로 설정되지 않은 경우)의 radix
속성을 가진 요소에 적용되지 않을 수 있습니다. 모든 경우를 잡으려면 기본값에 대한 속성
셀렉터를 제거해야 합니다:
EXAMPLE { /*... 기본 프로퍼티 설정 ...*/ } EXAMPLE[radix=octal] { /*... 기타 설정 ...*/ }
여기서 ''EXAMPLE[radix=octal]'' 셀렉터가 타입 셀렉터만 있을 때보다 더 구체적이므로,
radix
속성 값이 "octal"
인 요소에는 두 번째 규칙의 스타일 선언이 첫 번째 규칙보다 우선 적용됩니다. 기본값에만 적용되는 프로퍼티
선언이 비기본값 스타일 규칙에서 반드시 오버라이드되도록 주의해야 합니다.
6.6. 클래스 셀렉터
클래스 셀렉터는 식별자 앞에 점(.
U+002E)을 바로 붙여서 작성합니다. 이는 해당 식별자가 지정한 클래스에 속한 요소를 나타냅니다(문서 언어에서 정의). 예를 들어 [HTML5], [SVG11], [MATHML]에서는
class
속성으로 클래스 소속을 결정합니다. 이 언어들에서는 class
속성의 ~=
표기와 동등합니다(즉
[class~=identifier]
).
class~="pastoral"
인 모든 요소에 스타일을 적용하려면 다음과 같이 쓸 수 있습니다:
*.pastoral { color: green } /* class~=pastoral인 모든 요소 */
또는 단순히
.pastoral { color: green } /* class~=pastoral인 모든 요소 */
다음은 class~="pastoral"
인 H1 요소에만 스타일을 적용합니다:
H1.pastoral { color: green } /* class~=pastoral인 H1 요소 */
이 규칙이 있을 때 아래 첫 번째 H1
은 녹색이 아니고, 두 번째 H1
은 녹색이 됩니다:
<H1>Not green</H1> <H1 class="pastoral">Very green</H1>
다음 규칙은 P 요소 중 class
속성 값이 공백으로 구분된 여러 값 중 pastoral
과 marine
을 모두 포함하는
경우에만 매칭합니다:
p.pastoral.marine { color: green }
이 규칙은 class="pastoral blue aqua
marine"
일 때 매칭하지만 class="pastoral
blue"
일 때는 매칭하지 않습니다.
참고: CSS는 "class" 속성에 큰 힘을 부여하므로, 작성자가 div, span 등 구조적 의미가 거의 없는 요소로 "문서 언어"를 만들고 스타일을 class 속성에만 할당할 수도 있습니다. 하지만 구조적 요소는 의미가 있으므로, 임의 class로만 문서를 설계하는 것은 피하는 것이 좋습니다.
참고: 요소에 여러 개의 class 속성이 있으면, 값들을 공백으로 연결한 후 class를 검색해야 합니다. 하지만 현재 작업 그룹에서는 이런 상황을 만들 수 있는 방법을 알지 못하므로, 이 동작은 명세에서 규범적이지 않습니다.
문서가 쿼크 모드일 때, 클래스 이름은 ASCII 대소문자 구분 없이 매칭해야 합니다. 그렇지 않으면 클래스 셀렉터는 대소문자 구분하며, 동일한 클래스 이름만 매칭합니다. [INFRA]
6.7. ID 셀렉터
문서 언어에는 ID 타입으로 선언된 속성이 있을 수 있습니다.
ID 타입 속성이 특별한 이유는, 해당 값을 가진 속성은 어떤 요소 타입이든 관계없이 문서 내에서 중복될 수 없다는 점입니다.
문서 언어가 무엇이든 ID 타입 속성은 요소를 고유하게 식별하는 데 사용할 수 있습니다.
HTML에서는 모든 ID 속성이 id
로 이름 붙여집니다;
XML에서는 이름이 다를 수 있지만 동일한 제한이 적용됩니다.
어떤 속성이 "ID 속성"으로 간주되는지는 문서 언어가 정의합니다.
ID 셀렉터는 "숫자 기호"(U+0023,
#
) 바로 뒤에 ID 값을 붙여 작성하며,
ID 값은 CSS 식별자여야 합니다.
ID 셀렉터는 ID 값이 일치하는 요소 인스턴스를 나타냅니다.
(비준수 문서에서는 하나의 ID 셀렉터에 여러 요소가 매칭될 수도 있습니다.)
h1#chapter1
다음 ID 셀렉터는 ID 타입 속성 값이 "chapter1"인 모든 요소를 나타냅니다:
#chapter1
다음 셀렉터는 ID 타입 속성 값이 "z98y"인 모든 요소를 나타냅니다.
*#z98y
참고: XML 1.0 [XML10]에서는, 요소의 ID가 들어있는 속성 정보가 DTD나 스키마에 포함됩니다. XML을 파싱할 때 UA가 항상 DTD를 읽는 것은 아니므로, 요소의 ID 속성이 무엇인지 모를 수도 있습니다(하지만 UA가 해당 네임스페이스에 대한 지식을 가지면 어떤 속성이 ID인지 알 수 있습니다). 스타일 시트 작성자가 UA가 요소의 ID를 모르리라 예상된다면, 일반 속성 셀렉터를 사용하는 것이 좋습니다: ''[name=p371] 대신 #p371''.
요소에 여러 개의 ID 속성이 있으면, 모두 해당 요소의 ID로 간주해야 합니다. xml:id, DOM3 Core, XML DTD, 네임스페이스별 정보 등을 혼합하면 이런 상황이 발생할 수 있습니다.
문서가 쿼크 모드일 때, ID는 ASCII 대소문자 구분 없이 매칭해야 합니다. 그렇지 않으면 ID 셀렉터는 대소문자 구분하며, 동일한 ID만 매칭합니다. [INFRA]
7. 언어적 의사 클래스
7.1. 방향성 의사 클래스: :dir()
:dir()
의사 클래스는 작성자가 요소의 방향성을
문서 언어에 의해 결정된 값에 따라
나타내는 셀렉터를 작성할 수 있게 해줍니다.
예를 들어, [HTML5]에서는 요소의 방향성이 어떻게 결정되는지를
dir
속성, 주변 텍스트, 기타 요인의 조합으로 정의합니다.
또 다른 예로, Internationalization Tag Set의 its:dir
및 dirRule
요소는
[ITS20]에서 [XML10] 문서 내에서 방향성을 정의할 수 있습니다.
:dir() 의사 클래스는 스타일 상태에 따라 선택하지 않습니다. 예를 들어 CSS의 direction 프로퍼티는 매칭에 영향을 주지 않습니다.
:dir(ltr) 의사 클래스는 방향성이 왼쪽-오른쪽(ltr
)인 요소를 나타냅니다.
:dir(rtl) 의사 클래스는 방향성이 오른쪽-왼쪽(rtl
)인 요소를 나타냅니다.
:dir()의 인자는 반드시 하나의
식별자여야 하며, 그렇지 않으면 셀렉터가 잘못된 셀렉터가 됩니다. 식별자와 괄호 사이에 선택적으로 공백을 둘 수 있습니다. ltr
과 rtl
이 아닌
값은 무효가 아니지만 아무것도 매칭하지 않습니다. (향후 마크업 명세에서 다른 방향성을 정의하면, Selectors도 확장될 수 있습니다.)
:dir(C)와 ''[dir=C]''의 차이는 ''[dir=C]''는 요소의 속성과 비교만 하지만, :dir(C) 의사 클래스는 UA가 문서 의미를 인식하여 비교한다는 점입니다. 예를 들어 HTML에서 dir
속성이 없는 자식은
가장 가까운 상위 dir
속성 값을 상속받아 방향성이 결정됩니다. 또 다른 예로, HTML에서 ''[dir=auto]''는 요소의 실제 방향성이 결정되면 :dir(ltr) 또는 :dir(rtl) 중 하나와 매칭됩니다. [HTML5]
7.2. 언어 의사 클래스: :lang()
문서 언어가 요소의 (인간) 콘텐츠 언어를 결정하는 방법을 정의한다면, 해당 콘텐츠 언어를 기준으로 요소를 나타내는 셀렉터를 작성할 수 있습니다. :lang() 의사 클래스는 쉼표로 구분된 하나 이상의 언어 범위를 인자로 받아, 인자에 있는 언어 중 하나라도 콘텐츠 언어인 요소를 나타냅니다. :lang()의 각 언어 범위는 유효한 CSS <ident> 또는 <string> 여야 합니다. (별표(*)가 포함된 언어 범위는 반드시 올바르게 이스케이프하거나 문자열로 감싸야 합니다. 예: :lang(\*-Latn) 또는 :lang("*-Latn").)
참고: 요소의 콘텐츠 언어는 문서
언어가 정의합니다.
예를 들어 HTML [HTML5]에서는 콘텐츠 언어가 lang
속성,
meta 요소 정보,
그리고 프로토콜(예: HTTP 헤더 등)로 결정됩니다.
XML 언어는 xml:lang
속성으로 요소의 언어 정보를 나타낼 수 있습니다. [XML10]
요소의 콘텐츠 언어가 언어 범위와 일치하는지 여부는,
BCP 47 문법 [BCP47]으로 표현했을 때,
[RFC4647] Matching of Language
Tags(섹션 3.3.2)의 확장 필터링 연산에 따라 언어 범위와 비교합니다.
이때 와일드카드 언어 범위("*"
)는
언어 태그가 없는 요소(lang=""
)에는 매칭되지 않지만,
언어가 미확정(lang=und
)인 경우에는 매칭됩니다.
매칭은 ASCII 대소문자 구분 없이 수행합니다.
언어 범위가 유효한 언어 코드가 아니어도 비교가 가능합니다.
빈 문자열(:lang(""))로 이루어진 언어 범위는 언어 태그가 없는 요소만 매칭합니다.
참고: 문서와 프로토콜은 [BCP47] 또는 후속 규격의 언어 코드를 사용해 언어를 표시하고, XML 기반 포맷의 경우 xml:lang
속성으로
표시하는 것이 권장됩니다. [XML10] “FAQ: 언어 코드 2글자 또는 3글자” 참고
html:lang(fr-be) html:lang(de) :lang(fr-be) > q :lang(de) > q
참고: :lang(C)와 ''|='' 연산자의 차이는, ''|='' 연산자는 요소의 속성값과 비교만 하지만, :lang(C) 의사 클래스는 UA가 문서의 의미를 인식하여 비교합니다.
<body lang=fr> <p>Je suis français.</p> </body>
예를 들어, :lang(de-DE)는 de-DE, de-DE-1996, de-Latn-DE, de-Latf-DE, de-Latn-DE-1996 모두를 매칭하지만, ''[lang|=de-DE]는 de-DE''와 de-DE-1996만 매칭합니다.
첫 번째 서브태그(주 언어)에 대해 와일드카드 매칭을 하려면, 별표를 사용해야 합니다: *-CH는 de-CH, it-CH, fr-CH, rm-CH 모두를 매칭합니다.
이런 언어 범위 매칭으로 lang
속성 값을 기준으로 선택하려면,
속성 셀렉터와 언어 의사 클래스를 함께 사용하세요.
예: [lang]:lang(de-DE).
참고: 와일드카드 언어 매칭 및 쉼표 구분 리스트는 Level 4에서 새롭게 도입되었습니다.
8. 위치 의사 클래스
8.1. 하이퍼링크 의사 클래스: :any-link
:any-link
의사 클래스는 하이퍼링크의 소스 앵커 역할을 하는 요소를 나타냅니다.
예를 들어 [HTML5]에서는
a
또는
area
요소에
href
속성이 있다면 하이퍼링크로 간주하며, :any-link
와 매칭됩니다.
이 요소는 :link 또는 :visited와 매칭되는
경우도 포함하며,
:is(:link, :visited)와 동등합니다.
8.2. 링크 히스토리 의사 클래스: :link 및 :visited
사용자 에이전트는 일반적으로 방문하지 않은 하이퍼링크와 방문한 링크를 다르게 표시합니다. Selectors는 :link 및 :visited 의사 클래스로 이를 구분합니다:
일정 시간이 지나면, 사용자 에이전트는 방문한 링크를 다시 :link 상태로 돌릴 수 있습니다.
두 상태는 상호 배타적입니다.
스타일 시트 작성자가 :link와 :visited 의사 클래스를 남용해 사용자의 방문 사이트를 사용자의 동의 없이 알아내는 경우가 있을 수 있으므로, UA는 모든 링크를 방문하지 않은 링크로 처리하거나, 방문/비방문 링크를 다르게 렌더링하면서도 사용자의 프라이버시를 보호하는 다른 방법을 구현할 수 있습니다.
8.3. 로컬 링크 의사 클래스: :local-link
:local-link 의사 클래스는 작성자가 하이퍼링크를 사용자의 현재 사이트 위치에 따라 스타일링할 수 있게 해줍니다. 현재 페이지의 절대 URL과 하이퍼링크 대상의 절대 URL이 일치하는 하이퍼링크의 소스 앵커 요소를 나타냅니다. 하이퍼링크 대상에 프래그먼트 URL이 포함되어 있다면, 현재 URL의 프래그먼트도 일치해야 합니다; 그렇지 않으면 현재 URL의 프래그먼트 부분은 비교에서 제외됩니다.
nav :local-link { text-decoration: none; }
참고: 사용자가 같은 페이지 내의 다른 프래그먼트를 대상으로 링크를 클릭하거나
pushState
API로 URL이 바뀌거나,
또는 다른 페이지로 이동하거나 리다이렉트(HTTP, <meta http-equiv="...">
, 스크립트 등)로 인해
현재 URL이 변경될 수 있습니다.
UA는 :local-link,
아래의 :target 및 :target-within 의사 클래스가
이런 상태 변화에 올바르게 반응하도록 해야 합니다.
8.4. 타겟 의사 클래스: :target
일부 문서 언어에서는 문서의 URL이 문서 내 특정 요소를 가리키는 URL의 프래그먼트로 지정할 수 있습니다. 이렇게 가리키는 요소가 문서의 타겟 요소가 됩니다.
https://example.com/index.html#section2
는
https://example.com/index.html
문서에서 id="section2"
인 요소를 가리킵니다.
:target 의사 클래스는 문서의 타겟 요소와 매칭됩니다. 문서의 URL에 프래그먼트 식별자가 없다면, 문서에는 타겟 요소가 없습니다.
:target { color : red } :target::before { content : url(target.png) }
8.5. 타겟 컨테이너 의사 클래스: :target-within
:target-within 의사 클래스는 :target 의사 클래스가 적용되는 모든 요소, 그리고 flat tree의 자손(텍스트 노드 등 비요소 노드 포함)이 :target의 조건을 만족하는 요소에도 적용됩니다.
8.6. 참조 요소 의사 클래스: :scope
일부 컨텍스트에서는 셀렉터가 하나 이상의 스코프 루트를
기준으로 매칭됩니다.
예를 들어 querySelector()
메서드를 [DOM]에서 호출할 때 등입니다.
:scope 의사 클래스는
이 스코프 루트를 나타내며,
실제 요소일 수도 있고
DocumentFragment
와
같은 가상 요소일 수도 있습니다.
스코프 루트가 없다면 :scope는 문서의 루트(즉, :root)를 나타냅니다. 특정 요소에 매칭되도록 의도하는 명세는 반드시 스코프 루트를 정의해야 합니다.
가상 스코프 루트는 문서 프래그먼트의 루트를 나타내는 객체로, 셀렉터 패턴에서 다른 요소와의 관계를 표현할 때 사용됩니다. 이 스코프 루트는 해당 문서 프래그먼트 내의 모든 루트 요소의 부모 역할을 합니다. 가상 스코프 루트는 무특성이며, 셀렉터의 주체가 될 수 없습니다.
DocumentFragment
df
가 있다면,
df. querySelectorAll( ":scope > .foo" )
은 문서 프래그먼트에서 "최상위" .foo 요소(즉, document fragment가 parentNode
인
요소)를 모두 매칭합니다.
그러나 df
는 아무
요소도 매칭하지 않습니다.
문서 프래그먼트 자체는 셀렉터의
주체가 될 수 없기 때문입니다.
9. 사용자 동작 의사 클래스
인터랙티브 UI에서는 사용자 동작에 따라 렌더링이 변화할 수 있습니다. Selectors는 사용자가 동작 중인 요소를 선택하기 위한 여러 사용자 동작 의사 클래스를 제공합니다. (비인터랙티브 UA에서는 이 의사 클래스가 유효하지만 어떤 요소와도 매칭되지 않습니다.)
이 의사 클래스들은 상호 배타적이지 않습니다. 하나의 요소가 여러 사용자 동작 의사 클래스와 동시에 매칭될 수 있습니다.
a:link /* 방문하지 않은 링크 */ a:visited /* 방문한 링크 */ a:hover /* 마우스 오버 */ a:active /* 활성 링크 */
동적 의사 클래스 조합 예시:
a:focus a:focus:hover
마지막 셀렉터는 a 요소 중 :focus와 :hover 상태 모두에 있는 요소를 매칭합니다.
참고: 이 섹션에서 정의된 여러 의사 클래스가 언제 적용되는지 판단에 필요한 hit-testing의 세부 사항은 아직 정의되지 않았으며, 앞으로 정의될 예정입니다.
9.1. 포인터 호버 의사 클래스: :hover
:hover 의사 클래스는 사용자가 포인팅 장치로 요소를 지정할 때(반드시 활성화하지 않아도 됨) 적용됩니다. 예를 들어, 시각적 UA에서는 커서(마우스 포인터)가 해당 요소의 박스 위에 올라가면 이 의사 클래스가 적용됩니다. 하드웨어 제한으로 인해 호버를 감지할 수 없는 인터랙티브 UA(예: 호버 감지 불가 펜 디바이스)도 규격을 준수하는 것으로 간주합니다. 해당 UA에서는 이 셀렉터가 절대 매칭되지 않을 뿐입니다.
요소의 flat tree 자손(텍스트 노드 등 비요소 포함)이 위 조건을 만족해도 :hover와 매칭됩니다.
문서 언어는 :hover와 매칭되는 추가 방법을 정의할 수 있습니다. 예를 들어, [HTML5]는 라벨 요소가 호버된 경우 해당 라벨이 연결된 컨트롤이 :hover와 매칭되도록 정의합니다.
참고: :hover 상태는 자식이 포인터로 지정되어도 상위 요소에 적용될 수 있으므로, :hover가 포인터 아래에 있지 않은 요소에도 적용될 수 있습니다.
:hover 의사 클래스는 모든 의사 요소에도 적용될 수 있습니다.
9.2. 활성화 의사 클래스: :active
:active 의사 클래스는 요소가 사용자가 활성화 중일 때 적용됩니다. 예를 들어, 마우스 버튼을 눌렀다가 뗄 때까지의 사이입니다. 마우스 버튼이 여러 개 있을 때 :active는 주(기본) 액티베이션 버튼(보통 "왼쪽" 버튼) 및 그 별칭에만 적용됩니다.
어떤 요소가 :active가 될 수 있는지는 문서 언어나 구현에 따라 제한될 수 있습니다. 예를 들어 [HTML5]는 활성화 가능한 요소 목록을 정의합니다.
요소의 flat tree 자손(텍스트 노드 등 비요소 포함)이 위 조건을 만족해도 :active와 매칭됩니다.
문서 언어는 :active와 매칭되는 추가 방법을 정의할 수 있습니다.
참고: 요소는 :visited와 :active (혹은 :link와 :active)를 동시에 가질 수 있습니다.
9.3. 입력 포커스 의사 클래스: :focus
:focus 의사 클래스는 요소가 포커스를 가지고 있을 때(키보드, 마우스 이벤트 또는 기타 입력을 받는 상태) 적용됩니다.
어떤 요소가 :focus를 받을 수 있는지는 문서 언어나 구현에 따라 제한될 수 있습니다. 예를 들어 [HTML]은 포커스 가능한 영역 목록을 정의합니다.
문서 언어는 :focus와 매칭되는
추가 방법을 정의할 수 있지만,
:focus 의사 클래스는 부모 요소로 자동 전파되면 안 됩니다—
폼 컨트롤의 :focus 상태를 연결된
label
요소에도 전파하길 원하는 의견이 있음;
주된 반대 이유는 구현 난이도.
CSSWG 이슈(CSS) 및 WHATWG 이슈(HTML) 참고.
9.4. 포커스 표시 의사 클래스: :focus-visible
:focus 의사 클래스는 항상 현재 포커스된 요소에 매칭되지만, UA는 포커스가 표시될 때만 포커스 표시를(예: "포커스 링" 그리기) 시각적으로 제공하며, 다양한 휴리스틱을 사용해 사용자가 필요할 때만 포커스 표시를 보여줍니다. :focus-visible 의사 클래스는 이런 경우에만 포커스된 요소에 매칭되며, 작성자가 포커스 표시가 언제 나타날지 변경하지 않고 포커스 표시의 스타일만 바꿀 수 있게 해줍니다.
:root{ --focus-gold : #ffbf47; } :focus-visible{ outline : 3 px solidvar ( --focus-gold); } a:focus-visible{ background-color : var ( --focus-gold); }
-
사용자가 항상 포커스 표시를 보기를 원하는 경우(시스템/브라우저 설정 등), 포커스 표시를 다른 조건과 관계 없이 항상 표시합니다. (UA가 자체 포커스 표시를 스타일 무시하고 보여주는 것도 옵션입니다.)
-
키보드 입력을 지원하는 요소(예:
input
등, 물리 키보드가 없을 때 포커스 시 가상 키보드를 띄우는 요소 등)는 포커스 표시를 합니다. -
사용자가 키보드 등 포인터가 아닌 장치로 페이지와 상호작용할 경우 포커스 표시를 합니다. (즉, 키보드 사용 여부에 따라 이 의사 클래스 매칭 유무가 바뀔 수 있습니다.)
-
포인터 장치(마우스/터치 등)로 상호작용하고, 포커스 요소가 키보드 입력을 지원하지 않으면 포커스 표시를 하지 않습니다.
-
이전에 포커스된 요소가 포커스 표시를 했다면, 스크립트로 포커스가 이동했을 때 새 포커스 요소도 포커스 표시를 해야 합니다.
반대로 이전 포커스 요소가 포커스 표시를 하지 않았다면, 스크립트로 포커스가 이동해도 새 포커스 요소는 포커스 표시를 하지 않아야 합니다.
UA는 또한 :focus-visible을 기본 포커스 스타일에 사용해야 하며, 작성자가 :focus-visible을 사용할 때 기본 :focus 스타일을 별도로 비활성화할 필요가 없게 해야 합니다.
9.5. 포커스 컨테이너 의사 클래스: :focus-within
:focus-within 의사 클래스는 :focus 의사 클래스가 적용되는 요소, 그리고 flat tree의 자손(텍스트 노드 등 비요소 포함)이 :focus 조건을 만족하는 요소에도 적용됩니다.
10. 시간 차원 의사 클래스
이 의사 클래스들은 문서의 음성 렌더링, WebVTT로 자막을 표시하는 비디오 등에서 현재 표시되거나 활성 위치(타임라인)의 요소를 분류합니다.
CSS는 이 타임라인을 정의하지 않습니다; 호스트 언어에서 정의해야 합니다. 요소에 대해 타임라인이 정의되어 있지 않으면, 이 의사 클래스들은 그 요소와 매칭되지 않아야 합니다.
참고: :current 요소의 조상도 :current이지만, :past 또는 :future 요소의 조상은 반드시 :past 또는 :future 인 것은 아닙니다. 하나의 요소는 :current, :past, :future 중 하나에만 매칭됩니다.
10.1. 현재 요소 의사 클래스: :current
:current 의사 클래스는 현재 표시 중인 요소 또는 그 조상 요소를 나타냅니다.
대체형 :current()는 :is()처럼, 복합 셀렉터 리스트를 인자로 받습니다: 인자와 매칭되는 :current 요소를 나타내며, 그렇지 않으면 인자와 매칭되는 :current 요소의 가장 안쪽 조상 요소를 나타냅니다. (만약 :current 요소와 그 조상 모두 인자와 매칭되지 않으면, 아무것도 나타내지 않습니다.)
10.2. 과거 요소 의사 클래스: :past
:past 의사 클래스는 :current 요소보다 완전히 이전에 발생하는 것으로 정의된 모든 요소를 나타냅니다. 예를 들어, WebVTT 명세는 :past 의사 클래스를 미디어 요소의 현재 재생 위치에 따라 정의합니다. 문서 언어에서 시간 기반 요소 순서가 정의되지 않은 경우, 이는 :current 요소의 (간접) 이전 형제 요소를 나타냅니다.
10.3. 미래 요소 의사 클래스: :future
:future 의사 클래스는 :current 요소보다 완전히 이후에 발생하는 것으로 정의된 모든 요소를 나타냅니다. 예를 들어, WebVTT 명세는 :future 의사 클래스를 미디어 요소의 현재 재생 위치에 따라 정의합니다. 문서 언어에서 시간 기반 요소 순서가 정의되지 않은 경우, 이는 :current 요소의 (간접) 다음 형제 요소를 나타냅니다.
11. 리소스 상태 의사 클래스
이 섹션의 의사 클래스들은 주로 이미지/비디오 등 로드된 리소스를 나타내는 요소에 적용되며, 해당 상태의 특성에 따라 선택할 수 있게 해줍니다.
11.1. 미디어 재생 상태: :playing, :paused, :seeking 의사 클래스
:playing 의사 클래스는 "재생" 또는 "일시정지"가 가능한 요소 중 실제로 "재생" 중인 요소를 나타냅니다. (여기에는 명시적으로 재생 중인 경우뿐 아니라, 사용자의 의도와 무관하게 일시적으로 정지되어 있지만 곧 자동 재개되는 상태(예: "버퍼링" 또는 "중단")도 포함됩니다.)
:paused 의사 클래스는 "재생" 또는 "일시정지"가 가능한 요소 중 "일시정지" 상태(즉 재생 중 아님)인 요소를 나타냅니다. (명시적 "일시정지" 상태뿐 아니라 "로드됨, 아직 활성화되지 않음" 등 다른 비재생 상태도 포함됩니다.)
:seeking
의사 클래스는 "탐색(seeking)"이 가능한 요소 중
실제로 "탐색" 중인 요소를 나타냅니다.
(HTML의
audio
및
video
요소의 경우, HTML
§ 4.8.11.9 Seeking 참고.)
11.2. 미디어 로딩 상태: :buffering, :stalled 의사 클래스
:buffering 의사 클래스는 "재생" 또는 "일시정지"가 가능한 요소 중 미디어 데이터를 얻으려고 시도하고 있지만 아직 충분한 데이터를 얻지 못해 재생을 계속할 수 없는 경우를 나타냅니다. (이때도 "버퍼링" 중인 요소는 "재생" 중인 것으로 간주합니다. :buffering에 매칭되는 요소는 :playing에도 매칭됩니다.)
:stalled
의사 클래스는 미디어 데이터를 얻으려고 시도하고 있지만 일정 시간 동안 데이터를 전혀 받지 못해 재생을 계속할 수 없는 요소를 나타냅니다.
HTML의
audio
및
video
요소에서는 이 시간이 미디어 요소 중단 타임아웃입니다. [HTML]
(:buffering 의사 클래스와 마찬가지로,
"중단" 상태의 요소도 "재생" 중인 것으로 간주합니다.
:stalled에 매칭되는 요소는 :playing에도 매칭됩니다.)
11.3. 사운드 상태: :muted, :volume-locked 의사 클래스
:muted
의사 클래스는 소리를 낼 수 있는 요소 중
"음소거"(강제 무음) 상태인 요소를 나타냅니다.
(HTML의
audio
및
video
요소의 경우, muted 참고. [HTML])
:volume-locked 의사 클래스는 소리를 낼 수 있는 요소 중 프로그래밍적으로 볼륨을 변경해도 요소의 실제 미디어 볼륨이 변하지 않는 상태인 요소를 나타냅니다.
12. 요소 표시 상태 의사 클래스
12.1. 접힘 상태: :open, :closed 의사 클래스
:open 의사 클래스는 "open"과 "closed" 두 상태를 가지는 요소 중 현재 "open" 상태인 요소를 나타냅니다.
:closed 의사 클래스는 "open"과 "closed" 두 상태를 가지는 요소 중 현재 "closed" 상태인 요소를 나타냅니다.
구체적으로 "open"과 "closed"가 무엇을 의미하는지는 호스트 언어에 따라 다르지만,
HTML의
details
,
select
,
dialog
요소 등에서,
"open"으로 토글하면 더 많은 콘텐츠가 표시되는(혹은
dialog
의
경우, 어떤 콘텐츠라도 표시됨) 경우가 이에 해당합니다.
참고: "open" 또는 "closed"는 의미적 상태입니다. 현재 화면에 표시되지 않는 요소(예: visibility: collapse, display: none 하위 트리 등)도 "open" 상태일 수 있으며, :open과 매칭됩니다.
12.2. 모달(단독 상호작용) 상태: :modal 의사 클래스
:modal 의사 클래스는 해당 요소가 닫히기 전까지 외부 요소와의 모든 상호작용을 배제하는 상태를 나타냅니다. 여러 요소가 동시에 :modal이 될 수 있으며, 그 중 단 하나만 활성(입력 가능) 상태가 됩니다.
dialog
요소는 showModal()
API로 열렸을 때 :modal이 됩니다.
마찬가지로 :fullscreen 요소도 requestFullscreen()
API로 열렸을 때 :modal이 되며,
이때 페이지의 나머지 부분과 상호작용할 수 없습니다.
12.3. 전체 화면 표시 상태: :fullscreen 의사 클래스
:fullscreen 의사 클래스는 전체 화면 API 등으로 화면 대부분(보통 전체)을 차지하는 모드로 표시된 요소를 나타냅니다. [FULLSCREEN]
12.4. 화면 속 화면(Picture-in-Picture) 표시 상태: :picture-in-picture 의사 클래스
:picture-in-picture 의사 클래스는 화면의 일부에 제한적으로 표시되면서 다른 콘텐츠 위에 떠 있는 모드(화면 속 화면 API 등)로 표시된 요소를 나타냅니다. [picture-in-picture]
13. 입력 의사 클래스
이 섹션의 의사 클래스들은 주로 사용자 입력을 받는 요소(예: HTML의 input 요소)에 적용됩니다.
13.1. 입력 컨트롤 상태
13.1.1. :enabled 및 :disabled 의사 클래스
:enabled 의사 클래스는 활성 상태인 사용자 인터페이스 요소를 나타냅니다; 이러한 요소는 반드시 대응되는 비활성 상태를 가져야 합니다.
반대로 :disabled 의사 클래스는 비활성 상태인 사용자 인터페이스 요소를 나타냅니다; 이러한 요소는 반드시 대응되는 활성 상태를 가져야 합니다.
활성/비활성 상태, 사용자 인터페이스 요소의 기준은 호스트 언어에 따라 달라집니다. 일반적인 문서에서는 대부분의 요소가 :enabled 또는 :disabled 중 어느 것도 해당하지 않습니다. 예를 들어 [HTML5]에서는 비활성화되지 않은 인터랙티브 요소가 :enabled이고, 명시적으로 비활성화된 요소가 :disabled입니다.
참고: 사용자의 상호작용 가능성에 영향을 줄 수 있는 CSS 프로퍼티(예: display, visibility 등)는 요소가 :enabled 또는 :disabled와 매칭되는지에 영향을 주지 않습니다.
13.1.2. 변경 가능성 의사 클래스: :read-only, :read-write
요소가 문서 언어에 따라 사용자가 변경 가능하면 :read-write와 매칭됩니다. 그렇지 않으면 :read-only와 매칭됩니다.
예를 들어 [HTML5]에서 비활성화되지 않고
readonly가 아닌 <input>
요소는 :read-write에 해당하며,
contenteditable
속성이 true로 설정된 요소도 마찬가지입니다.
13.1.3. 플레이스홀더 표시 의사 클래스: :placeholder-shown
입력 요소는 사용자에게 입력 힌트로 플레이스홀더 텍스트를 표시할 수 있습니다.
예를 들어 [HTML5]의 placeholder
속성을 참고하세요.
:placeholder-shown 의사 클래스는
해당 플레이스홀더 텍스트를 표시중인 입력 요소에 매칭됩니다.
이 텍스트는 속성이나 실제 요소로 제공될 수도, UA에서 암시적으로 제공될 수도 있습니다.
placeholder
속성이 있는
input
요소나,
특정 조건에서
option
요소가 첫 번째로 오는
select
요소 등에서 플레이스홀더 텍스트가 제공됩니다.
:placeholder-shown 클래스는 이러한 플레이스홀더 텍스트가 실제로 표시될 때마다 적용됩니다.
13.1.4. 자동 입력 의사 클래스: :autofill
:autofill 의사 클래스는 UA에 의해 자동으로 채워지고, 이후 사용자가 직접 변경하지 않은 입력 요소를 나타냅니다.
13.1.5. 기본 옵션 의사 클래스: :default
:default 의사 클래스는 유사한 요소 집합 내에서 기본값인 하나 이상의 UI 요소에 적용됩니다. 주로 컨텍스트 메뉴 항목, 버튼, select 리스트/메뉴 등에 적용됩니다.
예시로 여러 버튼 중 기본 제출 버튼,
팝업 메뉴에서 기본 옵션 등이 있습니다.
select-many 그룹(예: 피자 토핑 선택)에서는 여러 요소가 :default와 매칭될 수 있습니다.
예를 들어 [HTML5]에서는 :default가 폼의 "기본 버튼",
<select>
의 최초 선택된 <option>
(들),
그 외 몇몇 요소에 해당합니다.
13.2. 입력 값 상태
13.2.1. 선택 옵션 의사 클래스: :checked
라디오/체크박스 요소는 사용자가 토글할 수 있습니다.
메뉴 항목도 사용자가 선택하면 "선택됨"이 됩니다.
이러한 요소가 "켜짐" 상태로 토글되면 :checked
의사 클래스가 적용됩니다.
예를 들어 [HTML5]에서는 체크된 체크박스, 라디오 버튼,
선택된 <option>
요소가 :checked와 매칭됩니다.
:checked 의사
클래스는 동적이며,
사용자 동작에 따라 변경될 수 있지만,
[HTML5]의 selected
, checked
속성
등과 같이 문서 내 의미 속성에 근거할 수도 있으므로,
모든 미디어에 적용됩니다.
13.2.2. 불확정 값 의사 클래스: :indeterminate
:indeterminate 의사 클래스는 값이 불확정 상태인 UI 요소에 적용됩니다. 예를 들어, 라디오/체크박스 요소는 체크됨/해제됨 상태로 토글될 수 있지만, 때때로 체크/해제 모두 아닌 불확정 상태가 있을 수 있습니다. 마찬가지로 진행률 미터도 완료율이 알려지지 않으면 불확정 상태가 될 수 있습니다. 예를 들어 [HTML5]는 체크박스가 :indeterminate와 매칭될 수 있도록 정의합니다.
:checked 의사 클래스와 마찬가지로, :indeterminate도 모든 미디어에 적용됩니다. 라디오 그룹에서 사전 선택된 항목이 없는 경우, 해당 컴포넌트들은 정적 표시에서도 :indeterminate 상태가 됩니다.
13.3. 입력 값 검증
13.3.1. 빈 값 의사 클래스: :blank
:blank 의사 클래스는 입력값이 빈 값(빈 문자열 또는 null 입력)인 사용자 입력 요소에 적용됩니다.
textarea
요소의 내용이 비어 있거나,
input
필드의 값이 비어 있을 때 등입니다.
여기서 고려하는 값은 제출 시의 값이며
(자세한 내용은 폼
컨트롤의 값 참고),
HTML에서는 해당 값이 반드시
value
속성값과 동일하지 않을 수 있습니다.
참고: 이 셀렉터는 위험군(at-risk)입니다.
13.3.2. 유효성 의사 클래스: :valid, :invalid
요소의 내용이나 값이 문서 언어에서 정의한 데이터 유효성 의미에 따라 각각 유효하거나 유효하지 않은 경우 :valid, :invalid가 적용됩니다. 데이터 유효성 의미가 없는 요소는 :valid 또는 :invalid에 해당하지 않습니다.
참고: 제약 조건이 없는 요소는 항상 :valid이지만,
데이터 유효성 의미 자체가 없는 요소는 :valid이나 :invalid 중 어느 것도 해당하지
않습니다.
예를 들어 HTML에서 <input type="text">
요소는 제약 조건이 없다면 항상 :valid이지만,
p 요소는 유효성 의미가 없으므로
항상 이 의사 클래스와 매칭되지 않습니다.
13.3.3. 범위 의사 클래스: :in-range, :out-of-range
:in-range, :out-of-range 의사 클래스는 범위 제한이 있는 요소에만 적용됩니다. 요소가 문서 언어에서 정의한 범위 제한 내에 값이 있으면 :in-range, 범위 밖이면 :out-of-range와 매칭됩니다. 범위 제한이 없거나 폼 컨트롤이 아닌 요소는 :in-range나 :out-of-range 중 어느 것도 해당하지 않습니다. 예: 1~10까지만 나타내는 슬라이더 컨트롤에서 값이 11이면 :out-of-range입니다. 팝업 메뉴에서 "A", "B", "C"만 선택 가능한데 값이 "E"면 :out-of-range입니다.
13.3.4. 선택 가능성 의사 클래스: :required, :optional
폼 요소가 값이 있어야 유효하게 제출될 수 있으면 :required, 값이 없어도 되면 :optional입니다. 폼 요소가 아닌 요소는 required/optional 모두 해당하지 않습니다.
13.3.5. 사용자 상호작용 의사 클래스: :user-valid, :user-invalid
:user-invalid 및 :user-valid 의사 클래스는 각각 잘못된 입력/올바른 입력이 있는 요소를 나타내지만, 반드시 사용자가 해당 요소와 충분히 상호작용한 이후에만 적용됩니다.
:user-invalid 의사 클래스는 :invalid, :out-of-range, 또는 blank이지만 :required 요소에 대해 사용자가 폼 제출을 시도한 후 다시 상호작용하기 전까지 매칭해야 합니다.
:user-valid 의사 클래스는 :valid 요소에 대해 사용자가 폼 제출을 시도한 후 다시 상호작용하기 전까지 매칭해야 합니다.
UA는 사용자에게 오류를 강조하는 것이 적절하다면 다른 시점에도 해당 요소에 매칭할 수 있습니다. 예를 들어, UA가 사용자가 입력 필드에 텍스트를 입력하고 다른 요소로 포커스를 옮겼을 때 :user-invalid가 :invalid 요소에 매칭되도록 하고, 사용자가 입력을 성공적으로 수정하면 매칭을 중단할 수 있습니다.
<form> <label> Volume: <input name='vol' type=number min=0 max=10 value=11> </label> ... </form>
:-moz-ui-invalid와 교차 검증 필요.
제안된 :dirty pseudo-class 평가 필요
이 의사 클래스(:invalid, :valid)가 form과 fieldset 요소에도 적용될 수 있음을 명확히 할 것.
14. 트리 구조 의사 클래스
셀렉터는 구조적 의사 클래스 개념을 도입하여 문서 트리에 존재하지만 다른 단순 셀렉터나 결합자로 표현할 수 없는 추가 정보를 기반으로 선택할 수 있게 합니다.
독립 텍스트 노드 및 기타 비요소 노드는 부모의 자식 리스트에서 요소의 위치를 계산할 때 카운트되지 않습니다. 부모의 자식 리스트에서 요소의 위치를 계산할 때 인덱스 번호는 1부터 시작합니다.
구조적 의사 클래스는 문서 트리의 요소에만 적용되며, 의사 요소에는 절대 매칭되지 않아야 합니다.
14.1. :root 의사 클래스
:root 의사 클래스는 문서의 루트 요소를 나타냅니다.
예를 들어 DOM 문서에서, :root 의사 클래스는 Document 객체의 루트 요소와 매칭됩니다. HTML에서는 html 요소가 이에 해당합니다 (스크립트로 문서가 변경되지 않은 경우).
14.2. :empty 의사 클래스
:empty 의사 클래스는 자식이 없는 요소(옵션으로 문서 공백 문자만 허용)를 나타냅니다. 문서 트리 관점에서, 요소 노드와 콘텐츠 노드(예: [DOM] 텍스트 노드, 엔티티 참조) 중 데이터 길이가 0보다 큰 것만 비어있는지 여부에 영향을 줍니다; 주석, 처리 명령, 기타 노드는 요소가 비어있는지 여부에 영향을 주지 않습니다.
p
요소를 올바르게 나타냅니다:
<p></p> <p> <p> </p> <p></p>
div:empty는 다음 조각의 <div>
요소를 올바르게 나타내지 않습니다:
<div>text</div> <div><p></p></div> <div> </div> <div><p>bla</p></div> <div>this is not <p>:empty</p></div>
참고: Selectors Level 2, 3에서는 :empty가 공백만 포함된 요소에는 매칭되지 않았습니다. 이는 HTML에서 공백이 대체로 축약되며 소스 코드 포매팅에 사용되고, 특히 종료 태그가 생략된 요소는 DOM 텍스트 콘텐츠에 공백이 포함될 수 있으므로, 작성자가 비어 있다고 인식하는 요소를 기대대로 선택할 수 있게 변경되었습니다.
14.3. 자식 인덱스 기반 의사 클래스
이 섹션의 의사 클래스들은 포함 형제 중 인덱스에 따라 요소를 선택합니다.
참고: Selectors 3에서는 부모의 자식 리스트에서 인덱스에 따라 선택한다고 설명했었습니다. (이 설명은 섹션 이름과 여러 의사 클래스 이름에 남아 있습니다.) 부모가 없는 요소, 비요소 부모를 배제할 이유가 없으므로, 요소의 형제 중 상대적 인덱스로 서술하도록 변경되었습니다.
14.3.1. :nth-child() 의사 클래스
:nth-child(An+B [of S]? ) 의사 클래스 표기법은 S 셀렉터 리스트(포함 형제 중 selector list에 매칭되는 요소)에서 An+B번째 요소를 나타냅니다. S는 <complex-selector-list>이며, forgiving selector list로 파싱됩니다. S가 생략되면 *|*이 기본값입니다.
An+B 표기법과 해석은 CSS Syntax 3 § 6 The An+B microsyntax에서 정의합니다; 0 이상의 정수 n에 대해 i = An + B인 인덱스에 해당합니다.
참고: 여기서 요소 리스트는 1부터 시작합니다;
즉, 부모의 첫 번째 자식은 인덱스 1을 가지며 :nth-child(2n+1)에 매칭됩니다.
n=0
일 때 값이 1이 되기 때문입니다.
예를 들어, 이 셀렉터는 테이블의 짝수 행을 선택하거나, 4개씩 반복해서 단락의 텍스트 색상을 변경하는데 쓸 수 있습니다.
:nth-child(even) /* 2번째, 4번째, 6번째 등 요소 :nth-child(10n-1) /* 9번째, 19번째, 29번째 등 요소 */ :nth-child(10n+9) /* 동일 */ :nth-child(10n+-1) /* 문법 오류, 무시됨 */
참고: :nth-child()의 특이성은 일반 의사 클래스 하나의 특이성 + S가 있으면 S 내 가장 특이성 높은 복잡 셀렉터의 특이성입니다. § 17 셀렉터 특이성 계산 참고. 즉 S:nth-child(An+B)와 :nth-child(An+B of S)는 특이성이 동일하지만, 동작은 다릅니다 (아래 예시 참고).
:nth-child(-n+3 of li.important)
셀렉터를 함수 바깥으로 옮기면 동작이 달라집니다:
li.important:nth-child(-n+3)
이 셀렉터는 단순히 첫 세 자식이 "important" 목록 항목일 때만 선택합니다.
보통 테이블 줄 무늬를 위해 아래와 같이 CSS를 씁니다:
tr { background: white; } tr:nth-child(even) { background: silver; }
하지만 일부 행이 숨겨지면 패턴이 깨져 인접 행 배경색이 같아질 수 있습니다. 예를 들어 HTML에서 행을 [hidden] 속성으로 숨겼다면, 아래 CSS는 숨겨진 행과 무관하게 줄 무늬를 유지합니다:
tr { background: white; } tr:nth-child(even of :not([hidden])) { background: silver; }
14.3.2. :nth-last-child() 의사 클래스
:nth-last-child(An+B [of S]? ) 의사 클래스 표기법은 S 셀렉터 리스트(포함 형제 중 selector list에 매칭되는 요소)에서 끝에서부터 An+B번째 요소를 나타냅니다. S는 <complex-selector-list>이며, forgiving selector list로 파싱됩니다. S가 생략되면 *|*이 기본값입니다.
참고: :nth-last-child() 의사 클래스의 특이성도 :nth-child()와 같이 일반 의사 클래스 + 셀렉터 인자 S의 특이성이 합산됩니다. § 17 셀렉터 특이성 계산 참고.
CSS Syntax 모듈 [CSS3SYN]에서 An+B 표기법을 정의합니다.
tr:nth-last-child(-n+2) /* HTML 테이블의 마지막 두 행 */ foo:nth-last-child(odd) /* 부모 요소에서 끝에서부터 홀수번째 foo 요소 모두 */
14.3.3. :first-child 의사 클래스
:first-child 의사 클래스는 포함 형제 중 첫 번째 요소를 나타냅니다. :nth-child(1)과 동일합니다.
div > p:first-child
이 셀렉터는 아래 조각의 div
안에 들어있는 p
에 적용됩니다:
<p> The last P before the note.</p> <div class="note"> <p> The first P inside the note.</p> </div>
아래 조각의 두 번째 p
에는 적용되지 않습니다:
<p> The last P before the note.</p> <div class="note"> <h2> Note </h2> <p> The first P inside the note.</p> </div>
다음 두 셀렉터는 보통 동등합니다:
* > a:first-child /* a가 아무 요소의 첫 자식일 때 */ a:first-child /* (a가 루트 요소가 아니면) 동일 */
14.3.4. :last-child 의사 클래스
:last-child 의사 클래스는 포함 형제 중 마지막 요소를 나타냅니다. :nth-last-child(1)과 동일합니다.
14.3.5. :only-child 의사 클래스
:only-child 의사 클래스는 형제가 없는 요소를 나타냅니다. :first-child:last-child 또는 :nth-child(1):nth-last-child(1)과 동일하지만 특이성은 더 낮습니다.
14.4. 타입별 자식 인덱스 의사 클래스
이 섹션의 의사 클래스들은 자식 인덱스 기반 의사 클래스와 유사하지만, 요소의 형제 리스트에서 같은 타입(태그명) 요소들 중 인덱스를 기준으로 동작합니다.
14.4.1. :nth-of-type() 의사 클래스
:nth-of-type(An+B) 의사 클래스 표기법은
해당 요소와 타입 및 네임스페이스가 같은 S 셀렉터에서 :nth-child(|An+B| of S)에 매칭되는
요소와 동일합니다.
예를 들어,
HTML
img
요소가 이 의사 클래스에 해당하는지 판단할 때,
S는 html|img입니다(적절한 html
네임스페이스가 선언되어 있다고 가정).
img:nth-of-type(2n+1) { float: right; } img:nth-of-type(2n) { float: left; }
참고: 요소 타입을 미리 안다면, 이 의사 클래스는 타입 셀렉터와 :nth-child()를 결합한 것과 동일합니다. 즉 img:nth-of-type(2)은 *:nth-child(2 of img)과 같습니다.
14.4.2. :nth-last-of-type() 의사 클래스
:nth-last-of-type(An+B) 의사 클래스 표기법은
해당 요소와 타입 및 네임스페이스가 같은 S 셀렉터에서 :nth-last-child(|An+B| of S)에
매칭되는 요소와 동일합니다.
예를 들어,
HTML
img
요소가 이 의사 클래스에 해당하는지 판단할 때,
S는 html|img입니다(적절한 html
네임스페이스가 선언되어 있다고 가정).
body
의 모든 h2
자식 중 첫 번째와 마지막을 뺀 나머지를 나타내려면 다음 셀렉터를 사용할 수 있습니다:
body > h2:nth-of-type(n+2):nth-last-of-type(n+2)
이 경우 :not()을 써도 되지만, 셀렉터 길이는 거의 같습니다:
body > h2:not(:first-of-type):not(:last-of-type)
14.4.3. :first-of-type 의사 클래스
:first-of-type 의사 클래스는 :nth-of-type(1)과 동일한 요소를 나타냅니다.
dl
내부에서
자식 중 첫 번째 dt
를 나타냅니다.
dl dt:first-of-type
아래 예시에서 첫 두 dt
에는 적용되지만, 세 번째에는 적용되지 않습니다:
<dl> <dt>gigogne</dt> <dd> <dl> <dt>fusée</dt> <dd>multistage rocket</dd> <dt>table</dt> <dd>nest of tables</dd> </dl> </dd> </dl>
14.4.4. :last-of-type 의사 클래스
:last-of-type 의사 클래스는 :nth-last-of-type(1)과 동일한 요소를 나타냅니다.
14.4.5. :only-of-type 의사 클래스
:only-of-type 의사 클래스는 :first-of-type:last-of-type과 동일한 요소를 나타냅니다.
15. 결합자
15.1. 자손 결합자 (
)
저자는 셀렉터를 통해 문서 트리 내에서 다른 요소의 자손인 요소를 묘사하고 싶을 때가 있습니다(예: "em 요소가 H1 요소 내부에 포함된 경우"). 자손 결합자는 이러한 관계를 표현합니다.
자손 결합자는 두 복합 셀렉터를 공백으로 분리한 것입니다.
A B 형태의 셀렉터는 B
요소가 어떤 상위 요소 A
의 임의 자손임을 나타냅니다.
h1 em
이 셀렉터는 em 요소가 h1 요소의 자손인 경우를 나타냅니다. 아래 조각에 대해 올바르고 유효하지만 부분적인 설명입니다:
<h1>This <span class="myclass">headline is <em>very</em> important</span></h1>
다음 셀렉터:
div * p
이는 p 요소가 div 요소의 손자 또는 그 이상의 자손인 경우를 나타냅니다. "*" 앞뒤의 공백은 범용 셀렉터의 일부가 아니며,
공백은 결합자로서 div
가 어떤 요소의 상위이고, 그 요소가 p
의 상위임을 의미합니다.
자손 결합자와 속성 셀렉터를 조합한 다음 셀렉터는 (1) href
속성이 있고, (2)
p
내부에 있으며, (3) div
내부에 있는 요소를 나타냅니다:
div p *[href]
15.2. 자식 결합자 (>
)
자식 결합자는 두 요소 사이의 자식 관계를 설명합니다. 자식 결합자는 "보다 큼" 기호(U+003E, >) 코드 포인트로 두 복합 셀렉터를 분리합니다.
body
의 자식일 때를 나타냅니다:
body > p
다음 예시는 자손 결합자와 자식 결합자를 조합한 것입니다.
div ol>li p
이 셀렉터는 p 요소가 li 요소의 자손이고, li 요소가 ol 요소의 자식이며, ol 요소가
div
의 자손임을 나타냅니다. ">" 결합자 주위의 공백은 생략될 수 있습니다.
요소의 첫 번째 자식을 선택하는 방법은 위 :first-child 의사 클래스 섹션을 참고하세요.
15.3.
인접 형제 결합자 (+
)
인접 형제 결합자는 "더하기" 기호(U+002B, +) 코드 포인트로 두 복합 셀렉터를 분리합니다. 두 복합 셀렉터가 나타내는 요소는 문서 트리에서 동일한 부모를 가지며, 첫 번째 복합 셀렉터가 나타내는 요소가 두 번째 요소 바로 앞에 위치합니다. 비요소 노드(예: 요소 사이의 텍스트)는 요소 간 인접성 판단에서 무시됩니다.
math + p
다음 셀렉터는 앞의 예와 유사하지만, 속성 셀렉터를 추가하여 h1 요소가 class="opener"
일 때만 인접한 h2
요소를
선택합니다:
h1.opener + h2
15.4.
일반 형제 결합자 (~
)
일반 형제 결합자는 "틸드"(U+007E, ~) 코드 포인트로 두 복합 셀렉터를 분리합니다. 두 복합 셀렉터가 나타내는 요소는 문서 트리에서 동일한 부모를 가지며, 첫 번째 복합 셀렉터가 나타내는 요소가 두 번째 요소보다 앞에 위치하면(바로 앞이 아니어도 됨) 매칭됩니다.
h1 ~ pre
이는 pre 요소가 h1
뒤에 올 때를 나타냅니다. 아래 조각에 대해 올바르고 유효하지만 부분적
설명입니다:
<h1>Definition of the function a</h1> <p>Function a(x) has to be applied to all figures in the table.</p> <pre>function a(x) = 12x/13.5</pre>
16. 그리드 구조 셀렉터
2차원 그리드에서 셀의 행과 열 이중 연관은 계층적 마크업 언어에서 부모-자식 관계로 모두 표현할 수 없습니다. 둘 중 하나만 계층적으로 표현할 수 있으며, 나머지는 문서 언어 의미에서 명시적/암시적으로 정의되어야 합니다. HTML과 DocBook 두 가지 대표적인 계층적 마크업 언어에서는 행 중심(row-primary)으로 마크업이 구성되어 행 연관이 계층적으로 표현되고, 열 연관은 암시적으로 처리됩니다. 이런 암시적인 열 기반 관계를 표현할 수 있도록 열 결합자와 :nth-col(), :nth-last-col() 의사 클래스가 정의되어 있습니다. 열 중심(column-primary) 포맷에서는 이 의사 클래스들이 행 연관에 대해 매칭됩니다.
16.1. 열 결합자 (||
)
열 결합자는 파이프 두 개(||)로 구성되며, 열 요소와 그 열에 속한 셀 요소의 관계를 나타냅니다. 열 소속 여부는 오직 문서 언어의 의미에 따라 결정됩니다: 요소가 어떻게 표시되는지는 고려되지 않습니다. 셀 요소가 둘 이상의 열에 속하면, 해당 열 중 어느 하나에 속함을 나타내는 셀렉터로 표현됩니다.
col.selected || td { background: gray; color: white; font-weight: bold; }
<table> <col span="2"> <col class="selected"> <tr><td>A <td>B <td>C <tr><td colspan="2">D <td>E <tr><td>F <td colspan="2">G </table>
16.2. :nth-col() 의사 클래스
:nth-col(An+B) 의사 클래스 표기법은 셀 요소가 속한 열이 An+B-1개의 열을
앞에 두고 있을 때 매칭됩니다. n
이 0 이상인 경우에 해당합니다. 열 소속 여부는 오직 문서 언어의 의미에 따라 결정됩니다. 셀 요소가 둘
이상의 열에 속한다면, 해당 열 중 어느 하나와의 소속을 나타내는 셀렉터로 표현됩니다.
CSS Syntax 모듈 [CSS3SYN]에서 An+B 표기법을 정의합니다.
16.3. :nth-last-col() 의사 클래스
:nth-last-col(An+B) 의사 클래스 표기법은 셀 요소가 속한 열이
An+B-1개의 열을 뒤에 두고 있을 때 매칭됩니다. n
이 0 이상인 경우에 해당합니다. 열 소속 여부는 오직 문서
언어의 의미에 따라 결정됩니다. 셀 요소가 둘 이상의 열에 속한다면, 해당 열 중 어느 하나와의 소속을 나타내는 셀렉터로 표현됩니다.
CSS Syntax 모듈 [CSS3SYN]에서 An+B 표기법을 정의합니다.
17. 셀렉터의 특이성 계산
셀렉터의 특이성은 해당 요소에 대해 다음과 같이 계산합니다:
- 셀렉터 내 ID 셀렉터 개수 세기 (= A)
- 셀렉터 내 클래스 셀렉터, 속성 셀렉터, 의사 클래스 개수 세기 (= B)
- 셀렉터 내 타입 셀렉터와 의사 요소 개수 세기 (= C)
- 범용 셀렉터는 무시
셀렉터가 셀렉터 리스트라면, 각 셀렉터마다 위 수치를 계산합니다. 리스트에서 매칭 프로세스가 수행될 때, 적용되는 특이성은 매칭된 셀렉터 중 가장 높은 특이성입니다.
일부 의사 클래스는 다른 셀렉터에 대해 "평가 컨텍스트"를 제공하므로, 특이성이 별도로 정의됩니다:
- :is(), :not(), :has() 의사 클래스의 특이성은 인자 셀렉터 리스트 중 가장 높은 복합 셀렉터의 특이성으로 대체됩니다.
- 마찬가지로, :nth-child() 또는 :nth-last-child() 셀렉터의 특이성은 해당 의사 클래스 자체(의사 클래스 하나로 카운트) + 인자 셀렉터 리스트 중 가장 높은 복합 셀렉터의 특이성입니다.
- :where() 의사 클래스의 특이성은 0으로 대체됩니다.
- :is(em, #foo)의 특이성은 (1,0,0) — #foo ID 셀렉터와 동일 —
<em>
,<p id=foo>
,<em id=foo>
중 어떤 것과 매칭되어도 마찬가지. - .qux:where(em, #foo#bar#baz)의 특이성은 (0,1,0): :where() 내부는 특이성에 영향을 주지 않고 바깥의 .qux만 특이성에 기여.
- :nth-child(even of li, .item)의 특이성은 (0,2,0) — 클래스 셀렉터(.item) + 의사 클래스 1개 —
<li>
,<ul class=item>
,<li class=item id=foo>
중 어떤 것과 매칭되어도 마찬가지. - :not(em, strong#foo)의 특이성은 (1,0,1) — 태그 셀렉터(strong) + ID 셀렉터(#foo) — 어떤 요소와 매칭되어도 마찬가지.
특이성 비교는 세 구성요소를 순서대로 비교합니다: A 값이 더 크면 더 특이적; A가 같으면 B 값이 더 크면 더 특이적; B도 같으면 C 값이 더 크면 더 특이적; 모두 같으면 두 특이성은 동등합니다.
저장 한계로 인해 구현에는 A, B, C 값의 크기에 제한이 있을 수 있습니다. 이런 경우 제한값을 초과하면 그 한계에 고정(clamp)하고 오버플로우하지 않아야 합니다.
* /* a=0 b=0 c=0 */ LI /* a=0 b=0 c=1 */ UL LI /* a=0 b=0 c=2 */ UL OL+LI /* a=0 b=0 c=3 */ H1 + *[REL=up] /* a=0 b=1 c=1 */ UL OL LI.red /* a=0 b=1 c=3 */ LI.red.level /* a=0 b=2 c=1 */ #x34y /* a=1 b=0 c=0 */ #s12:not(FOO) /* a=1 b=0 c=1 */ .foo :is(.bar, #baz) /* a=1 b=1 c=0 */
참고: 동일한 단순 셀렉터가 반복되어 등장해도 특이성이 증가합니다.
참고: HTML style
속성에서 지정된 스타일의 특이성은 CSS Style Attributes에서 설명합니다. [CSSSTYLEATTR]
18. 문법
셀렉터는 다음 문법에 따라 파싱됩니다:
<selector-list> = <complex-selector-list> <complex-selector-list> = <complex-selector># <compound-selector-list> = <compound-selector># <simple-selector-list> = <simple-selector># <relative-selector-list> = <relative-selector># <complex-selector> = <compound-selector> [ <combinator>? <compound-selector> ]* <relative-selector> = <combinator>? <complex-selector> <compound-selector> = [ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]! <simple-selector> = <type-selector> | <subclass-selector> <combinator> = '>' | '+' | '~' | [ '|' '|' ] <type-selector> = <wq-name> | <ns-prefix>? '*' <ns-prefix> = [ <ident-token> | '*' ]? '|' <wq-name> = <ns-prefix>? <ident-token> <subclass-selector> = <id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector> <id-selector> = <hash-token> <class-selector> = '.' <ident-token> <attribute-selector> = '[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']' <attr-matcher> = [ '~' | '|' | '^' | '$' | '*' ]? '=' <attr-modifier> = i | s <pseudo-class-selector> = ':' <ident-token> | ':' <function-token> <any-value> ')' <pseudo-element-selector> = ':' <pseudo-class-selector>
위 문법을 해석할 때는 다음 규칙을 적용합니다:
-
공백은 허용되지 않음:
-
<compound-selector>의 최상위 컴포넌트 사이(즉, <type-selector>와 <subclass-selector> 사이, 또는 <subclass-selector>와 <pseudo-element-selector> 사이 등)에는 공백 금지.
-
<type-selector> 또는 <class-selector>의 모든 컴포넌트 사이에 공백 금지.
-
<pseudo-element-selector> 또는 <pseudo-class-selector>의 ':' 사이, 또는 ':'와 <ident-token> 또는 <function-token> 사이에 공백 금지.
-
<wq-name>의 모든 컴포넌트 사이에 공백 금지.
-
<attr-matcher>의 모든 컴포넌트 사이에 공백 금지.
-
<combinator>의 모든 컴포넌트 사이에 공백 금지.
공백은 두 <compound-selector> 사이에서, 그 사이의 <combinator>가 생략된 경우 반드시 필요합니다. (즉, 자손 결합자를 사용하는 경우임.)
-
- 네 개 Level 2 의사 요소(::before, ::after, ::first-line, ::first-letter) 는 호환성 이유로 <pseudo-class-selector> 문법으로 단일 ":"만 붙여 나타낼 수 있습니다.
- <id-selector>에서는 <hash-token> 값이 반드시 식별자여야 합니다.
참고: 셀렉터는 더 구체적인 구문 제약도 적용되므로, 위 문법을 준수하는 것만으로 충분 조건이 아닙니다. 셀렉터가 올바른지 판단하는 추가 규칙은 § 3.9 잘못된 셀렉터 및 오류 처리 참고.
참고: 일반적으로 <pseudo-element-selector>는 <complex-selector>의 마지막 <compound-selector> 끝에만 올 수 있습니다. 하지만 경우에 따라 <pseudo-element-selector> 또는 <pseudo-class-selector>가 더 올 수도 있습니다; 이는 각 케이스별로 명세에서 규정합니다. (예: 사용자 동작 의사 클래스는 어떤 의사 요소 뒤에도 허용되고, 트리 종속 의사 요소는 ::slotted() 뒤에도 허용됩니다.)
18.1. <forgiving-selector-list> 및 <forgiving-relative-selector-list>
호환성 이유로, 셀렉터 리스트 내 셀렉터 중 하나라도 파싱에 실패하면 (예: 새로운 셀렉터, UA 전용 기능 등), 전체 셀렉터 리스트가 잘못된 셀렉터가 됩니다. 이로 인해 새로운 셀렉터를 쓰면서도 구형 UA에서 제대로 동작하는 CSS를 작성하기 어렵습니다.
<forgiving-selector-list> 생산식(production)은 리스트 내 각 셀렉터를 개별적으로 파싱하며, 파싱에 실패한 셀렉터는 무시하고 남은 셀렉터만 사용할 수 있게 합니다.
참고: 스타일 규칙에서는 여전히 일반(비관용적) 셀렉터 리스트 동작을 사용합니다. <forgiving-selector-list>는 일부 함수(예: :is() 등)에서 사용됩니다. 약간의 특이성 변화가 있지만, 스타일 규칙 셀렉터를 :is()로 감싸면 관용적(forgiving)이 됩니다.
문법적으로 <forgiving-selector-list>는
<any-value>?
와
동등합니다.
이후 관용적 셀렉터 리스트로 파싱해 실제 값을 얻습니다.
-
목록을 구문 분석하여 <complex-selector>를 input에서 추출하고, selector list에 그 결과를 저장한다.
-
selector list에서 실패 항목을 모두 제거하고, 잘못된 선택자인 모든 항목도 제거한 후, 남은 항목을 나타내는 <selector-list>를 반환한다. (이 목록은 비어 있을 수 있다.)
<forgiving-relative-selector-list>는 <forgiving-selector-list>와 동일하지만, 구성 요소를 <complex-selector> 대신 <relative-selector>로 파싱합니다.
19. API 훅
셀렉터 개념을 사용하는 명세 작성을 돕기 위해, 이 섹션에서는 다른 명세에서 호출할 수 있는 여러 API 훅을 정의합니다.
match와 invalid selector의 정의가 엄밀해진 지금,
이것들이 여전히 필요한가요?
명사 개념이 서술적 명세에서 조율하기 더 쉽고,
querySelector
에서 반환되는 요소의 정확한 순서 같은 세부사항은 셀렉터 명세가 아니라 DOM 명세에서 정의하는 게 더 자연스러운 것 같습니다.
19.1. 셀렉터 파싱
이 섹션은 문자열 source에서 셀렉터를 파싱하는 방법을 정의합니다. 반환값은 복합 셀렉터 리스트 또는 실패입니다.
- selector를 CSS 문법에 따라 파싱하여 <selector-list>로 얻는다. 실패하면, 이는 잘못된 셀렉터이며; 실패 반환.
- selector가 그 밖의 이유(예: 선언되지 않은 네임스페이스 접두사 포함 등)로 잘못된 셀렉터라면, 실패 반환.
- 그 외의 경우, selector 반환.
19.2. 상대 셀렉터 파싱
이 섹션은 문자열 source에서 상대 셀렉터를 파싱하는 방법을 정의합니다. 반환값은 복합 셀렉터 리스트 또는 실패입니다.
- selector를 CSS 문법에 따라 파싱하여 <relative-selector-list>로 얻는다. 실패하면, 이는 잘못된 셀렉터이며; 실패 반환.
- selector가 그 밖의 이유(예: 선언되지 않은 네임스페이스 접두사 포함 등)로 잘못된 셀렉터라면, 실패 반환.
- 그 외의 경우, selector 반환.
19.3. 셀렉터를 요소에 매칭
이 섹션은 셀렉터를 요소에 매칭하는 방법을 정의합니다.
이 알고리즘을 사용하는 API는 selector와 element를 제공해야 합니다.
호출자는 선택적으로 다음을 제공할 수 있습니다:
이 알고리즘은 성공 또는 실패를 반환합니다.
주어진 selector(즉, 복합 셀렉터 리스트) 내 각 복합 셀렉터에 대해, 아래 단락에서 설명한 대로 복합 셀렉터를 element에 매칭합니다. 매칭 결과가 어느 복합 셀렉터에서라도 성공이면, 알고리즘은 성공을 반환; 그렇지 않으면 실패를 반환합니다.
복합 셀렉터를 요소에 매칭하는 방법은 오른쪽에서 왼쪽으로 한 번에 하나씩 복합 셀렉터를 처리하는 재귀적 과정으로 정의됩니다:
- 오른쪽 끝 복합 셀렉터 내 단순 셀렉터 중 하나라도 해당 요소와 매칭되지 않으면, 실패 반환.
- 그렇지 않고 복합 셀렉터가 하나만 있으면, 성공 반환.
- 그렇지 않으면, 오른쪽 끝 결합자로 해당 요소와 관련될 수 있는 모든 요소를 고려. 이때, 오른쪽 복합 셀렉터와 결합자를 제거한 셀렉터를 각 요소에 매칭해 성공이 나오면 성공 반환. 그렇지 않으면 실패 반환.
19.4. 셀렉터를 의사 요소에 매칭
이 섹션은 셀렉터를 의사 요소에 매칭하는 방법을 정의합니다.
이 알고리즘을 사용하는 API는 selector와 pseudo-element를 제공해야 하며, 셀렉터를 요소에 매칭하는 알고리즘에 제공 가능했던 것들도 선택적으로 제공할 수 있습니다.
이 알고리즘은 성공 또는 실패를 반환합니다.
주어진 selector 내 각 복합 셀렉터에 대해, 다음 조건이 모두 충족되면:
- 복합 셀렉터의 오른쪽 끝 단순 셀렉터가 pseudo-element와 매칭되고,
- 복합 셀렉터를 요소에 매칭을 해당 복합 셀렉터에서 오른쪽 끝 단순 셀렉터만 제거한 나머지 셀렉터, pseudo-element가 연결된 요소, 그리고 이 알고리즘에 제공된 선택적 인자들로 실행했을 때 성공 반환,
그 외(즉, selector의 어느 복합 셀렉터에도 위 조건이 성립하지 않으면), 실패 반환.
19.5. 셀렉터를 트리에 매칭
이 섹션은 셀렉터를 트리에 매칭하는 방법을 정의합니다.
이 알고리즘을 사용하는 API는 셀렉터와 하나 이상의 root elements(셀렉터로 탐색할 하위 트리 루트)를 제공해야 합니다. 모든 root elements는 동일한 루트를 공유해야 하며, 그렇지 않으면 이 알고리즘 호출은 무효입니다.
선택적으로 다음을 제공할 수 있습니다:
- 하나 이상의 스코프 루트: 셀렉터가 스코프됨을 나타냄.
-
매치 리스트에 포함될 수 있는 의사 요소
목록.
지정하지 않으면 모든 의사 요소 허용이 기본값.
실제로 트리 종속 의사 요소만 이런 방식으로 다뤄집니다.
이 알고리즘은 (빈일 수 있는) 요소 리스트를 반환합니다.
- candidate elements(후보 요소)를, root elements와 그 모든 하위 요소로 시작하며, shadow 포함 트리 순서로 정렬(별도 지정 없으면).
- 스코프 루트가 지정됐다면, candidate elements에서 모든 자손이 아닌 요소 제거.
- selector match list를 빈 리스트로 초기화.
-
candidate elements 내 각 element에 대해:
- 셀렉터를 요소에 매칭 결과가 성공이면, selector match list에 element 추가.
-
element에 연결된 가능한 의사 요소 중,
매치 리스트에 포함될 수 있는 의사 요소 각각에 대해,
셀렉터를 의사 요소에 매칭 결과가 성공이면,
해당 의사 요소를 selector match list에 추가.
매치 리스트 내 의사 요소의 상대적 위치는 정의되어 있지 않음. 아직 이런 정보가 노출되는 컨텍스트가 없지만, 언젠가 노출되기 전에 결정해야 함.
부록 A: 소스 문서 및 데이터의 요소 트리 맵핑 지침
이 섹션은 참고용입니다.
DOM이 설명하는 요소 트리 구조는 강력하고 유용하며, 트리 기반 데이터(적절한 해석이 있으면 그래프 기반 데이터까지) 기술 언어 대부분을 모델링할 만큼 범용적입니다.
HTML 같은 일부 언어는 리소스에서 DOM 객체를 생성하는 절차가 이미 잘 정의되어 있습니다. 주어진 언어가 그런 절차를 갖고 있지 않다면, 셀렉터를 해당 언어 문서에 적용하려면 반드시 이런 절차를 정의해야 합니다.
최소한, 문서 언어는 무엇이 DOM 개념의 "요소"에 맵핑되는지 정의해야 합니다.
노드 간 1:N 관계—트리 구조에서 부모/자식, 그래프 구조에서 요소/이웃—는 요소의 자식 노드로 표현되어야 합니다.
요소의 기타 특성은 DOM에서 같은 목적을 가진 기능과 유사하게 맵핑되어야 합니다:
- type
-
문서 언어의 요소에 "타입" 개념(서로 다른 그룹을 구분하는 기본 요소)이 있으면,
"type" 기능으로 맵핑해야 합니다.
이 "type"이 "기본" 이름과 이름 그룹화를 위한 "네임스페이스"로 나뉠 수 있으면, 후자는 "namespace" 기능에 맵핑하고, 그렇지 않으면 네임스페이스 없이 전체 이름을 "type" 기능에 맵핑합니다.
- id
-
요소의 어떤 특성이 문서 전체에서 고유 식별자로 동작한다면,
"id" 기능에 맵핑해야 합니다.
참고: HTML에서는 요소가 단일 ID만 가질 수 있지만, 이것이 일반적인 제한으로 받아들여져선 안 됩니다. 중요한 점은 각 ID가 하나의 요소와 연결되어야 한다는 것이며; 하나의 요소에 여러 ID가 있어도 유효할 수 있습니다.
- classes and attributes
- 요소의 식별에 유용하지만 문서 내에서 일반적으로 고유하지 않은 특성은 "class" 또는 "attribute" 기능에 맵핑해야 합니다. "라벨"(단일 문자열)과 유사하면 "class"로, "프로퍼티"(이름/값 쌍)와 유사하면 "attribute"로.
- pseudo-classes and pseudo-elements
-
어떤 요소가 의사 클래스에 매칭되거나 의사 요소를 가진다면,
반드시 명확하게 정의해야 합니다.
일부 의사 클래스는 *문법적*입니다, 예: :has(), :is() 등은 항상 동작해야 합니다. 어디든 명시해야 할 듯. 구조적 의사 클래스들은 자식 리스트가 순서가 있다면 항상 동작해야 함.
- JSON 문서의 "요소"는 각 배열, 객체, 불린, 문자열, 숫자, null입니다. 배열과 객체 요소는 그 내용을 자식으로 가집니다.
- 각 요소의 타입은 JS 타입 이름: "array", "object" 등.
- 객체의 자식은 키를 클래스로 가집니다.
- 배열의 자식은 :first-child, :nth-child() 등 의사 클래스와 매칭됩니다.
- 루트 객체는 :root에 매칭.
- 추가로 :val(), :contains() 의사 클래스도 정의되어, 특정 값 또는 특정 부분 문자열을 가진 불린/숫자/문자열 요소를 매칭할 수 있습니다.
이 구조 덕분에 셀렉터로 JSON 문서를 강력하고 간결하게 쿼리할 수 있습니다.
부록 B: 웹 호환을 위한
-webkit-
파싱 특이점(구현 필수)
이 부록은 규범적입니다.
웹 호환성 제약으로 인해, 웹 문서 파싱을 기대하는 UA는 다음 기능을 지원해야 합니다:
-
:-webkit-autofill은 레거시 셀렉터 별칭으로서 :autofill과 동일하게 처리되어야 합니다.
-
"-webkit-"로 시작하는(ASCII 대소문자 구분 없이 일치) 모든 의사 요소 이름은, 함수 표기가 아닌 경우, 파싱 시 유효한 것으로 처리되어야 합니다. (::-webkit-asdf는 파싱 시 유효하지만, ::-webkit-jkl()은 아님.) 별도 지원하지 않는 경우, 아무것도 매칭하지 않는 것으로 처리하며, 알 수 없는 -webkit- 의사 요소가 됩니다.
알 수 없는 -webkit- 의사 요소는 반드시 ASCII 소문자로 직렬화해야 합니다.
이 특이점의 의미는?
셀렉터는 오랫동안, 하나의 알 수 없거나 잘못된 셀렉터가 전체 셀렉터 리스트를 무효화하는 동작이 있었습니다 (실제로는 하나의 복합 셀렉터만 무효화해야 하지만). 작업 그룹에서 레거시 실수로 간주되지만, 너무 많은 스타일시트가 이 동작에 의존하고 있어 지금은 고칠 수 없습니다. 일부러든 아니든, 많은 스타일시트가 이 동작에 의존하고 있습니다.
이의 한 측면은 벤더 전용 셀렉터 사용이 해당 셀렉터를 인식하지 못하는 UA에서는 전체 셀렉터를 무효화하며, 전체 스타일 규칙도 사라지게 된다는 점입니다. 과거에는 일부러(특정 브라우저에서 스타일 규칙을 숨기기 위해) 사용되었고, 최근에는 의도치 않게 많이 쓰입니다. 예: 의사 요소 스타일링 시 vendor-specific pseudo-element와 함께 보통 요소도 스타일링할 때, 다른 브라우저에서는 전체 규칙이 무효화됨을 모르는 경우.
이런 일반적 이유 외에도, WebKit 계열 UA(사파리, 크롬 등)는 벤더 프리픽스 의사 요소 관련 추가 특이점이 있습니다. ::-webkit- 접두 셀렉터는 파싱 시 유효로 간주됩니다. (초기 CSS 기능의 잔재로 추정; 당시에는 모든 의사 요소를 파싱 시 유효로 간주하고, 저자가 직접 정의할 수 있게 할 계획이 있었음.)
다른 레거시 특이점([QUIRKS] 참고)과 마찬가지로, 이 벤더 특이점도 너무 광범위하게 사용되어 다른 UA까지 사이트가 깨질 정도가 되어, 실질적으로 모든 UA가 지원해야만 현재 웹을 제대로 렌더링할 수 있습니다. 이를 명세로 규정함으로써 모든 UA가 현대 웹페이지를 더 잘 렌더링할 수 있게 됩니다.
다만 이런 특이점에 의존하는 웹페이지는 CSSWG와 건전한 웹 개발자들에게 비난받을 것입니다.
20. 변경 사항
20.1. 2022년 5월 7일 워킹 드래프트 이후 변경 사항
2022년 5월 7일 워킹 드래프트 이후 주요 변경 사항:
-
의사 요소가 :has() 내에 올 수 없도록 명시(의사 요소 정의에서 명시적으로 허용된 경우만 가능). (이슈 7463)
-
::lang("") 및 언어 태그 없는 요소의 매칭 정의. (이슈 6915)
-
"scoped"와 "relative" 셀렉터 개념을 완전히 분리함. (이슈 6399)
-
"absolutize a selector"를 제거하고, 상대 셀렉터 매칭을 앵커링 요소 기준으로만 정의.
-
-
:nth-child()의 복합 셀렉터 제한을 되돌림. (이슈 3760)
-
:-webkit-autofill을 레거시 셀렉터 별칭으로 정의. (이슈 7474)
20.2. 2018년 11월 21일 워킹 드래프트 이후 변경 사항
2018년 11월 21일 워킹 드래프트 이후 주요 변경 사항:
- Selector 프로필 제거, :has()를 선택적 및 위험군(at-risk)으로 표시. (이슈 3925)
- § 3.6.4 Sub-pseudo-elements 추가, sub-pseudo-elements 및 관련 용어 정의.
- :defined 추가. (이슈 2258)
- :modal 추가. (이슈 6965)
- :fullscreen, :picture-in-picture 추가. (이슈 3796)
- :seeking, :buffering, :stalled 미디어 재생 상태 의사 클래스 추가. (이슈 3821)
- :muted, :volume-locked 사운드 상태 의사 클래스 추가. (이슈 3821, 이슈 3933)
- :autofill 추가. (이슈 5775)
- :user-valid 추가. (토론)
- :is(), :where(), :has(), :nth-child(), :nth-last-child()가 잘못된 셀렉터를 포함해도 자신은 무효화되지 않도록 정의. (이슈 3264)
- :nth-child(), :nth-last-child() 내 셀렉터를 복합 셀렉터로 한정(임시). (이슈 3760)
- 대소문자 구분 문자열 매칭을 [INFRA]에서 정의한 문자열 동일성으로 명확화.
- UA가 제공하는 플레이스홀더 텍스트도 :placeholder-shown을 트리거하도록 명확화.
- :focus-visible 정의를 명확히 다시 작성.
- 문법 섹션에서 공백 필요에 대한 안내를 규범 텍스트로 변경; <compound-selector> 사이에 <combinator> 토큰이 없으면 공백 필수.
20.3. 2018년 2월 2일 워킹 드래프트 이후 변경 사항
2018년 2월 2일 워킹 드래프트 이후 주요 변경 사항:
- 특이성 0 셀렉터 :where() 명명. (이슈 2143)
- :matches()를 :is()로 이름 변경. (이슈 3258)
- :empty를 공백 문자만 포함된 노드는 무시하도록 재정의. (이슈 1967)
- :blank를 빈 요소가 아닌 빈 사용자 입력값을 나타내도록 재정의. (이슈 1283)
- :is(), :has(), :nth-child() 특이성이 어떤 인자 셀렉터가 매칭되는지에 따라 달라지지 않도록 변경. (이슈 1027)
- :drop() 의사 클래스 삭제(HTML이 관련 기능 삭제함). (이슈 2257)
- 속성 셀렉터에 대소문자 구분 플래그
s
추가. (이슈 2101) - :focus-visible에 대한 추가 안내 추가.
- 부록 B: 웹 호환을 위한 -webkit- 파싱 특이점 추가, ::-webkit- 의사 요소 파싱 특이점 정의. (이슈 3051)
- 공백 허용 위치에 대한 문법 규칙 명확화. (§ 18 문법 참고)
20.4. 2013년 5월 2일 워킹 드래프트 이후 변경 사항
2013년 5월 2일 워킹 드래프트 이후 주요 변경 사항:
- :target-within, :focus-within, :focus-visible, :playing, :paused 의사 클래스 추가.
- 특이성 0 :matches()-유형 의사 클래스 추가(이름 미정).
- 주체 표시자(!) 기능을 :has()로 대체.
- :nth-match(), :nth-last-match() 셀렉터를 :nth-child(… of selector), :nth-last-child(… of selector)로 대체.
- :active-drop-target, :valid-drop-target, :invalid-drop-target을 :drop()으로 변경.
- 비어 있거나 공백만 포함된 셀렉터 초안 작성(토론 중, 오픈 이슈 참고).
- :user-error를 :user-invalid로 이름 변경. (토론)
- :nth-column()/:nth-last-column()을 :nth-col()/:nth-last-col()로 이름 변경(잠재적 ::column 의사 클래스와 혼동 방지).
- :local-link() 의사 클래스가 마지막 슬래시 무시하도록 변경.
:local-link()
의사 클래스의 함수형 표기 및 참조 결합자 삭제(관심 부족).- 셀렉터 문법을 CSS Value Definition Syntax로 재작성.
- 상대 셀렉터 정의를 스코프 셀렉터와 분리(둘은 별개 개념임).
- <An+B> 마이크로 문법 정의를 CSS Syntax로 이동.
-
신규 섹션 추가:
- § 3.2 데이터 모델
-
§ 19 API 훅
- 이전 버전은 셀렉터 평가 섹션을 정의했으나, 현재는 없음. 해당 섹션을 참조하던 명세는 셀렉터를 트리에 매칭 알고리즘을 참조해야 함.
- :matches(), :not() 내 결합자 제한 제거(토론).
- 셀렉터 리스트의 특이성 정의. (이유?)
- :lang() 값에 별표(*)가 포함된 경우 따옴표 사용 필수; CSS 식별자인 언어 코드만 따옴표 없이 사용 가능.
참고: 2018년 2월 1일 드래프트는 미완성 작업이 실수로 커밋됨; 2월 2일자에서 이를 되돌리고 일부 링크도 수정됨.
20.5. 2012년 8월 23일 워킹 드래프트 이후 변경 사항
2012년 8월 23일 워킹 드래프트 이후 주요 변경 사항:
- :placeholder-shown 의사 클래스 추가.
- :matches(), :not()의 일부 제한 해제.
- 빠르고 완전한 Selectors 프로필(이제 "live"와 "snapshot" 명칭)을 정의.
- 특이성 정의를 :matches()에 더 잘 대응하도록 개선.
- 문법 업데이트.
- <An+B> 표기법 정의 정리.
- scope-relative 셀렉터 정의, scope-constrained를 scope-filtered로 이름 변경(혼동 방지).
- :local-link() 의사 클래스가 마지막 슬래시 무시하도록 변경.
20.6. 2011년 9월 29일 워킹 드래프트 이후 변경 사항
2011년 9월 29일 워킹 드래프트 이후 주요 변경 사항:
- RFC 4647에 따른 언어 변이 처리 추가.
- 스코프 셀렉터 추가.
- :user-error (현재 :user-invalid) 추가.
- :valid-drop-target 추가.
- 열 결합자를 슬래시 두 개에서 파이프 두 개로 변경.
20.7. Level 3 이후 변경 사항
Level 3 이후 추가 사항:
- :not()이 셀렉터 리스트를 받을 수 있도록 확장.
- :is(), :where(), :has() 추가.
- :scope 추가.
- :any-link, :local-link 추가.
- 시간 차원 의사 클래스 추가.
- :target-within, :focus-within, :focus-visible 추가.
- :dir() 추가.
- :lang()이 와일드카드 매칭과 언어 코드 리스트를 받을 수 있도록 확장.
- :nth-child()이 셀렉터 리스트를 받을 수 있도록 확장.
- CSS Basic User Interface Module Level 3의 입력 셀렉터를 통합하고 :indeterminate를 다시 추가.
- :blank, :user-invalid 추가.
- 그리드 구조(열) 셀렉터 추가.
- 속성값 매칭 플래그(대소문자 구분/비구분) 추가.
21. 감사의 글
CSS 워킹 그룹은 수년간 이전 Selectors 명세에 기여해주신 모든 분들께 감사드립니다. 그 명세가 현재 명세의 토대가 되었습니다. 특히 Selectors Level 4에 구체적으로 기여해주신 다음 분들께 특별히 감사드립니다: L. David Baron, Andrew Fedoniouk, Daniel Glazman, Ian Hickson, Grey Hodge, Lachlan Hunt, Anne van Kesteren, Jason Cranford Teague, Lea Verou
22. 프라이버시 및 보안 고려 사항
이 명세는 다음과 같은 프라이버시 및 보안 고려 사항을 포함합니다: