탐색

문법

선택자

선택자 연결 방식, 관련 요소, 목록, 리터럴 인코딩, 명시도입니다.

이 페이지의 내용

선택자 접미사는 클래스의 선언을 적용할 요소나 의사 요소를 결정합니다. 전체 클래스를 가진 요소가 시작점입니다. 접미사는 그 요소를 검사하거나 관련 요소를 선택하거나 두 작업을 함께 할 수 있습니다.

이 페이지는 선택자 연결, 인코딩, 그룹화, 명시도를 정의합니다. 컴포넌트에 호버와 키보드 포커스 스타일을 추가하는 방법은 구문 튜토리얼을, 네이티브 일치 동작은 CSS 선택자를 참고하세요.

선택자 연결

등록된 유틸리티나 네이티브 선언의 닫는 괄호 뒤에 선택자를 붙입니다. 조건은 선택자 뒤에, 중요도는 맨 끝에 둡니다.

utility<selector><conditions>!(property:value)<selector><conditions>!

위의 꺾쇠괄호 부분과 !는 생략 가능한 구문 자리표시자입니다. 예를 들어 underline:hover@sm은 클래스를 가진 요소가 호버 상태이고 뷰포트가 @sm에 일치할 때 밑줄을 적용합니다. 조건은 선택자의 대상 요소를 바꾸지 않습니다.

생성된 CSS
@layer utilities {  @media (width >= 52.125rem) {    .underline\:hover\@sm:hover {      text-decoration-line: underline    }  }  @media (width >= 52.125rem) {    .\(text-decoration-thickness\:2px\)\:hover\@sm:hover {      text-decoration-thickness: 2px    }  }}

Master CSS는 생성 CSS 선택자에서 전체 클래스 이름을 이스케이프합니다. .underline\:hover 안의 콜론은 리터럴 클래스 이름의 일부이고 뒤에 붙는 :hover가 실제 의사 클래스입니다. HTML에는 예제처럼 이스케이프하지 않은 클래스를 쓰세요.

클래스를 가진 요소 일치

결합자가 없으면 접미사는 클래스를 가진 요소에 요구 조건을 추가합니다. underline.active는 클래스 목록에 underline.active와 active가 모두 있는 요소에만 일치합니다.

<a class="underline.active active" href="/guide/installation">Installation</a>
클래스클래스를 가진 요소의 요구 조건
underline.activeactive 클래스도 있음
underline#currentID가 current
underline[data-current]data-current 속성이 있음
underline:hover브라우저의 호버 상태에 일치
underline:is(a)a 요소임
생성된 CSS
@layer utilities {  .underline\#current#current {    text-decoration-line: underline  }  .underline\:is\(a\):is(a) {    text-decoration-line: underline  }  .underline\[data-current\][data-current] {    text-decoration-line: underline  }  .underline\:hover:hover {    text-decoration-line: underline  }  .underline\.active.active {    text-decoration-line: underline  }}

같은 요소의 타입을 검사하려면 :is(a)나 :where(a)를 사용하세요. 자식 요소를 선택하려면 >a나 >*를 사용합니다. 유틸리티 이름 바로 뒤의 단독 태그 이름은 별도의 선택자 접미사가 아닙니다.

요구 조건 조합

인접한 단순 선택자는 같은 요소를 설명합니다. underline:hover:not([aria-disabled=true])는 호버를 요구하고 aria-disabled 속성이 true인 요소를 제외합니다. 이 속성을 설정하거나 갱신하지는 않습니다.

생성된 CSS
@layer utilities {  .underline\:hover\:not\(\[aria-disabled\=true\]\):hover:not([aria-disabled=true]) {    text-decoration-line: underline  }}

선택자는 DOM과 브라우저 상태에 반응하며 상호작용 동작을 만들지는 않습니다. 네이티브 속성과 ARIA는 각자의 의미를 유지합니다. 특히 aria-disabled="true"는 비활성 상태를 설명할 뿐 자체적으로 활성화 동작을 막지 않습니다.

관련 요소

결합자는 클래스를 가진 요소에서 다른 요소로 이동합니다. 선언은 선택자 끝의 요소에 적용되며 클래스를 가진 요소에서 상속되는 것이 아닙니다.

클래스대상
underline_a깊이에 관계없는 하위 링크
underline>a직계 자식 링크
underline+a다음 형제 요소가 링크인 경우 그 요소
underline~a같은 부모를 가진 뒤쪽의 모든 형제 링크
underline>*모든 직계 자식 요소

_는 선택자 사이의 하위 요소 공백을 인코딩합니다. HTML에 실제 공백을 쓰면 다른 클래스가 시작됩니다. >, +, ~는 네이티브 CSS 의미를 유지합니다.

생성된 CSS
@layer utilities {  .underline\+a + a {    text-decoration-line: underline  }  .underline\>\* > * {    text-decoration-line: underline  }  .underline\>a > a {    text-decoration-line: underline  }  .underline_a a {    text-decoration-line: underline  }  .underline\~a ~ a {    text-decoration-line: underline  }}

자식 선택자는 첫 번째 단계까지만

두 트리는 구조가 같습니다. 밑줄은 실제 대상 링크를, 들여쓰기와 연결 가지는 깊이를 나타냅니다.

텍스트 설명
  1. 클래스를 가진 article은 링크 A와 링크 B를 포함하는 section을 가집니다.
  2. underline>a는 직계 자식 링크 A에만 밑줄을 적용합니다. underline_a는 A와 B가 모두 하위 링크이므로 둘 다 적용합니다.
  3. 선언은 해당 링크를 직접 대상으로 합니다. 이 그림은 article에서 텍스트 장식을 상속하는 모습을 나타내지 않습니다.

형제 선택자는 소유 요소 뒤를 선택

각 행의 모든 노드는 같은 부모를 가집니다. 윤곽선으로 표시한 소유 요소가 클래스를 가지며 밑줄은 선택된 링크를 나타냅니다.

텍스트 설명
  1. 형제 순서는 링크 A, 클래스를 가진 요소, 링크 B, 링크 C입니다.
  2. underline+a는 다음 형제 요소 B를 선택합니다. underline~a는 뒤쪽 형제 링크 B와 C를 선택합니다.
  3. 두 선택자 모두 앞선 형제 A를 선택하지 않습니다. 다음 요소가 링크가 아니면 +a는 아무것도 선택하지 않습니다.

상태의 위치

상태의 위치는 어떤 요소가 그 상태에 일치해야 하는지 결정합니다. 다음 두 클래스는 같은 부모와 자식 관계를 가지지만 서로 다른 위치에서 호버를 검사합니다.

article의 클래스호버 요구 조건밑줄을 적용할 링크
underline:hover>aarticle이 호버 상태모든 직계 자식 링크
underline>a:hover직계 자식 링크가 호버 상태해당 링크만

같은 호버, 다른 대상

두 예시 모두 첫 번째 링크가 호버 상태입니다. 파란 점선 윤곽은 접미사의 :hover 검사에 일치하는 요소이며 생성된 테두리가 아닙니다.

텍스트 설명
  1. 두 article은 유틸리티 클래스를 가지며 같은 두 직계 자식 링크를 포함합니다. 첫 번째 링크가 호버 상태이므로 조상 article도 둘 다 :hover에 일치합니다.
  2. underline:hover>a는 article을 검사한 뒤 직계 자식 링크를 선택합니다. 두 링크 모두 text-decoration-line: underline을 받습니다.
  3. underline>a:hover는 직계 자식 링크를 선택한 뒤 각 링크를 검사합니다. 호버된 첫 번째 링크만 선언을 받습니다.
  4. 파란 점선 윤곽은 호버 검사에 일치하는 요소를 나타냅니다. 생성된 테두리가 아니며 두 번째 article이 호버 상태가 아니라는 뜻도 아닙니다.
<article class="underline:hover>a">  <p>Documentation</p>  <a class="(text-decoration-line:none)" href="/guide/installation">Installation and setup</a>  <a class="(text-decoration-line:none)" href="/reference/packages">API reference</a></article><article class="underline>a:hover">  <p>Documentation</p>  <a class="(text-decoration-line:none)" href="/guide/installation">Installation and setup</a>  <a class="(text-decoration-line:none)" href="/reference/packages">API reference</a></article>
생성된 CSS
@layer utilities {  .\(text-decoration-line\:none\) {    text-decoration-line: none  }  .underline\:hover\>a:hover > a {    text-decoration-line: underline  }  .underline\>a\:hover > a:hover {    text-decoration-line: underline  }}

링크를 호버하면 조상 article도 호버 상태가 됩니다. 첫 번째 예제에서는 두 링크가 모두 조건을 충족하지만 두 번째에서는 다른 링크가 자신의 :hover 검사에 여전히 일치하지 않습니다. 클래스는 각각 article이 가지지만 선언은 링크를 대상으로 합니다. 링크의 클래스가 기본 밑줄을 제거하고 명시도가 높은 부모와 자식 선택자가 호버 조건에 일치할 때 밑줄을 복원합니다.

선택자 목록

최상위 쉼표는 같은 클래스 소유 요소에서 다른 분기를 시작합니다. 각 분기에서 결합자를 반복하세요. block>div,>span은 직계 div 자식과 직계 span 자식을 선택합니다. 두 번째 분기는 첫 번째 분기의 대상에서 이어지지 않습니다.

<section class="block>div,>span">  <div>First child</div>  <span>Second child</span></section>
생성된 CSS
@layer utilities {  .block\>div\,\>span > div,  .block\>div\,\>span > span {    display: block  }  .\(content\:\'“\'\)\:\:before\,\:\:after::before,  .\(content\:\'“\'\)\:\:before\,\:\:after::after {    content: '“'  }}

함수나 따옴표로 감싼 속성 값의 쉼표는 해당 구조 안에 남습니다. underline:is(:hover,:focus-visible)는 두 대안을 가진 하나의 선택자 접미사이며 최상위 분기 두 개가 아닙니다.

생성된 CSS
@layer utilities {  .underline\[data-label\=\'draft\,review\'\][data-label='draft,review'] {    text-decoration-line: underline  }  .underline\:is\(\:hover\,\:focus-visible\):is(:hover, :focus-visible) {    text-decoration-line: underline  }}

선택자 목록은 클래스 소유 요소에서 다시 시작

쉼표는 대안을 구분합니다. 각 선택자는 클래스를 가진 요소에서 시작하며 어느 상태든 일치할 수 있습니다.

텍스트 설명
  1. underline:hover,:focus-visible은 각 분기에서 전체 이스케이프 클래스 소유 요소를 반복하는 선택자 목록을 생성합니다.
  2. hover와 focus-visible은 대안이며 두 상태에 모두 일치할 필요는 없습니다. 두 분기는 선언을 공유합니다.

선택자 함수

함수일치 동작
:is(...)목록의 선택자 중 하나 이상에 일치
:where(...):is()와 같이 일치하지만 함수와 인수의 명시도는 0
:not(...)목록의 선택자 중 하나라도 일치하는 요소를 제외
:has(...)선택 중인 요소를 기준으로 상대적 일치를 검사

:has()는 관계를 검사하며 일치하는 관련 요소로 선언을 옮기지 않습니다. b-blue-60:has(>input:checked)는 label의 직계 자식 input이 선택되었을 때 label의 테두리 색을 설정합니다.

<label class="b(1) b-solid b-line-control b-blue-60:has(>input:checked)"><input type="checkbox" />Include archived items</label>
생성된 CSS
@layer theme {  :root,  :host {    --color-blue-60: oklch(51.83% .2687 266.1)  }}@layer utilities {  .b-blue-60\:has\(\>input\:checked\):has(>input:checked) {    border-color: var(--color-blue-60)  }  .underline\:has\(\+input\:checked\):has(+input:checked) {    text-decoration-line: underline  }}

상대적 일치는 형제 요소일 수도 있습니다. underline:has(+input:checked)는 다음 형제 요소가 선택된 input일 때 클래스를 가진 요소에 밑줄을 적용합니다. 네이티브 :has() 제한이 그대로 적용되며 :has()를 자신 안에 중첩하는 것은 유효하지 않습니다. 작동하는 체크박스 예제와 실용적인 대안은 호환성을 참고하세요.

has()는 자식을 검사하고 소유 요소를 스타일링

클래스는 label에 있습니다. input의 선택 상태를 검사하고 label이 border-color를 받습니다.

텍스트 설명
  1. b-blue-60:has(>input:checked)는 클래스를 가진 요소에 선택한 직계 자식 input이 있는지 검사합니다.
  2. 일치하면 input이 아닌 소유 label의 테두리 색이 바뀝니다. 검사 위치와 스타일 대상을 구분하도록 input을 같은 경계 안에 표시합니다.

네이티브 상태

Master CSS는 네이티브 의사 클래스 이름을 유지합니다. 다음은 자주 쓰는 접미사이며 전체 상태 레지스트리가 아닙니다.

접미사네이티브 일치 맥락
:hover, :active포인터 호버 또는 활성화
:focus, :focus-visible, :focus-within요소의 포커스, 가시적 포커스 표시, 내부의 포커스
:first-child, :last-child, :nth-child(even)형제 요소 사이의 위치
:valid, :invalid, :required네이티브 폼 제약
:disabled비활성화된 폼 컨트롤
:checked, :indeterminate네이티브 컨트롤 상태
:dir(rtl), :dir(ltr)해석된 텍스트 방향

:first-child, :nth-child(odd) 같은 전체 이름을 사용하세요. Master CSS가 출력하는 표기라도 브라우저에서 지원하지 않거나 유효하지 않을 수 있습니다. 각 상태의 자세한 동작은 네이티브 의사 클래스 레퍼런스를 참고하세요.

<ul>  <li class="bg-surface-inset:nth-child(even)">Draft</li>  <li class="bg-surface-inset:nth-child(even)">In review</li>  <li class="bg-surface-inset:nth-child(even)">Published</li></ul>
생성된 CSS
@layer theme {  :root,  :host {    --color-zinc-5: oklch(96.5% .0011 265);    --color-zinc-100: oklch(15% .0016 265)  }  :root,  :host {    --color-surface-inset: light-dark(var(--color-zinc-5), var(--color-zinc-100))  }  :root,  :host {    --spacing-xs: .5rem  }}@layer utilities {  .bg-surface-inset\:nth-child\(even\):nth-child(even) {    background-color: var(--color-surface-inset)  }  .mr-xs\:dir\(rtl\):dir(rtl) {    margin-right: var(--spacing-xs)  }  .\(opacity\:\.5\)\:disabled:disabled {    opacity: .5  }}

속성 선택자

속성 접미사는 DOM 값을 검사합니다. 불리언 형식의 속성 선택자는 존재 여부를 검사합니다. [open]은 펼쳐진 details 요소에 일치하고 [data-active]는 해당 속성이 있으면 일치합니다. 특정 상태 값을 검사하려면 [aria-pressed=true]처럼 값을 포함하세요.

접미사일치 조건
[data-active]값이 비어 있어도 속성이 존재함
[aria-pressed=true]정확히 true인 값
[href^=https]값이 https로 시작
[href$='.pdf']값이 .pdf로 끝남
[title*=master]값에 master가 포함됨
[lang|=en]값이 en이거나 en-으로 시작
[title~=css]공백으로 구분한 값에 단어 css가 포함됨

속성의 정확한 값과 단어 일치는 다름

각 행은 같은 DOM 속성 값을 두 접미사로 검사합니다. 하이픈은 공백으로 구분하는 단어 경계가 아닙니다.

텍스트 설명
  1. [title=css]는 정확히 css인 값에만 일치합니다. [title~=css]는 공백으로 구분한 단어가 css와 같으면 일치합니다.
  2. css에는 두 선택자가 모두 일치합니다. master css에는 단어 선택자만 일치하며 css-in-js에는 둘 다 일치하지 않습니다.
  3. 선택자는 속성을 검사하며 클래스 문자열을 나누거나 속성 값을 수정하지 않습니다.

따옴표로 감싼 속성 텍스트는 리터럴로 유지됩니다. underline[data-state=':first']:first-child는 값 :first와 요소의 위치를 별도로 검사합니다. [data-id='a_b']의 밑줄은 값 안에 남고 .is\_active의 이스케이프된 밑줄은 클래스 식별자 안에 남습니다.

<a class="underline[data-state=':first']:first-child" data-state=":first" href="/guide">Guide</a><a class="underline.is\_active is_active" href="/reference">Reference</a>
생성된 CSS
@layer utilities {  .underline\.is\\_active.is\_active {    text-decoration-line: underline  }  .underline\[data-id\=\'a_b\'\][data-id='a_b'] {    text-decoration-line: underline  }  .underline\[data-state\=\'\:first\'\]\:first-child[data-state=':first']:first-child {    text-decoration-line: underline  }}

CSS 따옴표는 HTML 공백이 클래스를 나누는 것을 막지 못합니다. 속성 값에 실제 공백이 필요하면 [data-label='New\000020collection']처럼 CSS 이스케이프를 사용하세요. 따옴표 값 바로 뒤에 대소문자 플래그를 붙일 수 있습니다. 예를 들어 [data-kind='draft'i]는 ASCII 대소문자를 구분하지 않습니다. 네이티브 연산자와 대소문자 일치는 속성 선택자를 참고하세요.

생성된 CSS
@layer utilities {  .underline\[data-kind\=\'draft\'i\][data-kind='draft' i] {    text-decoration-line: underline  }  .underline\[data-label\=\'New\\000020collection\'\][data-label='New\000020collection'] {    text-decoration-line: underline  }}

의사 요소

의사 요소 접미사는 원래 요소 대신 해당 의사 요소를 대상으로 합니다. 생성 콘텐츠에는 content 선언을 명시적으로 쓰세요.

<span class="(content:open-quote)::before (content:close-quote)::after">Keep the interface clear.</span>
생성된 CSS
@layer utilities {  .\(background-color\:currentcolor\)\:\:-webkit-scrollbar-thumb::-webkit-scrollbar-thumb {    background-color: currentcolor  }  .\(content\:close-quote\)\:\:after::after {    content: close-quote  }  .\(content\:open-quote\)\:\:before::before {    content: open-quote  }}

생성 콘텐츠는 의사 요소에 속함

인용부호는 실제 ::before와 ::after의 content 선언이 생성합니다. 세 괄호는 하나의 렌더링 요소의 부분을 나타내며 DOM 자식 세 개가 아닙니다.

텍스트 설명
  1. span은 Keep the interface clear 텍스트를 포함합니다. (content:open-quote)::before와 (content:close-quote)::after 클래스가 보이는 인용부호를 제공합니다.
  2. 각 선언은 해당 의사 요소를 대상으로 합니다. Master CSS는 별도 자식 요소를 만들거나 의사 요소 접미사가 있다는 이유만으로 content 선언을 추가하지 않습니다.

공급업체별 선택자는 명시적으로 쓰세요. Master CSS는 표기를 유지하며 의사 요소를 공급업체별 변형으로 확장하거나 브라우저 지원을 제공하지 않습니다. 괄호가 포함된 따옴표 값은 네이티브 선언 경계를 참고하세요.

명시도

생성된 선택자는 브라우저의 명시도 규칙을 따릅니다. 이스케이프된 클래스 이름은 안에 있는 구두점과 관계없이 클래스 선택자 하나의 명시도를 더합니다. 추가한 접미사는 별도로 기여합니다.

클래스, ID – 클래스/속성/상태 – 타입/의사 요소CSS
underline0-1-0
underline:hover0-2-0
underline>a0-1-1
underline:where(:hover,#selected)0-1-0
underline:is(:hover,#selected)1-1-0

:is(), :not(), :has()는 선택자 목록에서 명시도가 가장 높은 인수를 사용합니다. :where()는 인수를 포함해 명시도를 더하지 않습니다. 결합자와 전체 선택자도 명시도를 더하지 않습니다. 이 가중치는 캐스케이드가 출처, 중요도, 레이어 우선순위를 결정한 뒤 적용됩니다. 따라서 명시도가 높은 선택자가 다른 레이어의 규칙을 자동으로 이기는 것은 아닙니다.

생성된 CSS
@layer utilities {  .underline\:is\(\:hover\,\#selected\):is(:hover, #selected) {    text-decoration-line: underline  }  .underline\:where\(\:hover\,\#selected\):where(:hover, #selected) {    text-decoration-line: underline  }}

where()와 is()는 같은 상태에도 다른 명시도

그림은 명시도만 비교합니다. 캐스케이드는 출처, 중요도, 레이어 우선순위를 먼저 고려합니다.

텍스트 설명
  1. 두 생성 선택자에서 이스케이프된 전체 클래스 소유 요소는 0-1-0을 더합니다.
  2. :where(:hover,#selected)의 접미사는 0-0-0을 더하므로 합계는 0-1-0입니다.
  3. :is(:hover,#selected)에서는 ID 인수가 가장 높은 인수 명시도 1-0-0을 제공하므로 호버 대안이 일치할 때도 합계는 1-1-0입니다.

규칙 정렬은 캐스케이드 레이어를, 실제 선택 방법은 가이드의 재정의 흐름을 참고하세요. HTML의 클래스 순서를 바꿔도 명시도는 바뀌지 않습니다.

외부 맥락

접미사는 클래스를 가진 요소에서 시작합니다. 대상에 조상이나 앞선 형제 요소에 따른 스타일이 필요하면 네이티브 CSS 규칙으로 그 관계를 직접 표현할 수 있습니다.

@layer components {  .active .contextual {    display: none;  }  .active > .child-contextual {    display: none;  }  .active + .adjacent-contextual {    display: none;  }  .active ~ .sibling-contextual {    display: none;  }}

여러 유틸리티 선언을 같은 관계로 감싸려면 네이티브 선택자와 @contents가 있는 믹스인을 사용하세요. 확장과 전달은 믹스인 콘텐츠 규칙에, 이 형식을 선택할 때는 스타일 재사용에 설명되어 있습니다.

생성 CSS는 출력되었다는 증거이며 브라우저가 선택자를 지원하거나 일치시킨다는 증명은 아닙니다. DOM 관계, 실제 상태, 네이티브 선택자의 유효성을 확인하세요. 일반 CSS 선택자 목록에서는 잘못된 분기 하나가 전체 목록을 무효화할 수 있습니다. :is()와 :where()는 오류를 허용하는 선택자 목록을 사용합니다. 브라우저 검사와 대안 설계는 호환성을 참고하세요.