CSS 조건부 규칙 모듈 레벨 5

W3C 워킹 드래프트,

이 문서에 대한 추가 정보
이 버전:
https://www.w3.org/TR/2025/WD-css-conditional-5-20251030/
최신 게시 버전:
https://www.w3.org/TR/css-conditional-5/
에디터스 드래프트:
https://drafts.csswg.org/css-conditional-5/
히스토리:
https://www.w3.org/standards/history/css-conditional-5/
피드백:
CSSWG 이슈 저장소
명세 내 인라인
에디터:
L. David Baron (Google)
Elika J. Etemad / fantasai (Apple)
Chris Lilley (W3C)
Miriam E. Suzanne (초청 전문가)
Lea Verou (초청 전문가)
명세에 대한 수정 제안:
GitHub 에디터
델타 명세:
테스트 스위트:
https://wpt.fyi/results/css/css-conditional/

요약

이 모듈은 스타일 시트의 일부를 조건부로 처리할 수 있게 하는 CSS의 기능을 포함하고 있습니다. 이는 스타일 시트가 적용되는 프로세서 또는 환경의 능력에 따라 동작합니다. CSS Conditional 4 [css-conditional-4]의 기능을 포함하고 확장하며, 일반화된 조건 규칙 @when과 연쇄 조건 규칙 @else를 추가하고, supports query 문법에 폰트 처리 쿼리를 도입하여 @supports 규칙과 컨테이너 쿼리에서 사용할 수 있게 합니다.

CSS는 구조화된 문서(예: HTML, XML 등)의 렌더링을 화면, 인쇄물 등에서 설명하기 위한 언어입니다.

이 문서의 상태

이 섹션은 본 문서가 발행될 당시의 상태를 설명합니다. 현재 W3C의 발행 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인에서 확인할 수 있습니다.

이 문서는 CSS 작업 그룹에 의해 워킹 드래프트로 발행되었으며, 권고안 트랙을 사용합니다. 워킹 드래프트로의 발행은 W3C 및 그 회원들의 승인을 의미하지 않습니다.

이 문서는 초안이며, 언제든지 다른 문서에 의해 갱신, 교체 또는 폐기될 수 있습니다. 이 문서를 진행 중인 작업 외의 참고 용도로 인용하는 것은 적절하지 않습니다.

피드백은 GitHub 이슈 등록(권장)을 통해 보내주시고, 제목에 사양 코드 “css-conditional”을 포함하여 “[css-conditional] …의견 요약…”처럼 작성해 주세요. 모든 이슈와 코멘트는 아카이브됩니다. 또는 (아카이브됨) 공개 메일링 리스트 www-style@w3.org로도 피드백을 보낼 수 있습니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서의 적용을 받습니다.

이 문서는 W3C 특허 정책 하에서 운영되는 그룹에 의해 작성되었습니다. W3C는 그룹 산출물 관련 공개 특허 공개 목록을 유지하며, 해당 페이지에는 특허 공개 방법도 안내되어 있습니다. 실제로 특허에 대해 알고 있고 해당 특허가 필수 청구항을 포함한다고 생각하는 개인은 W3C 특허 정책 6조에 따라 정보를 공개해야 합니다.

1. 소개

현재 이 문서는 레벨 5에서 새롭게 추가된 항목들의 초기 초안입니다. 레벨 3과 레벨 4의 기능들은 여전히 [css-conditional-3][css-conditional-4]에 정의되어 있으며, 아직 이곳으로 복사되지 않았습니다.

CSS Conditional Level 5는 @supports 규칙과 supports query 문법을 확장하여, 커스텀 지원 조건뿐 아니라 지원되는 at-rules 및 폰트 기술에 대한 테스트를 가능하게 합니다.

또한 @when 규칙을 추가하여 조건 규칙의 개념을 일반화합니다. 기존 조건 규칙에서 표현할 수 있는 모든 것은 해당 조건의 종류를 선언하는 적절한 함수로 감싸서 @when에서도 표현할 수 있습니다. 이를 통해 저자는 미디어 쿼리와 supports 쿼리 같은 여러 유형의 쿼리를 단일 불리언 표현식으로 쉽게 결합할 수 있습니다. 이 기능이 없으면 저자는 별도의 조건 규칙을 중첩하는 방식에 의존해야 하며, 이는 읽고 쓰기 어려울 뿐 아니라 조건들이 “and” 불리언 관계로 결합된다고 가정하게 만들고(다르게 표시하기도 쉽지 않음), 제안된 조건 규칙 체인에서의 활용도를 제한합니다.

또한 @else 규칙을 추가합니다. 이는 다른 조건 규칙 바로 뒤에 이어지며, 직전 규칙의 조건의 반대를 자동으로 적용하여, 조건 규칙 체인에서 일치하는 첫 번째 규칙만 적용되도록 합니다.

또한 컨테이너 쿼리를 추가합니다. 이는 개념적으로 미디어 쿼리와 유사하지만, 문서 전체가 아니라 문서 내 요소(예: 박스 치수 또는 계산된 스타일)의 특성을 테스트할 수 있도록 합니다.

2. @supports 규칙의 확장

이 레벨의 명세는 <supports-feature> 문법을 다음과 같이 확장합니다:

<supports-feature> = <supports-selector-fn>
                   | <supports-font-tech-fn> | <supports-font-format-fn>
                   | <supports-at-rule-fn>
           | <supports-decl>
<supports-decl> = ( [ <declaration> | <supports-condition-name> ] )
<supports-font-tech-fn> = font-tech( <font-tech> )
<supports-font-format-fn> = font-format( <font-format> )
<supports-at-rule-fn> = at-rule( <at-keyword-token> )
<supports-condition-name>

UA가 명명된 조건을 지원하면 결과는 true입니다. 이름을 인식하지 못하면 결과는 false입니다.

<supports-font-tech-fn>

UA가 함수 인자로 제공된 폰트 기술을 지원하면 결과는 true입니다.

<supports-font-format-fn>

UA가 함수 인자로 제공된 폰트 포맷을 지원하면 결과는 true입니다.

<supports-at-rule-fn>

UA가 함수 인자로 제공된 at-rule을 지원하면 결과는 true입니다.

2.1. 지원 정의의 확장

2.1.1. 폰트 기술 및 형식

테스트

CSS 프로세서는 레이아웃과 렌더링에서 지정된 CSS Fonts 4 § 11.1 Font tech를 활용할 수 있을 때 폰트 기술을 지원한다고 간주됩니다.

CSS 프로세서는 레이아웃과 렌더링에서 CSS Fonts 4 § 11.2 Font formats에 지정된 형식을 활용할 수 있고, 이 형식이 <string>으로 지정되지 않았을 때 폰트 포맷을 지원한다고 간주됩니다.

2.1.2. At-규칙

테스트

CSS 프로세서는 어떤 컨텍스트에서든 지정된 at-keyword로 시작하는 at-rule을 허용한다면 at-rule을 지원한다고 간주됩니다.

참고: @charset은 유효한 at-rule이 아니므로, 이 정의에 따라 지원되는 것으로 간주되지 않습니다.

2.1.3. 이름이 있는 조건

CSS 프로세서는 관련된 명명된 supports 조건이 true를 반환할 때 이름이 있는 조건을 지원한다고 간주됩니다.

3. 일반화된 조건 규칙: @when 규칙

@when at-rule은 조건부 그룹 규칙으로서, @media@supports 같은 개별 조건부 그룹 규칙을 일반화합니다. 정의는 다음과 같습니다:

@when <boolean-condition> {
  <rule-list>
}

여기서 <boolean-condition>Media Queries 4 § 3 Syntax의 불 대수와 유사하되, 잎(leaf)으로 media()supports() 함수가 사용됩니다.

Conditional에서 "잎이 X인 불 대수"를 일반적인 방식으로 정의하여, 모든 조건 규칙이 이를 직접 참조할 수 있도록 하고 각 규칙이 불 대수를 개별적으로 재정의하지 않도록 해야 합니다.

media()supports() 함수는 다음과 같이 정의됩니다:

media() = media( [ <mf-plain> | <mf-boolean> | <mf-range> ] )
supports() = supports( <declaration> )

media() 또는 supports() 함수는 그 안에 포함된 조건이 연관되는 불리언 결과와 연관됩니다.

4. 연쇄 조건: @else 규칙

일반적으로 조건부 그룹 규칙은 서로 독립적입니다. 각 규칙은 다른 규칙에 직접 의존하지 않는 별도의 조건을 가지며, 자신의 조건에만 근거하여 내부 규칙을 적용할지 여부를 결정합니다.

이는 단순한 조건에는 괜찮지만, 상호 배타적이어야 하는 조건 모음을 작성하기는 어렵게 만듭니다: 저자는 다른 규칙이 활성화되어야 할 때 자신이 활성화되지 않도록 매우 신중하게 조건을 구성해야 하며, 조건 모음이 실수로 모두 어떤 상황을 배제하여 그 상황이 스타일 없이 남지 않도록 보장해야 합니다.

@else 규칙은 조건부 그룹 규칙을 연결한 조건 규칙 체인을 구성하는 데 사용되며, 여러 조건부 그룹 규칙을 연관시켜 일치하는 첫 번째 규칙만 자신의 조건을 true로 평가하도록 보장합니다. 정의는 다음과 같습니다:

@else <boolean-condition>? {
  <rule-list>
}

@else@when과 동일하게 해석됩니다. <boolean-condition>이 생략되면 항상 true인 조건을 가진 것으로 취급됩니다.

조건 규칙 체인은 연속된 조건부 그룹 규칙의 시퀀스로서, @else가 아닌 조건부 그룹 규칙으로 시작하고 그 뒤에 0개 이상의 @else 규칙이 따릅니다. 연속된 조건부 그룹 규칙들 사이에는 공백 및/또는 주석 외에는 어떤 것도 올 수 없으며, 그 외의 토큰이 있으면 체인이 “끊어집니다”.

체인에서 마지막 @else만 조건 생략을 허용하도록 요구해야 할까요? 디버깅 시 if-else 체인의 하나를 "true"로 설정해 단락시키는 일은 흔하며, CSS에서도 비슷하게 유용할 것입니다. 조건을 실수로 생략했을 때도 잘못되었음을 비교적 쉽게 알아볼 수 있습니다.

조건 규칙 체인 내에서 각 조건부 그룹 규칙의 조건은 순서대로 평가됩니다. 그중 하나가 true이면, 체인에서 그 이후의 모든 조건부 그룹 규칙의 조건은 명시된 조건과 상관없이 false로 평가됩니다.

@else 규칙이 조건 규칙 체인의 일부가 아니면 유효하지 않으며 무시되어야 합니다.

예를 들어, 다음은 (약간 엉뚱한) 조건 체인입니다:
@when media(width >= 400px) and media(pointer: fine) and supports(display: flex) {
  /* A */
} @else supports(caret-color: pink) and supports(background: double-rainbow()) {
  /* B */
} @else {
  /* C */
}

위 규칙들 중 정확히 하나만 선택됩니다. 두 번째 규칙이 큰 너비, 정밀 포인터, 또는 플렉스박스 지원을 배제하지 않더라도, 그리고 마지막 규칙이 아무 것도 지정하지 않더라도 마찬가지입니다.

조건 규칙 체인 없이 동일한 결과를 얻으려면 다음처럼 작성해야 합니다:

@media (width >= 400px) and (pointer: fine) {
  @supports (display: flex) {
  /* A */
  }
  @supports not (display: flex) {
  @supports (caret-color: pink) and (background: double-rainbow()) {
    /* B */
  }
  @supports not ((caret-color: pink) and (background: double-rainbow())) {
    /* C */
  }
  }
}
@media not ((width >= 400px) and (pointer: fine)) {
  @supports (caret-color: pink) and (background: double-rainbow()) {
  /* B */
  }
  @supports not ((caret-color: pink) and (background: double-rainbow())) {
  /* C */
  }
}

이는 동시에 읽기 어렵고, 조건과 내용의 상당한 중복을 요구하며, 올바르게 작성하기가 매우 어렵습니다. 조건이 더 복잡해지면(실제 컨텐츠에서는 흔함) 예시는 훨씬 더 나빠질 것입니다.

이 예에서는 선호도 순으로 서로 다른 3가지 컬러 폰트 기술을 테스트하고, 모노크롬 폴백을 추가합니다. 가장 강력한 COLRv1은 그라디언트와 폰트 가변 둘 다를 지원하고, 그다음인 SVG는 그라디언트를 지원하며, 가장 약한 COLRv0는 단색 채우기만 지원합니다.

폴백은 테스트 조건이 없으므로, 앞선 조건 중 하나가 충족되지 않으면 항상 선택됩니다.

@when font-tech(color-COLRv1) and font-tech(variations) {
  @font-face { font-family: icons; src: url(icons-gradient-var.woff2); }
}
@else font-tech(color-SVG) {
  @font-face { font-family: icons; src: url(icons-gradient.woff2); }
}
@else font-tech(color-COLRv0) {
  @font-face { font-family: icons; src: url(icons-flat.woff2); }
}
@else {
  @font-face { font-family: icons; src: url(icons-fallback.woff2); }
}

이 예에서 가변 컬러 폰트는 COLRv1이 지원되고 폰트 가변도 지원되는 경우에만 다운로드됩니다.

또한 사용 가능한 옵션 중 하나만 다운로드됩니다. 다음 예에서 보이듯이 @when@else가 없으면 그렇지 않습니다.

이 예에서는 COLRv1이 지원되면 폴백이 사용되지 않을 것처럼 보이지만, 실제로는 두 폰트가 모두 다운로드되어 사용되지 않는다면 대역폭을 낭비하게 됩니다.

일부 문자에 대해서는 여전히 폴백이 사용될 수 있습니다. 예를 들어, 컬러 폰트가 라틴 문자만 지원하고 폴백은 라틴과 그리크를 지원하는 경우가 그렇습니다.

@font-face { font-family: icons; src: url(icons-fallback.woff2);
@supports font-tech(color-COLRv1) {
  @font-face { font-family: icons; src: url(icons-gradient-var.woff2); }
}

5. 컨테이너 쿼리

미디어 쿼리가 문서가 표시되는 사용자 에이전트나 기기 환경(뷰포트 치수 또는 사용자 선호 등)의 측면을 질의하는 방법을 제공하는 반면, 컨테이너 쿼리는 문서 내 요소의 측면(박스 치수나 계산된 스타일 등)을 테스트할 수 있게 합니다.

기본적으로, 모든 요소는 컨테이너 스타일 쿼리를 위한 쿼리 컨테이너이며, 컨테이너 크기 쿼리컨테이너 스크롤 상태 쿼리에 대해서는 container-type 속성 (또는 container 약식)을 사용하여 추가 쿼리 유형을 지정함으로써 쿼리 컨테이너로 설정할 수 있습니다. 쿼리 컨테이너플랫 트리 하위에 적용되는 스타일 규칙은 @container 조건부 그룹 규칙을 사용하여 해당 컨테이너를 대상으로 한 쿼리로 조건을 걸 수 있습니다.

예를 들어, 메인 컨텐츠 영역과 사이드바를 컨테이너로 정의하고, 컨테이너의 크기에 따라 세로 레이아웃에서 가로 레이아웃으로 바뀌는 .media-object를 기술할 수 있습니다:
main, aside {
  container: my-layout / inline-size;
}

.media-object {
  display: grid;
  grid-template: 'img' auto 'content' auto / 100%;
}

@container my-layout (inline-size > 45em) {
  .media-object {
  grid-template: 'img content' auto / auto 1fr;
  }
}

메인과 사이드바 영역의 미디어 오브젝트는 각자의 컨테이너 문맥에 반응할 것입니다.

::part()::slotted() 의사 요소 선택자는 DOM 트리의 실제 요소를 나타내므로, 해당 요소들의 플랫 트리 조상들에 의해 쿼리 컨테이너가 설정될 수 있습니다. 다른 의사 요소의 경우, 발생 원소의 포함적 플랫 트리 조상들에 의해 쿼리 컨테이너가 설정될 수 있습니다.

따라서 다음이 성립합니다:
발생 원소의 크기를 쿼리하는 ::before 선택자:
<style>
  #container {
  width: 100px;
  container-type: inline-size;
  }
  @container (inline-size < 150px) {
  #inner::before {
    content: "BEFORE";
  }
  }
</style>
<div id=container>
  <span id=inner></span>
</div>
섀도 호스트 자식을 스타일링하기 위한 ::slotted() 선택자는 섀도 트리의 컨테이너를 쿼리할 수 있습니다:
<div id=host style="width:200px">
  <template shadowroot=open>
  <style>
    #container {
    width: 100px;
    container-type: inline-size;
    }
    @container (inline-size < 150px) {
    ::slotted(span) {
      color: green;
    }
    }
  </style>
  <div id=container>
    <slot />
  </div>
  </template>
  <span id=slotted>Green</span>
</div>

5.1. 쿼리 컨테이너 생성: container-type 속성

이름: container-type
값: normal | [ [ size | inline-size ] || scroll-state ]
초깃값: normal
적용 대상: 모든 요소
상속: no
백분율: n/a
계산값: 지정된 키워드
표준 순서: 문법에 따름
애니메이션 유형: 애니메이션 불가

container-type 속성은 특정 유형의 쿼리에 대해 요소를 쿼리 컨테이너로 설정합니다. 특정 형태의 containment가 필요한 크기 컨테이너 쿼리의 경우 이 속성을 통해 요소를 명시적으로 쿼리 컨테이너로 만듭니다. 다른 유형의 쿼리 컨테이너의 경우에는, 컨테이너 스타일 쿼리처럼 어떤 요소든 쿼리 컨테이너가 될 수 있습니다.

값의 의미는 다음과 같습니다:

size
쿼리 컨테이너를 컨테이너의 인라인 축과 블록 축 모두에 대한 컨테이너 크기 쿼리의 대상으로 설정합니다. 스타일 컨테인먼트사이즈 컨테인먼트주 박스에 적용하고, 독립적인 포맷팅 컨텍스트를 설정합니다.
inline-size
컨테이너 자신의 인라인 축에 대한 컨테이너 크기 쿼리의 대상으로 쿼리 컨테이너를 설정합니다. 스타일 컨테인먼트인라인-사이즈 컨테인먼트주 박스에 적용하고, 독립적인 포맷팅 컨텍스트를 설정합니다.
scroll-state
컨테이너 스크롤 상태 쿼리를 위한 쿼리 컨테이너를 설정합니다
normal
이 요소는 어떤 컨테이너 크기 쿼리컨테이너 스크롤 상태 쿼리에 대해서도 쿼리 컨테이너가 아니지만, 컨테이너 스타일 쿼리에 대해서는 여전히 쿼리 컨테이너로 남습니다.
예를 들어, 저자는 컨테이너 크기에 반응하는 타이포그래피를 만들어 font-size, line-height 및 기타 타이포그래피 관련 속성을 컨테이너의 크기에 따라 조정할 수 있습니다:
aside, main {
  container-type: inline-size;
}

h2 { font-size: 1.2em; }

@container (width > 40em) {
  h2 { font-size: 1.5em; }
}

쿼리 조건에 사용된 40em 값은 해당 계산값 기준의 font-size에 대해 관련 쿼리 컨테이너를 기준으로 합니다.

컨테이너는 또한 질의를 위해 계산된 스타일 값을 노출할 수 있습니다. 이는 여러 속성에 걸친 동작 토글에 유용할 수 있습니다:
@container style(--cards: small) {
  article {
  border: thin solid silver;
  border-radius: 0.5em;
  padding: 1em;
  }
}
컨테이너는 스크롤 오프셋에 따라 달라지는 상태도 노출할 수 있습니다. 이 예에서는 상단 가장자리에 달라붙어 있을 때 sticky 위치의 요소의 하위 요소에 스타일을 적용합니다:
#sticky {
  container-type: scroll-state;
  position: sticky;
}
@container scroll-state(stuck: top) {
  #sticky-child {
  background-color: lime;
  }
}

5.2. 쿼리 컨테이너 이름 지정: container-name 속성

이름: container-name
값: none | <custom-ident>+
초깃값: none
적용 대상: 모든 요소
상속: no
백분율: n/a
계산값: none 키워드 또는 식별자의 순서 있는 목록
표준 순서: 문법에 따름
애니메이션 유형: 애니메이션 불가
테스트

container-name 속성은 쿼리 컨테이너 이름 목록을 지정합니다. 이 이름들은 @container 규칙에서 어떤 쿼리 컨테이너를 대상으로 할지 필터링하는 데 사용할 수 있습니다. 컨테이너 이름은 트리 범위 이름이 아닙니다.

none
쿼리 컨테이너에는 쿼리 컨테이너 이름이 없습니다.
<custom-ident>
쿼리 컨테이너 이름식별자로 지정합니다. none, and, not, or 키워드는 이 <custom-ident>에서 제외됩니다.
어떤 경우에는 가장 가까운 조상 컨테이너가 아니더라도 특정 컨테이너의 측면을 질의하고 싶을 수 있습니다. 예를 들어, 메인 컨텐츠 영역의 높이와 더 중첩된 인라인 컨테이너의 너비를 질의하고 싶을 수 있습니다.
main {
  container-type: size;
  container-name: my-page-layout;
}

.my-component {
  container-type: inline-size;
  container-name: my-component-library;
}

@container my-page-layout (block-size > 12em) {
  .card { margin-block: 2em; }
}

@container my-component-library (inline-size > 30em) {
  .card { margin-inline: 2em; }
}

이름만을 기준으로 컨테이너를 질의하는 것도 가능합니다.

@container my-page-layout {
  .card { padding: 1em; }
}

5.3. 이름 있는 컨테이너 생성: container 단축 속성

이름: container
값: <'container-name'> [ / <'container-type'> ]?
초깃값: 각 속성별 참조
적용 대상: 각 속성별 참조
상속: 각 속성별 참조
백분율: 각 속성별 참조
계산값: 각 속성별 참조
애니메이션 유형: 각 속성별 참조
표준 순서: 문법에 따름
테스트

container 단축 속성container-typecontainer-name을 동시에 설정합니다. <'container-type'>이 생략되면, 초깃값으로 재설정됩니다.

단축 문법을 사용해 container-typecontainer-name을 모두 정의할 수 있습니다:
main {
  container: my-layout / size;
}

.grid-item {
  container: my-component / inline-size;
}

5.4. 컨테이너 쿼리: @container 규칙

@container 규칙은 조건부 그룹 규칙의 하나로, 그 조건에 컨테이너 쿼리를 포함합니다. 컨테이너 쿼리는 컨테이너 크기 쿼리와/또는 컨테이너 스타일 쿼리의 불리언 조합입니다. <block-contents> 블록 안의 스타일 선언은 @container 규칙의 조건에 따라 해당 컨테이너 쿼리가 해당 요소의 쿼리 컨테이너에 대해 true일 때만 적용됩니다.

@container 규칙의 문법은 다음과 같습니다:

@container <container-condition># {
  <block-contents>
}

설명:

<container-condition> = [ <container-name>? <container-query>? ]!
<container-name> = <custom-ident>
<container-query> = not <query-in-parens>
          | <query-in-parens> [ [ and <query-in-parens> ]* | [ or <query-in-parens> ]* ]
<query-in-parens> = ( <container-query> )
          | ( <size-feature> )
          | style( <style-query> )
          | scroll-state( <scroll-state-query> )
          | <general-enclosed>

<style-query>     = not <style-in-parens>
          | <style-in-parens> [ [ and <style-in-parens> ]* | [ or <style-in-parens> ]* ]
          | <style-feature>
<style-in-parens> = ( <style-query> )
          | ( <style-feature> )
          | <general-enclosed>
<style-feature> = <style-feature-plain> | <style-feature-boolean> | <style-range>
<style-feature-plain> = <style-feature-name> : <style-feature-value>
<style-feature-boolean> = <style-feature-name>
<style-range> = <style-range-value> <mf-comparison> <style-range-value>
    | <style-range-value> <mf-lt> <style-range-value> <mf-lt> <style-range-value>
    | <style-range-value> <mf-gt> <style-range-value> <mf-gt> <style-range-value>
<style-range-value> = <custom-property-name> | <style-feature-value>

<scroll-state-query>     = not <scroll-state-in-parens>
             | <scroll-state-in-parens> [ [ and <scroll-state-in-parens> ]* | [ or <scroll-state-in-parens> ]* ]
             | <scroll-state-feature>
<scroll-state-in-parens> = ( <scroll-state-query> )
             | ( <scroll-state-feature> )
             | <general-enclosed>
테스트

none, and, not, or 키워드는 위 <custom-ident>에서 제외됩니다.

각 요소마다, 쿼리할 쿼리 컨테이너는 해당 요소의 조상 쿼리 컨테이너<container-query>에 사용된 모든 컨테이너 기능에 대해 유효하게 설정된 쿼리 컨테이너에서 선택됩니다. <container-query>에 알 수 없거나 지원되지 않는 컨테이너 기능이 포함되어 있으면, 해당 <container-condition>에 대해 쿼리 컨테이너가 선택되지 않습니다. <container-name>은 고려되는 쿼리 컨테이너 집합을 일치하는 쿼리 컨테이너 이름을 가진 컨테이너로만 필터링합니다.

요소에 대해 적합한 쿼리 컨테이너가 선택되면, <container-query>의 각 컨테이너 기능이 해당 쿼리 컨테이너에 대해 평가됩니다. 조상에 적합한 쿼리 컨테이너가 없으면, 해당 요소에 대해 컨테이너 쿼리unknown이 됩니다. 미디어 쿼리와 마찬가지로, <general-enclosed>unknown으로 평가됩니다. <container-query>가 생략된 경우, <container-name>만 일치하면 쿼리 컨테이너는 적합한 것으로 간주됩니다.

컨테이너 쿼리에 여러 <container-condition>이 포함되어 있을 때, 각 조건은 자체 쿼리 컨테이너를 선택하여 독립적으로 평가합니다. 컨테이너 쿼리는 구성 요소 <container-condition>하나라도 true이면 true가 되고, 모두 false일 때만 false가 됩니다.

미디어 쿼리와 마찬가지로, 여러 쿼리를 하나의 조건에 연결할 수 있습니다:
@container card (inline-size > 30em) and style(--responsive: true) {
  /* styles */
}

위 스타일은 조상 컨테이너 중 "card"라는 이름을 가진 컨테이너가 inline-sizestyle 조건을 모두 충족할 때만 적용됩니다.

여러 조건을 리스트로 결합해 각 조건이 서로 다른 컨테이너에 대해 평가되도록 할 수도 있습니다:

@container card (inline-size > 30em), style(--large: true) {
  /* styles */
}

위 스타일은 조상 컨테이너 중 "card"라는 이름을 가진 컨테이너가 inline-size 조건을 만족하거나 혹은 가장 가까운 스타일 컨테이너가 style 조건을 만족할 때 적용됩니다.

여러 중첩된 컨테이너 쿼리 내부의 요소에 정의된 스타일 규칙은 모든 바깥 컨테이너 쿼리가 true일 때 적용됩니다.

참고: 중첩된 컨테이너 쿼리는 서로 다른 컨테이너를 기준으로 평가될 수 있으므로, 개별 <container-condition>을 하나의 쿼리로 합치는 것이 항상 가능하지는 않습니다.

단일 콤마로 구분된 컨테이너 쿼리를 사용해 여러 컨테이너를 쿼리할 수 있습니다:
@container card (inline-size > 30em), style(--responsive: true) {
  /* styles */
}

위 스타일은 요소의 조상 중 하나라도 "card"라는 이름의 컨테이너가 inline-size 조건을 만족하거나, 혹은 해당 style 조건을 만족하는 컨테이너가 있는 경우 적용됩니다.

여러 컨테이너를 쿼리하면서 모든 조건을 충족해야 한다면, 여러 쿼리를 중첩해야 합니다:

@container card (inline-size > 30em) {
  @container style(--responsive: true) {
  /* styles */
  }
}

위 스타일은 "card"라는 이름의 조상 컨테이너가 inline-size 조건을 만족하고, 조상 컨테이너 중 하나가 style 조건을 만족해야만 적용됩니다.

전역 이름 정의 at-rule (예: @keyframes, @font-face, @layer 등)이 컨테이너 쿼리 내부에 정의되더라도, 컨테이너 쿼리 조건에 의해 제한되지 않습니다.

5.5. 애니메이션 컨테이너

컨테이너 쿼리의 평가 결과가 변하면, 그 변화는 스타일 변경 이벤트의 일부가 되어야 하며, 이 변화가 애니메이션 효과로 인해 발생했더라도 마찬가지입니다.

형제 요소에 대한 트랜지션이 컨테이너의 크기에 간접적으로 영향을 주어, 컨테이너 쿼리의 평가 결과가 바뀌는 순간마다 스타일 변경 이벤트가 발생하는 예시:
main {
  display: flex;
  width: 300px;
}

#container {
  container-type: inline-size;
  flex: 1;
}

/* Resolved width is initially 200px, but changes as the transition
   on #sibling progresses. */
#inner {
  transition: 1s background-color;
  background-color: tomato;
}

/* When this container query starts (or stops) applying, a transition
   must start on background-color on #inner. */
@container (width <= 150px) {
  #inner {
  background-color: skyblue;
  }
}

#sibling {
  width: 100px;
  transition: width 1s;
}

#sibling:hover {
  width: 200px;
}
<main>
  <div id=container>
  <div id=inner>Inner</div>
  </div>
  <div id=sibling>Sibling</div>
</main>

계산값컨테이너 쿼리 길이 단위로 인해 변경될 때도 반드시 스타일 변경 이벤트의 일부가 되어야 합니다.

6. 컨테이너 기능

컨테이너 기능쿼리 컨테이너의 특정 속성을 질의합니다.

컨테이너 기능미디어 기능과 동일한 규칙으로 불리언 문맥에서 평가됩니다.

6.1. 사이즈 컨테이너 기능

컨테이너 크기 쿼리쿼리 컨테이너주 박스(principal box)의 크기를 질의할 수 있도록 해줍니다. 이는 개별 사이즈 기능 (<size-feature>) 들의 불리언 조합이며, 각각은 쿼리 컨테이너의 하나의 특정 치수 속성을 질의합니다. <size-feature>의 문법은 미디어 기능과 동일합니다: 기능명, 비교 연산자, 그리고 값의 형태입니다. [mediaqueries-5] 불리언 문법과 사이즈 기능크기 쿼리로 조합하는 논리는 CSS 기능 쿼리와 동일합니다. (@supports 참고. [css-conditional-3])

테스트

쿼리 컨테이너주 박스가 없거나, 주 박스가 레이아웃 컨테인먼트 박스가 아니거나, 쿼리 컨테이너가 해당 축에서 컨테이너 크기 쿼리를 지원하지 않으면, 사이즈 기능의 평가 결과는 unknown입니다.

상대 길이 단위 (컨테이너 쿼리 길이 단위 포함) 및 커스텀 속성컨테이너 쿼리 조건 내에서 계산값쿼리 컨테이너 기준으로 평가합니다.

트리 카운팅 함수(CSS Values 5 § 9 Tree Counting Functions: sibling-count() 및 sibling-index() 표기)는 컨테이너 요소를 기준으로 평가됩니다.

참고: 이것은 미디어 쿼리에서의 상대 단위 처리와 다릅니다.

참고: 커스텀 속성 치환 결과가 사이즈 기능에 대해 잘못된 값이라면, 다른 잘못된 기능 값과 동일하게 처리되며, 해당 사이즈 기능의 결과는 unknown이 됩니다.

예를 들어, 서로 다른 font-size를 가진 쿼리 컨테이너em 기반 쿼리를 각자의 font-size 기준으로 평가합니다:
aside, main {
  container-type: inline-size;
}

aside { font-size: 16px; }
main { font-size: 24px; }

@container (width > 40em) {
  h2 { font-size: 1.5em; }
}

쿼리 조건에 사용된 40em 값은 해당 계산값 기준의 font-size에 대해 관련 쿼리 컨테이너를 기준으로 합니다:

이와 유사하게, 쿼리 컨테이너var() 기반 쿼리를 각자의 커스텀 속성의 계산값 기준으로 평가합니다:
aside, main {
  container-type: inline-size;
}

aside { --query: 300px; }
main { --query: 500px; }

@container (width > var(--query)) {
  h2 { font-size: 1.5em; }
}

쿼리 조건에 사용된 var(--query) 값은 관련 쿼리 컨테이너--query 커스텀 속성 계산값으로 치환됩니다:

6.1.1. 너비: width 기능

이름: width
대상: @container
값: <length>
유형: range

width 컨테이너 기능너비쿼리 컨테이너content box 기준으로 질의합니다.

6.1.2. 높이: height 기능

이름: height
대상: @container
값: <length>
유형: range

height 컨테이너 기능높이쿼리 컨테이너content box 기준으로 질의합니다.

6.1.3. 인라인-사이즈: inline-size 기능

이름: inline-size
대상: @container
값: <length>
유형: range

inline-size 컨테이너 기능사이즈쿼리 컨테이너content box쿼리 컨테이너인라인 축 기준으로 질의합니다.

6.1.4. 블록-사이즈: block-size 기능

이름: block-size
대상: @container
값: <length>
유형: range

block-size 컨테이너 기능사이즈쿼리 컨테이너content box쿼리 컨테이너블록 축 기준으로 질의합니다.

6.1.5. 종횡비: aspect-ratio 기능

이름: aspect-ratio
대상: @container
값: <ratio>
유형: range

aspect-ratio 컨테이너 기능width 컨테이너 기능 값을 height 컨테이너 기능 값으로 나눈 비율로 정의됩니다.

6.1.6. 방향: orientation 기능

이름: orientation
대상: @container
값: portrait | landscape
유형: discrete
portrait
orientation 컨테이너 기능portrait로, height 컨테이너 기능의 값이 width 컨테이너 기능의 값보다 크거나 같은 경우입니다.
landscape
그 외의 경우 orientationlandscape입니다.

6.2. 스타일 컨테이너 기능

컨테이너 스타일 쿼리쿼리 컨테이너의 계산값을 질의할 수 있게 해줍니다. 이는 개별 스타일 기능 (<style-feature>)의 불리언 조합이며, 각각은 쿼리 컨테이너의 하나의 특정 속성을 질의합니다. <style-feature>의 문법은 유효한 선언[CSS-SYNTAX-3]이나, <style-feature-name> 또는 유효한 스타일 범위(<style-range>)와 동일합니다. <style-feature-name>지원되는 CSS 속성이거나 유효한 <custom-property-name>일 수 있습니다. <style-feature-value><declaration-value>에 맞는 어떤 값도 허용하지만, <mf-lt>, <mf-gt> 그리고 <mf-eq> 토큰은 포함할 수 없습니다.

테스트

<style-feature-plain>쿼리 컨테이너에서 주어진 속성의 계산값이 (해당 쿼리 컨테이너 기준으로 계산된) 지정된 값과 일치하면 true, 그렇지 않으면 false로 평가됩니다.

값이 없는 스타일 기능 (<style-feature-boolean>)은 해당 계산값초깃값과 다를 경우 true가 됩니다.

<style-range> 평가를 위해서는 다음 단계가 필요합니다:
  1. <style-range-value><custom-property-name>이면, <custom-property-name>var()로 감싼 것처럼 치환해야 합니다.

  2. 임의 치환 함수<style-range-value> 내에서 치환합니다.

  3. <style-range-value><number>, <percentage>, <length>, <angle>, <time>, <frequency> 또는 <resolution>로 파싱합니다. 파싱이 안 되면 false로 평가합니다.

  4. 범위의 각 <style-range-value>가 동일한 타입이면, 각각을 계산하고 비교 평가합니다. 단위 없는 0은 <length>와 비교 시 0-<length>로 처리합니다.

  5. 그 외의 경우 false로 평가합니다.

불리언 문법과 논리로 스타일 기능스타일 쿼리로 조합하는 것은 CSS 기능 쿼리와 동일합니다. (@supports 참고. [css-conditional-3])

스타일 기능약식 속성(shorthand property)을 질의하는 경우, 모든 롱핸드 속성(longhand property)계산값이 일치하면 true, 그렇지 않으면 false입니다.

캐스케이드 의존 키워드(예: revert, revert-layer)는 스타일 기능에서 값으로 사용할 수 없으며, 컨테이너 스타일 쿼리를 false로 만듭니다.

참고: 나머지 비-캐스케이드-의존 CSS-와이드 키워드쿼리 컨테이너 기준으로 다른 값과 마찬가지로 계산됩니다.

6.3. 스크롤 상태 컨테이너 기능

컨테이너 스크롤 상태 쿼리는 스크롤 위치에 따라 달라지는 상태를 컨테이너에서 질의할 수 있도록 합니다. 이는 각 스크롤 상태 기능 (<scroll-state-feature>)을 불리언으로 조합한 것이며, 각각은 쿼리 컨테이너의 단일 기능을 질의합니다. <scroll-state-feature>의 문법은 미디어 기능과 동일하며, 기능 이름, 비교자, 값으로 이루어집니다.

스크롤 상태 기능은 스크롤러 자체의 상태에 일치할 수도 있고, 조상 스크롤 컨테이너스크롤포트의 스크롤 위치에 의해 영향을 받는 요소의 상태에 일치할 수도 있습니다. 전자의 예는 scrollable 기능이며, 후자의 예는 snapped입니다.

6.3.1. 스크롤 상태 업데이트

스크롤 상태는, 질의된 스크롤 상태가 스타일 변화를 유발하고, 그 결과 레이아웃에 의해 스크롤 상태가 다시 변할 수 있기 때문에, 레이아웃 사이클을 야기할 수 있습니다.

이러한 레이아웃 사이클을 방지하기 위해, scroll-state 쿼리 컨테이너스냅샷 post-layout 상태 단계 실행의 일부로 현재 상태를 업데이트하며, 이 단계는 HTML 이벤트 루프 처리 모델의 특정 지점에서만 실행됩니다.

스냅샷 post-layout 상태 단계 실행이 요청되면, 모든 scroll-state 쿼리 컨테이너의 현재 상태를 업데이트합니다. 이렇게 스냅샷된 상태는 이 단계가 다음에 실행될 때까지 이루어지는 모든 스타일 및 레이아웃 업데이트에 사용됩니다.

6.3.2. 스티키 포지셔닝: stuck 기능

Name: stuck
For: @container
Value: none | top | right | bottom | left | block-start | inline-start | block-end | inline-end
Type: discrete
Tests

stuck 컨테이너 기능sticky 포지션이 적용된 컨테이너가, 주어진 edge에 대해 sticky 뷰 사각형 안에 머물도록 시각적으로 이동되었는지를 질의합니다. 논리적 edge는 쿼리 컨테이너의 direction 및 writing-mode에 따라 물리적 edge로 매핑됩니다. 쿼리 컨테이너sticky 포지션이 아니면 어떤 값도 일치하지 않습니다.

서로 다른 축에 속한 두 값은 동시에 일치할 수 있으나, 동일한 축의 반대쪽 edge가 동시에 일치하는 일은 없습니다.

일치할 수 있음:
@container scroll-state((stuck: top) and (stuck: left)) { ... }

절대 일치하지 않음:

@container scroll-state((stuck: left) and (stuck: right)) { ... }
none
sticky 컨테이너는 어떤 방향으로도 이동되지 않았습니다.
top
sticky 컨테이너가 위쪽 edge 안에 있도록 이동되었습니다.
right
sticky 컨테이너가 오른쪽 edge 안에 있도록 이동되었습니다.
bottom
sticky 컨테이너가 아래쪽 edge 안에 있도록 이동되었습니다.
left
sticky 컨테이너가 왼쪽 edge 안에 있도록 이동되었습니다.
block-start
sticky 컨테이너가 block-start edge 안에 있도록 이동되었습니다.
inline-start
sticky 컨테이너가 inline-start edge 안에 있도록 이동되었습니다.
block-end
sticky 컨테이너가 block-end edge 안에 있도록 이동되었습니다.
inline-end
sticky 컨테이너가 inline-end edge 안에 있도록 이동되었습니다.

6.3.3. 스크롤 스냅: snapped 기능

Name: snapped
For: @container
Value: none | x | y | block | inline | both
Type: discrete
Tests

snapped 컨테이너 기능snap target이 주어진 축에서 자신의 스크롤 스냅 컨테이너에 스냅되어 있거나 스냅될 것인지를 질의합니다. 즉, scrollsnapchanging 이벤트가 발생하는 모든 snap target과 일치합니다.

none
쿼리 컨테이너snap target이 아닙니다.
x
snapped 컨테이너 기능은, 쿼리 컨테이너가 자신의 snap target이며 수평 방향일 때 x와 일치합니다. 그 대상 스크롤 컨테이너는 scroll container입니다.
y
snapped 컨테이너 기능은, y와 일치하며, 쿼리 컨테이너가 자신의 snap target이고 수직 방향일 때 해당합니다. 대상 스크롤 컨테이너는 scroll container입니다.
block
snapped 컨테이너 기능block과 일치하며, 쿼리 컨테이너가 자신의 snap target이고 scroll container의 block 방향에서 해당합니다. 또한 이는 scroll snap container의 block 방향을 가리킵니다.
inline
snapped 컨테이너 기능inline과 일치하며, 쿼리 컨테이너가 자신의 snap target이고 scroll container의 inline 방향에서 해당합니다. 이는 scroll snap container의 inline 방향을 의미합니다.
both
snapped 컨테이너 기능both와 일치하며, 쿼리 컨테이너가 자신의 snap target이고 scroll container의 양 방향에서 해당합니다. 이는 scroll snap container의 두 방향 모두를 의미합니다.

6.3.4. 스크롤 가능: scrollable 기능

Name: scrollable
For: @container
Value: none | top | right | bottom | left | block-start | inline-start | block-end | inline-end | x | y | block | inline
Type: discrete
Tests

scrollable 컨테이너 기능스크롤 컨테이너가, 사용자에 의해 시작된 스크롤 동작으로 접근 가능한, 주어진 방향의 잘린 스크롤 가능 오버플로우 사각형 콘텐츠를 가지는지를 질의합니다. 즉, scrollablehidden 컨테이너나, 음수 스크롤 가능 오버플로우 영역에는 일치하지 않습니다.

논리 값들은 쿼리 컨테이너의 direction 및 writing-mode에 따라 물리적 값으로 매핑됩니다. 컨테이너가 스크롤 컨테이너가 아니면 어떤 값도 일치하지 않습니다.

none
스크롤 컨테이너는 어떤 방향으로도 스크롤 가능 오버플로우가 없습니다.
top
스크롤 컨테이너는 위쪽 edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
right
스크롤 컨테이너는 오른쪽 edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
bottom
스크롤 컨테이너는 아래쪽 edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
left
스크롤 컨테이너는 왼쪽 edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
block-start
스크롤 컨테이너block-start edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
inline-start
스크롤 컨테이너inline-start edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
block-end
스크롤 컨테이너block-end edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
inline-end
스크롤 컨테이너inline-end edge를 넘어서는 스크롤 가능 오버플로우가 있습니다.
x
스크롤 컨테이너는 수평 방향의 스크롤 가능 오버플로우를 가집니다.
y
스크롤 컨테이너는 수직 방향의 스크롤 가능 오버플로우를 가집니다.
block
스크롤 컨테이너는 자신의 block 방향으로 스크롤 가능 오버플로우를 가집니다.
inline
스크롤 컨테이너는 자신의 inline 방향으로 스크롤 가능 오버플로우를 가집니다.

6.3.5. 스크롤됨: scrolled 기능

Name: scrolled
For: @container
Value: none | top | right | bottom | left | block-start | inline-start | block-end | inline-end | x | y | block | inline
Type: discrete
Tests

쿼리 컨테이너스크롤 컨테이너인 경우, scrolled 컨테이너 기능은 가장 최근의 상대 스크롤(relative scroll)의 방향을 질의합니다. 논리 값은 쿼리 컨테이너의 direction 및 writing-mode에 따라 물리적으로 매핑됩니다. 컨테이너가 스크롤 컨테이너가 아니면 어떤 값도 일치하지 않습니다.

none
쿼리 컨테이너에서는 아직 상대 스크롤이 발생하지 않았습니다.
top
가장 최근의 상대 스크롤이 위쪽으로 일어났습니다.
right
가장 최근의 상대 스크롤이 오른쪽으로 일어났습니다.
bottom
가장 최근의 상대 스크롤이 아래쪽으로 일어났습니다.
left
가장 최근의 상대 스크롤이 왼쪽으로 일어났습니다.
block-start
가장 최근의 상대 스크롤block-start 방향으로 일어났습니다.
inline-start
가장 최근의 상대 스크롤inline-start 방향으로 일어났습니다.
block-end
가장 최근의 상대 스크롤block-end 방향으로 일어났습니다.
inline-end
가장 최근의 상대 스크롤inline-end 방향으로 일어났습니다.
x
가장 최근의 상대 스크롤이 수평 방향으로 일어났습니다.
y
가장 최근의 상대 스크롤이 수직 방향으로 일어났습니다.
block
가장 최근의 상대 스크롤이 block 방향으로 일어났습니다.
inline
가장 최근의 상대 스크롤이 inline 방향으로 일어났습니다.

7. 컨테이너 상대 길이: cqw, cqh, cqi, cqb, cqmin, cqmax 단위

컨테이너 쿼리 길이 단위쿼리 컨테이너의 크기에 상대적인 길이를 지정합니다. 컨테이너 쿼리 길이 단위를 사용하는 스타일 시트는 하나의 쿼리 컨테이너에서 다른 컨테이너로 컴포넌트를 더 쉽게 옮길 수 있습니다.

컨테이너 쿼리 길이 단위는 다음과 같습니다:

컨테이너 단위 요약 정보
단위 기준
cqw 쿼리 컨테이너너비의 1%
cqh 쿼리 컨테이너높이의 1%
cqi 쿼리 컨테이너인라인 크기의 1%
cqb 쿼리 컨테이너블록 크기의 1%
cqmin cqi 또는 cqb 중 더 작은 값
cqmax cqi 또는 cqb 중 더 큰 값
테스트

각 요소에 대해 컨테이너 쿼리 길이 단위는 해당 단위로 설명되는 축(또는 축들)에 대해 컨테이너 크기 쿼리로 평가됩니다. 각 축의 쿼리 컨테이너는 해당 축에서 컨테이너 크기 쿼리를 허용하는 가장 가까운 상위 컨테이너입니다. 사용 가능한 쿼리 컨테이너가 없다면, 해당 축에 대해 작은 뷰포트 크기를 사용합니다.

참고: 어떤 경우에는 동일한 요소에서 cqicqb 단위가 서로 다른 쿼리 컨테이너를 기준으로 평가될 수 있습니다. 마찬가지로 cqmincqmax 단위는 cqicqb 단위 중 큰 값 또는 작은 값을 나타내며, 이 때 해당 크기가 서로 다른 쿼리 컨테이너에서 올 수 있습니다.

자식 요소는 부모에 대해 지정된 상대값을 상속하지 않고, 계산된 값을 상속합니다.

작성자는 컨테이너 쿼리 길이 단위가 적절한 쿼리 컨테이너를 갖도록, 동일한 container-type에 의존하는 컨테이너 쿼리 내부에 적용할 수 있습니다. 사용자 지정 대체값은 컨테이너 쿼리 외부에서 정의할 수 있습니다:
/* 대체값은 containment에 의존하지 않습니다 */
h2 { font-size: 1.2em; }

@container (inline-size >= 0px) {
  /* 인라인 크기 컨테이너가 있을 때만 적용 */
  h2 { font-size: calc(1.2em + 1cqi); }
}

8. 사용자 정의 지원 쿼리 정의: @supports-condition 규칙

@supports-condition at-rule은 작성자가 나중에 재사용할 수 있도록 supports 쿼리를 정의하고 이름을 지정할 수 있게 해주는 조건부 그룹 규칙입니다. 이를 통해 복잡하거나 자주 사용하는 기능 쿼리를 이름으로 참조할 수 있어, 유지보수성과 가독성이 향상됩니다.

@supports-condition <supports-condition-name> {
  <block-contents>
}
테스트

여기서 <supports-condition-name><extension-name>으로, supports 쿼리의 이름을 정의합니다.

블록 내부의 모든 내용은 사용자 에이전트가 사용된 기능을 지원하는지 테스트하기 위해 평가됩니다. 이 내용은 문서 렌더링에는 영향을 주지 않습니다.

한 번 정의된 named supports 조건은 이후 @supports 또는 @when 조건에서 사용할 수 있습니다.

동일한 이름으로 여러 @supports-condition 규칙이 정의된 경우, 문서 순서상 마지막 규칙이 적용되며 그 이전 것은 모두 무시됩니다.

예를 들어, 여러 속성을 한 번에 검사하는 supports 쿼리를 정의할 수 있습니다:
@supports-condition --thicker-underlines {
  text-decoration-thickness: 0.2em;
  text-underline-offset: 0.3em;
}

/* (text-decoration-thickness: 0.2em) 및 (text-underline-offset: 0.3em)과 동일 */
@supports (--thicker-underlines) {
  a {
    text-decoration: underline;
    text-decoration-thickness: 0.2em;
    text-underline-offset: 0.3em;
  }
}

@supports-condition 규칙은 @import@namespace 규칙 앞에 올 수 있습니다 (@charset 규칙(있다면) 다음).

지원 쿼리는 임의의 선언을 포함할 수 있으므로, 중첩 등 복잡한 기능 지원을 감지하는 데 사용할 수 있습니다:
@supports-condition --nesting {
  & { }
}

@import url("nested-styles.css") supports(--nesting);
지원 쿼리는 at-rule 지원 여부 감지에도 사용할 수 있습니다:
@supports-condition --stuck-container-feature {
  @container scroll-state(stuck: top) { }
}

@supports (--stuck-container-feature) {
  div { border-color: navy; }
}

at-rule의 이름은 논의 중입니다. 대안으로 @supports-query, @supports-test, @custom-supports 등이 있습니다. 이 이름은 사용자 정의 미디어 쿼리의 명명과 일관되어야 합니다.

9. API

9.1. CSSContainerRule 인터페이스

CSSContainerRule 인터페이스는 @container 규칙을 나타냅니다.

[Exposed=Window]
interface CSSContainerRule : CSSConditionRule {
  readonly attribute CSSOMString containerName;
  readonly attribute CSSOMString containerQuery;
};
conditionText 타입 CSSOMString (CSSContainerRule 전용, CSSConditionRule 속성에 대한 정의)
conditionText 속성(CSSConditionRule 상위 규칙에서 정의됨)은, 조회 시 다음과 같은 값을 반환해야 합니다:
@container 규칙에 <container-name>이 연관된 경우
containerNamecontainerQuery 속성 값을 공백 하나로 이어 붙인 결과입니다.
그 외의 경우
containerQuery 속성 값을 반환합니다.
containerName 타입 CSSOMString
containerName 속성 조회 시, 다음과 같은 값을 반환해야 합니다:
@container 규칙에 <container-name>이 연관된 경우
해당 <container-name>의 직렬화 결과입니다.
그 외의 경우
빈 문자열입니다.
containerQuery 타입 CSSOMString
containerQuery 속성은, 지정된 <container-query>를 논리적 단순화 없이 반환해야 하며, 반환된 쿼리는 이 명세의 모든 호환 구현에서(향후 확장 포함) 지정된 쿼리와 동일한 결과로 평가되어야 합니다. 즉, 토큰 스트림 단순화(공백 하나로 축소, 선택적으로 생략 등)는 허용되지만, 논리적 단순화(불필요한 괄호 제거, 결과 평가 기반 단순화 등)는 허용되지 않습니다.

컨테이너 쿼리는 matchContainer 메서드를 가져야 합니다. 이 메서드는 matchMedia()MediaQueryList 인터페이스를 모델로 하되, Window가 아닌 Element에 적용됩니다. 레이아웃 크기 측정 시 resizeObserver와 유사하게 동작하지만, 추가적인 컨테이너 쿼리 구문 및 기능을 제공합니다. [이슈 #6205]

9.2. CSSSupportsConditionRule 인터페이스

CSSSupportsConditionRule 인터페이스는 @supports-condition 규칙을 나타냅니다.

[Exposed=Window]
interface CSSSupportsConditionRule : CSSGroupingRule {
  readonly attribute CSSOMString name;
};
name 타입 CSSOMString
이 속성은 named supports condition의 이름입니다.

보안 고려사항

이 문서에 대해 제기된 보안 이슈는 없습니다.

프라이버시 고려사항

font-tech()font-format() 함수는 사용자의 소프트웨어에 대한 정보(버전, 특정 기능 활성화/비활성화 등)를 제공할 수 있습니다.

이 정보는 다른 API를 통해서도 파악할 수 있습니다. 하지만, 본 명세의 기능들은 이 정보가 웹에서 노출되는 여러 방법 중 하나입니다.

이 정보는 집계될 경우 사용자의 핑거프린팅 정확도를 높이는 데 사용될 수 있습니다.

변경사항

2024년 11월 5일 Working Draft 이후 변경사항

2024년 7월 23일 Working Draft 이후 변경사항

2021년 12월 21일 최초 Working Draft 이후 변경사항

Level 4 이후 추가사항

감사의 글

@when@else 규칙은 Tab Atkins의 제안에 기반합니다.

다음 사람들의 의견과 선행 작업에 감사드립니다: Adam Argyle, Amelia Bellamy-Royds, Anders Hartvoll Ruud, Brian Kardell, Chris Coyier, Christopher Kirk-Nielsen, David Herron, Eric Portis, Ethan Marcotte, Florian Rivoal, Geoff Graham, Gregory Wild-Smith, Ian Kilpatrick, Jen Simmons, Kenneth Rohde Christiansen, Lea Verou, Martin Auswöger, Martine Dowden, Mike Riethmuller, Morten Stenshorne, Nicole Sullivan, Rune Lillesveen, Scott Jehl Scott Kellum, Stacy Kvernmo, Theresa O’Connor, Una Kravets, 그리고 많은 분들이 본 명세에 기여해 주셨습니다.

적합성

문서 관례

적합성 요구사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. 본 문서의 규범적인 부분에서 “MUST”(반드시), “MUST NOT”(반드시 ~하지 않아야 함), “REQUIRED”(필수), “SHALL”(해야 한다), “SHALL NOT”(하지 않아야 한다), “SHOULD”(권장), “SHOULD NOT”(권장하지 않음), “RECOMMENDED”(추천), “MAY”(허용), “OPTIONAL”(선택 사항) 등의 주요 용어는 RFC 2119에 설명된 대로 해석되어야 합니다. 다만, 가독성을 위해 본 명세에서는 해당 단어들을 모두 대문자로 표기하지 않습니다.

명시적으로 비규범으로 표시된 섹션, 예제, 참고를 제외하고 본 명세의 모든 텍스트는 규범적입니다. [RFC2119]

본 명세의 예제는 “예를 들어”라는 말로 도입하거나, class="example"와 같이 규범 텍스트와 구분하여 제시합니다:

이것은 참고용 예제의 예시입니다.

참고 문구는 “참고”라는 단어로 시작하며, class="note"로 규범 텍스트와 구분됩니다:

참고, 이것은 참고용 노트입니다.

권고(advisement)는 특별한 주의를 환기하도록 스타일링된 규범적 섹션이며, <strong class="advisement">로 다른 규범 텍스트와 구분됩니다: UA는 반드시 접근 가능한 대안을 제공해야 합니다.

테스트

이 명세의 내용과 관련된 테스트는 이와 같은 “테스트” 블록에 기록될 수 있습니다. 이러한 블록은 모두 비규범적입니다.


적합성 클래스

본 명세에 대한 적합성은 세 가지 적합성 클래스로 정의됩니다:

스타일 시트
CSS 스타일 시트.
렌더러
스타일 시트의 의미를 해석하고 이를 사용하는 문서를 렌더링하는 UA.
저작 도구
스타일 시트를 작성하는 UA.

스타일 시트가 본 명세에 적합하려면, 이 모듈에서 정의된 문법을 사용하는 모든 구문이 일반 CSS 문법과 이 모듈에서 정의된 각 기능의 개별 문법에 따라 유효해야 합니다.

렌더러가 본 명세에 적합하려면, 해당 스타일 시트를 적절한 명세에 따라 해석하는 것 외에도, 본 명세에서 정의된 모든 기능을 올바르게 파싱하고 이에 따라 문서를 렌더링함으로써 지원해야 합니다. 단, 장치의 한계로 인해 UA가 문서를 올바르게 렌더링하지 못하더라도, 그것이 UA의 비적합성을 의미하지는 않습니다. (예: UA는 흑백 모니터에서 색상을 렌더링할 필요는 없습니다.)

저작 도구가 본 명세에 적합하려면, 일반 CSS 문법과 이 모듈 내 각 기능의 개별 문법에 따라 문법적으로 올바른 스타일 시트를 작성해야 하며, 이 모듈에서 설명한 스타일 시트의 모든 다른 적합성 요구사항도 충족해야 합니다.

부분 구현

작성자가 미래 호환 파싱 규칙을 활용하여 대체값을 지정할 수 있도록, CSS 렌더러는 사용 가능한 수준의 지원이 없는 at-rule, 속성, 속성값, 키워드 및 기타 구문 구조를 무효로 처리(적절히 무시)해야 합니다. 특히, 사용자 에이전트는 여러 값이 선언된 속성 선언에서 지원되지 않는 구성요소 값만 선택적으로 무시하고 지원되는 값만 적용해서는 안 됩니다: 어떤 값이 무효(지원되지 않음)로 간주되면, CSS는 전체 선언을 무시하도록 요구합니다.

불안정 및 독점 기능의 구현

향후 안정적인 CSS 기능과의 충돌을 피하기 위해, CSSWG는 베스트 프랙티스에 따라 불안정 기능 및 독점 확장을 구현할 것을 권고합니다.

비실험적 구현

명세가 후보 권고(Candidate Recommendation) 단계에 도달하면, 비실험적 구현이 가능하며, 구현자는 명세에 맞게 올바르게 구현되었음을 입증할 수 있는 CR 레벨 기능의 비접두사(언프리픽스) 구현을 공개해야 합니다.

CSS의 각 구현 간 상호 운용성을 확립·유지하기 위해 CSS 워킹 그룹은 비실험적 CSS 렌더러가 어떤 CSS 기능의 비접두사 구현을 공개하기 전에 구현 보고서(필요한 경우 해당 테스트 케이스 포함)를 W3C에 제출할 것을 요청합니다. W3C에 제출된 테스트 케이스는 CSS 워킹 그룹에서 검토 및 수정될 수 있습니다.

테스트 케이스 및 구현 보고서 제출에 대한 추가 정보는 CSS 워킹 그룹 웹사이트 https://www.w3.org/Style/CSS/Test/에서 확인할 수 있습니다. 문의는 public-css-testsuite@w3.org 메일링 리스트로 하면 됩니다.

색인

이 명세에서 정의된 용어

참조에 의해 정의된 용어

참고 문헌

규범적 참고문헌

[CSS-ANIMATIONS-1]
David Baron; 외. CSS Animations Level 1. 2023년 3월 2일. WD. URL: https://www.w3.org/TR/css-animations-1/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 2024년 8월 4일. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-CASCADE-4]
Elika Etemad; Tab Atkins Jr.. CSS Cascading and Inheritance Level 4. 2022년 1월 13일. CR. URL: https://www.w3.org/TR/css-cascade-4/
[CSS-CASCADE-5]
Elika Etemad; Miriam Suzanne; Tab Atkins Jr.. CSS Cascading and Inheritance Level 5. 2022년 1월 13일. CR. URL: https://www.w3.org/TR/css-cascade-5/
[CSS-CONDITIONAL-3]
Chris Lilley; David Baron; Elika Etemad. CSS Conditional Rules Module Level 3. 2024년 8월 15일. CRD. URL: https://www.w3.org/TR/css-conditional-3/
[CSS-CONDITIONAL-4]
Chris Lilley; David Baron; Elika Etemad. CSS Conditional Rules Module Level 4. 2025년 9월 4일. CRD. URL: https://www.w3.org/TR/css-conditional-4/
[CSS-CONTAIN-2]
Tab Atkins Jr.; Florian Rivoal; Vladimir Levin. CSS Containment Module Level 2. 2022년 9월 17일. WD. URL: https://www.w3.org/TR/css-contain-2/
[CSS-CONTAIN-3]
Tab Atkins Jr.; Florian Rivoal; Miriam Suzanne. CSS Containment Module Level 3. 2022년 8월 18일. WD. URL: https://www.w3.org/TR/css-contain-3/
[CSS-DISPLAY-4]
Elika Etemad; Tab Atkins Jr.. CSS Display Module Level 4. 2024년 12월 19일. FPWD. URL: https://www.w3.org/TR/css-display-4/
[CSS-EXTENSIONS-1]
CSS Extensions Module Level 1. Editor's Draft. URL: https://drafts.csswg.org/css-extensions-1/
[CSS-FONTS-4]
Chris Lilley. CSS Fonts Module Level 4. 2024년 2월 1일. WD. URL: https://www.w3.org/TR/css-fonts-4/
[CSS-FONTS-5]
Chris Lilley. CSS Fonts Module Level 5. 2024년 2월 6일. WD. URL: https://www.w3.org/TR/css-fonts-5/
[CSS-NAMESPACES-3]
Elika Etemad. CSS Namespaces Module Level 3. 2014년 3월 20일. REC. URL: https://www.w3.org/TR/css-namespaces-3/
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2025년 10월 7일. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. 2025년 10월 7일. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-SCOPING-1]
Tab Atkins Jr.; Elika Etemad. CSS Scoping Module Level 1. 2014년 4월 3일. FPWD. URL: https://www.w3.org/TR/css-scoping-1/
[CSS-SCROLL-SNAP-1]
Matt Rakow; 외. CSS Scroll Snap Module Level 1. 2021년 3월 11일. CR. URL: https://www.w3.org/TR/css-scroll-snap-1/
[CSS-SCROLL-SNAP-2]
Elika Etemad; Tab Atkins Jr.; Adam Argyle. CSS Scroll Snap Module Level 2. 2024년 7월 23일. FPWD. URL: https://www.w3.org/TR/css-scroll-snap-2/
[CSS-SHADOW-PARTS-1]
Tab Atkins Jr.; Fergal Daly. CSS Shadow Parts. 2018년 11월 15일. FPWD. URL: https://www.w3.org/TR/css-shadow-parts-1/
[CSS-SIZING-3]
Tab Atkins Jr.; Elika Etemad. CSS Box Sizing Module Level 3. 2021년 12월 17일. WD. URL: https://www.w3.org/TR/css-sizing-3/
[CSS-SYNTAX-3]
Tab Atkins Jr.; Simon Sapin. CSS Syntax Module Level 3. 2021년 12월 24일. CRD. URL: https://www.w3.org/TR/css-syntax-3/
[CSS-TRANSITIONS-1]
David Baron; 외. CSS Transitions. 2018년 10월 11일. WD. URL: https://www.w3.org/TR/css-transitions-1/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2024년 3월 12일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-VALUES-5]
Tab Atkins Jr.; Elika Etemad; Miriam Suzanne. CSS Values and Units Module Level 5. 2024년 11월 11일. WD. URL: https://www.w3.org/TR/css-values-5/
[CSS-VARIABLES-1]
Tab Atkins Jr.. CSS Custom Properties for Cascading Variables Module Level 1. 2022년 6월 16일. CR. URL: https://www.w3.org/TR/css-variables-1/
[CSS-WRITING-MODES-4]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 4. 2019년 7월 30일. CR. URL: https://www.w3.org/TR/css-writing-modes-4/
[CSSOM-1]
Daniel Glazman; Emilio Cobos Álvarez. CSS Object Model (CSSOM). 2021년 8월 26일. WD. URL: https://www.w3.org/TR/cssom-1/
[CSSOM-VIEW-1]
Simon Fraser; Emilio Cobos Álvarez. CSSOM View Module. 2025년 9월 16일. WD. URL: https://www.w3.org/TR/cssom-view-1/
[MEDIAQUERIES-4]
Florian Rivoal; Tab Atkins Jr.. Media Queries Level 4. 2021년 12월 25일. CRD. URL: https://www.w3.org/TR/mediaqueries-4/
[MEDIAQUERIES-5]
Dean Jackson; 외. Media Queries Level 5. 2021년 12월 18일. WD. URL: https://www.w3.org/TR/mediaqueries-5/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[SELECTORS-4]
Elika Etemad; Tab Atkins Jr.. Selectors Level 4. 2022년 11월 11일. WD. URL: https://www.w3.org/TR/selectors-4/
[WEB-ANIMATIONS-1]
Brian Birtles; 외. Web Animations. 2023년 6월 5일. WD. URL: https://www.w3.org/TR/web-animations-1/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

참고용 참고문헌

[CSS-POSITION-4]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 4. 2025년 10월 7일. WD. URL: https://www.w3.org/TR/css-position-4/
[CSS-PSEUDO-4]
Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 2025년 6월 27일. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS2]
Bert Bos; 외. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS2/

속성 색인

이름 초기값 적용 대상 상속 %비율 애니메이션 유형 정규 순서 계산된 값
container <'container-name'> [ / <'container-type'> ]? 개별 속성 참조 개별 속성 참조 개별 속성 참조 개별 속성 참조 개별 속성 참조 문법에 따름 개별 속성 참조
container-name none | <custom-ident>+ none 모든 요소 아니오 n/a 애니메이션 불가 문법에 따름 키워드 none 또는 식별자 목록(순서 있음)
container-type normal | [ [ size | inline-size ] || scroll-state ] normal 모든 요소 아니오 n/a 애니메이션 불가 문법에 따름 지정된 키워드

@container 설명자

이름 초기값 유형
aspect-ratio <ratio> range
block-size <length> range
height <length> range
inline-size <length> range
orientation portrait | landscape discrete
scrollable none | top | right | bottom | left | block-start | inline-start | block-end | inline-end | x | y | block | inline discrete
scrolled none | top | right | bottom | left | block-start | inline-start | block-end | inline-end | x | y | block | inline discrete
snapped none | x | y | block | inline | both discrete
stuck none | top | right | bottom | left | block-start | inline-start | block-end | inline-end discrete
width <length> range

IDL 색인

[Exposed=Window]
interface CSSContainerRule : CSSConditionRule {
  readonly attribute CSSOMString containerName;
  readonly attribute CSSOMString containerQuery;
};

[Exposed=Window]
interface CSSSupportsConditionRule : CSSGroupingRule {
  readonly attribute CSSOMString name;
};

이슈 색인

현재 이 문서는 레벨 5에서 새롭게 추가된 내용의 초기 초안입니다. 레벨 3, 레벨 4의 기능은 여전히 [css-conditional-3][css-conditional-4] 에 정의되어 있으며 아직 이곳에 복사되지 않았습니다.
"boolean algebra, with X as leaves"를 Conditional에서 일반적으로 정의하여, 모든 조건부 규칙이 이를 직접 참조할 수 있도록 해야 합니다. 각자 boolean algebra를 다시 정의하지 않도록.
체인에서 마지막 @else만 조건을 생략할 수 있도록 요구해야 할까요? 코드를 디버깅할 때 조건문 체인 중 하나를 "true"로 설정해 단락시키는 경우가 드물지 않습니다; CSS에서도 비슷하게 유용할 것 같습니다. 조건을 실수로 빠뜨렸을 때 잘못된 작업을 했다는 것을 발견하기도 쉽습니다.
at-rule의 이름은 논의 중입니다. 대안으로 @supports-query, @supports-test, @custom-supports 등이 있습니다. 이 이름은 사용자 정의 미디어 쿼리의 명명과 일관되어야 합니다.
컨테이너 쿼리는 matchContainer 메서드를 가져야 합니다. 이 메서드는 matchMedia()MediaQueryList 인터페이스를 모델로 하되, Window가 아닌 Element에 적용됩니다. 레이아웃 크기 측정 시 resizeObserver와 유사하게 동작하지만, 추가적인 컨테이너 쿼리 구문 및 기능을 제공합니다. [Issue #6205]