CSS 포함 모듈 레벨 2

W3C 워킹 드래프트,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2022/WD-css-contain-2-20220917/
최신 공개 버전:
https://www.w3.org/TR/css-contain-2/
에디터스 드래프트:
https://drafts.csswg.org/css-contain-2/
이전 버전:
히스토리:
https://www.w3.org/standards/history/css-contain-2
테스트 스위트:
https://test.csswg.org/harness/results/css-contain-1_dev/
https://wpt.fyi/results/css/css-contain/
피드백:
CSSWG 이슈 저장소
에디터:
Tab Atkins (Google)
Florian Rivoal (Bloomberg를 대표하여)
(Google)
이 규격에 편집 제안:
GitHub 에디터

요약

이 CSS 모듈은 요소의 하위 트리가 페이지의 나머지 부분과 독립적임을 나타내는 contain 속성을 설명합니다. 이를 잘 활용하면 사용자 에이전트가 대규모 최적화를 수행할 수 있습니다.

CSS는 구조화된 문서(HTML 및 XML 등)의 렌더링을 화면, 종이 등에서 기술하기 위한 언어입니다.

이 문서의 상태

이 섹션은 발행 시점에서 이 문서의 상태를 설명합니다. 현재 W3C 발행물 목록과 이 기술 보고서의 최신 개정판은 https://www.w3.org/TR/의 W3C 기술 보고서 인덱스에서 확인할 수 있습니다.

이 문서는 CSS 워킹 그룹워킹 드래프트권고안 트랙을 사용하여 발행하였습니다. 워킹 드래프트로 발행되었다고 해서 W3C 및 회원의 승인됨을 의미하지 않습니다.

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

피드백은 GitHub 이슈 등록(권장)으로 보내주시고, 제목에 규격 코드 “css-contain”을 포함해 주세요. 예시: “[css-contain] …댓글 요약…”. 모든 이슈와 댓글은 아카이브에 저장됩니다. 또는 (아카이브됨) 공개 메일링 리스트 www-style@w3.org로도 피드백을 보낼 수 있습니다.

이 문서는 2021년 11월 2일 W3C 프로세스 문서에 따라 관리됩니다.

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

1. 소개

웹사이트를 효율적으로 렌더링하려면 사용자 에이전트가 페이지의 어떤 부분이 표시되고 있는지, 현재 표시 중인 영역에 영향을 줄 수 있는 부분이 무엇인지, 무시해도 되는 부분이 무엇인지 감지할 수 있어야 합니다.

서브트리가 페이지의 나머지와 어떤 방식으로든 독립적인지 추측하기 위한 다양한 휴리스틱이 있지만, 이는 불안정하여, 페이지에 사소한 변경만 있어도 휴리스틱 테스트에 실패할 수 있고, 그로 인해 렌더링이 느린 경로로 떨어질 수 있습니다. 또 휴리스틱 방식으로 감지하기 어렵거나 불가능한 격리해야 할 많은 사례들이 있습니다.

이러한 문제를 완화하고 페이지의 서브트리를 나머지와 강력하고 예측 가능하게 분리할 수 있도록, 이 명세는 contain 속성을 정의합니다.

화면에 보이지 않는 콘텐츠의 최적화를 더 강화하기 위해, 이 명세는 content-visibility 속성도 정의하며, 사용자 에이전트가 필요하지 않을 때 요소의 레이아웃 및 페인팅을 완전히 생략할 수 있게 합니다.

1.1. 모듈 상호작용

이 문서에서는 기존 명세에 없던 새로운 기능을 정의합니다. 또한, 안정화되면 [CSS-CONTAIN-1]을 대체하고 우선시하는 것을 목표로 합니다.

1.2. 값 정의

이 명세는 CSS 속성 정의 규칙[CSS2]값 정의 문법, [CSS-VALUES-3]을 따릅니다. 이 명세에서 정의되지 않은 값 타입은 CSS Values & Units [CSS-VALUES-3]에서 정의합니다. 다른 CSS 모듈과 조합하면 이러한 값 타입의 정의가 확장될 수 있습니다.

각 속성 정의에 명시된 값 외에도, 이 명세에서 정의된 모든 속성은 CSS 전체 키워드도 속성 값으로 허용합니다. 가독성을 위해 명시적으로 반복하지 않았습니다.

2. 강력한 포함: contain 속성

이름: contain
값: none | strict | content | [ size || layout || style || paint ]
초기값: none
적용 대상: 아래 참조
상속 여부: no
백분율: 해당 없음
계산된 값: 키워드 none 또는 size, layout, paint 중 하나 이상
정식 순서: 문법에 따름
애니메이션 타입: 애니메이션 불가

사용자 에이전트는 시각적이지 않은 미디어를 포함해 모든 미디어에서 이 속성을 지원해야 합니다.

contain 속성은 작성자가 요소와 그 내용을, 최대한 독립적으로 문서 트리의 다른 부분과 분리되어 있음을 나타낼 수 있게 합니다. 이를 통해 사용자 에이전트는 contain을 올바르게 사용할 경우 렌더링에 훨씬 강력한 최적화를 적용할 수 있으며, 작성자는 사소한 변경으로 느린 경로로 떨어지는 일이 없다는 확신을 가질 수 있습니다.

none
이 값은 속성이 아무 효과가 없음을 나타냅니다. 요소는 일반적으로 렌더링되며, 포함 효과는 적용되지 않습니다.
strict
이 값은 size layout paint style로 계산되며, 요소에 모든 포함을 활성화합니다.
content
이 값은 layout paint style로 계산되며, 요소에 포함크기 포함만 제외하고 모두 활성화합니다.

참고: contain: content는 폭넓게 적용해도 비교적 "안전"합니다; 실제로는 효과가 비교적 경미하며, 대부분의 콘텐츠는 제약에 걸리지 않습니다. 하지만 크기 포함이 적용되지 않으므로, 요소는 여전히 자식의 크기에 반응할 수 있고, 이로 인해 레이아웃 무효화가 트리 상위로 더 확산될 수 있습니다. 가능한 한 contain: strict을 사용하여 최대한 많은 포함을 얻으세요.

size
이 값은 요소에 크기 포함을 활성화합니다. 이를 통해 포함 박스는 자손을 검사하지 않고도 레이아웃될 수 있습니다.
layout
이 값은 요소에 레이아웃 포함을 활성화합니다. 이를 통해 포함 박스는 레이아웃상 완전히 불투명하게 되어, 외부가 내부 레이아웃에 영향을 주거나, 그 반대가 되는 일이 없습니다.
style
이 값은 요소에 스타일 포함을 활성화합니다. 이를 통해 여러 요소와 자손에 영향을 줄 수 있는 속성들이 해당 요소 밖으로 영향을 주지 않게 보장합니다.
paint
이 값은 요소에 페인트 포함을 활성화합니다. 이를 통해 포함 박스의 자손이 경계를 벗어나서 표시되지 않게 하며, 요소가 화면에서 벗어나거나 보이지 않을 경우, 자손도 확실히 보이지 않게 됩니다.

이 속성은 일반적으로 모든 요소(예: CSS Pseudo-Elements 4 § 4.1 생성 콘텐츠 의사 요소: ::before 및 ::after)에 적용되지만, 일부 포함 유형은 특정 요소에 아무 효과가 없을 수 있습니다. 자세한 내용은 § 3 포함 유형에서 설명합니다. 또한 [SVG2]의 경우, contain 속성은 svg 요소 중 CSS 레이아웃 박스가 있는 경우에만 적용됩니다.

contain은 페이지에 널리 사용할 때 유용합니다. 특히 페이지에 많은 "위젯"이 모두 독립적으로 있을 때 더욱 그렇습니다.

예를 들어, 마이크로포스트 SNS가 다음과 같은 마크업을 사용한다고 가정해봅시다:

<body>
  <aside>...</aside>
  <section>
    <h2>Messages</h2>
    <article>
      Lol, check out this dog: images.example.com/jsK3jkl
    </article>
    <article>
      I had a ham sandwich today. #goodtimes
    </article>
    <article>
      I have political opinions that you need to hear!
    </article></section>
</body>

아마도 사이트에는 많은 메시지가 표시되지만, 각각은 독립적이어서 다른 것에 영향을 주지 않습니다. 따라서 각 메시지에 contain: content를 지정하여 사용자 에이전트가 이를 인식하고, 화면에 보이지 않는 메시지의 계산을 생략해 페이지를 최적화할 수 있게 합니다. 각 메시지의 크기를 미리 알 수 있다면, contain: strict을 적용해 추가적인 제한을 알릴 수 있습니다.

또한, HTML의 html 또는 body 요소에 포함이 활성화되면, body 요소에서 초기 포함 블록, 뷰포트, 캔버스 배경으로 속성이 전파되지 않습니다. 특히, 다음에 영향을 미칩니다:

참고: 초기 포함 블록, 뷰포트, 캔버스 배경으로 html 요소에서 설정된 속성은 영향을 받지 않습니다.

참고: contain 외에도 다양한 포함을 활성화할 수 있는 속성이 존재합니다. 이들은 contain의 값에는 영향을 주지 않습니다; 예를 들어, contain: none이어도 레이아웃 포함content-visibility로 인해 활성화될 수 있습니다.

3. 포함의 유형

요소는 여러 종류의 포함을 적용받을 수 있으며, 이는 자손이 페이지의 나머지에 미칠 수 있는 영향을 다양한 방식으로 제한합니다. 포함은 사용자 에이전트가 훨씬 더 강력한 최적화를 할 수 있도록 하며, 작성자가 페이지를 기능 단위로 구성할 때, 특정 변경 사항이 문서 전체에 영향을 미치는 범위를 제한해줍니다.

새 속성이나 메커니즘을 도입하는 명세 작성자는 다양한 포함 유형이 자신이 도입하는 것에 어떤 영향을 미치는지 반드시 고려해야 하며, 여기서 설명되지 않은 영향이 있다면 명세에 반드시 포함해야 합니다.

3.1. 크기 포함

요소에 크기 포함을 주면, 해당 요소의 주 박스크기 포함 박스가 되며, 다음과 같은 효과가 있습니다:

  1. 내재적 크기크기 포함 박스에 대해 요소에 콘텐츠가 전혀 없는 것처럼 결정되며, 비어있는 것처럼 크기 계산과 동일한 논리를 따릅니다.

    참고: 이는 min-content 또는 max-content 키워드를 명시적으로 사용할 때나, 이를 기반으로 하는 모든 계산(예: 그리드 트랙에 크기 포함된 항목이 배치될 때, 또는 fit-content 크기로 포함 박스의 부모를 크기 지정할 때)에 영향을 줍니다.

  2. 크기 포함 박스와 그 콘텐츠의 레이아웃은 개념적으로 두 단계로 이루어집니다:

    비어있는 것처럼 크기 지정
    사용된 widthheight포함 박스에 대해 일반적인 레이아웃을 수행하는 것처럼 결정되지만, 콘텐츠가 전혀 없는 것으로 취급합니다— ::before, ::before, ::after, ::marker 같은 의사 요소조차 없는 것으로 간주합니다.

    치환 요소자연스러운 너비와 높이를 0으로, 자연스런 종횡비 역시 없는 것으로 취급해야 합니다.

    참고: 크기 포함은 자연스런 종횡비만 억제하며, aspect-ratio처럼 선호 종횡비에 직접 영향을 주는 속성은 존중됩니다.

    크기 포함 박스의 모든 CSS 속성은 일반적인 레이아웃을 할 때처럼 고려됩니다. 다른 명세에서 특정 예외를 둘 수 있습니다.

    참고: 요소의 크기 지정 속성이 내재적 크기를 지정하더라도, 요소가 반드시 0 크기가 되는 것은 아닙니다: 요소 자체에 지정한 속성이 계속 반영되어 더 커질 수도 있습니다.

    제자리에 레이아웃
    포함 박스의 콘텐츠 (의사 요소 포함) 는 이제 고정된 크기의 포함 박스에 일반적으로 레이아웃되어야 합니다.

    참고: 크기 포함은 기준선 정렬을 억제하지 않습니다. 기준선 정렬 억제는 레이아웃 포함을 참고하세요.

  3. 크기 포함 박스모놀리식입니다(참고: CSS Fragmentation 3 § 4.1 가능한 분할 지점).

다음 마크업과 스타일에서는 이미지가 100px × 100px로 크기 지정됩니다. aspect-ratio 속성으로 지정한 종횡비 효과 때문입니다.
img {
  width: 100px;
  aspect-ratio: 1/1;
  contain: size;
}
<img src="https://www.example.com/300x100.jpg">

aspect-ratio 속성이 선언되지 않았다면, 이미지는 100px × 0px이 되었을 것입니다. 자연스런 종횡비는 억제되고, 자연스런 높이가 0으로 처리되기 때문입니다.

하지만 요소에 크기 포함을 적용해도 다음 조건 중 하나라도 해당되면 아무 효과가 없습니다:

참고: 내부 테이블 박스(테이블 캡션 제외)는 테이블 레이아웃 알고리즘이 박스가 내부 콘텐츠보다 작아지는 것을 허용하지 않으므로 제외됩니다. 테이블 셀을 비어있는 것처럼 크기 지정한 뒤, 그 안에 콘텐츠를 레이아웃하더라도 크기 변경 없이 처리하는 것은 정의되지 않은 동작입니다. widthheight 속성을 0으로 수동 지정해도 콘텐츠보다 작게 만들 수 없습니다. 이 문제는 테이블 캡션에는 적용되지 않으며, 캡션은 콘텐츠와 무관하게 고정 크기를 충분히 가질 수 있습니다.

3.1.1. 크기 포함 최적화 가능성

이 섹션은 비규범적입니다.

크기 포함만으로는 최적화 기회가 많지 않습니다. 그 자체의 주요 이점은, 포함 박스의 크기를 기준으로 그 내용을 레이아웃하려는 도구(예: "컨테이너 쿼리" 개념을 구현한 JS 라이브러리)가 "무한 루프" 걱정 없이 작업할 수 있다는 점입니다. 즉, 자식의 크기가 포함 박스 크기에 따라 반응하면, 포함 박스의 크기도 변경될 수 있고, 그에 따라 자식의 크기 계산이 다시 바뀌고, 포함 박스 크기도 다시 바뀌는 식으로 무한 반복될 수 있는데 이런 걱정이 사라집니다.

레이아웃 포함과 함께 사용하면, 다음과 같은(이에 국한되지 않음) 최적화가 가능합니다:

  1. 포함 박스의 자손 스타일이나 콘텐츠가 변경될 때, DOM 트리에서 "더럽혀졌을" 가능성이 있는(재레이아웃이 필요한) 부분 계산을 포함 박스까지만 하면 됩니다.

  2. 페이지를 레이아웃할 때, 포함 박스가 화면 밖에 있거나 가려져 있으면, 그 내용(즉 "제자리에 레이아웃")은 지연하거나 우선순위를 낮게 처리할 수 있습니다.

3.2. 레이아웃 포함

요소에 레이아웃 포함을 지정하면 해당 요소의 주 박스레이아웃 포함 박스가 되며 다음과 같은 효과가 있습니다:

  1. 레이아웃 포함 박스독립적인 포맷팅 컨텍스트를 생성합니다.

  2. 어떤 단편화 컨테이너라도 단편화 컨텍스트에서 레이아웃 포함이 적용된 경우, 또는 단편화 컨테이너단편화 컨텍스트의 자손이고, 동일한 단편화 컨텍스트의 이후 단편화 컨테이너는 해당 레이아웃 포함 요소의 자손이 아니라면, 첫 번째 레이아웃 포함 박스단편화 컨테이너이거나 단편화 컨테이너의 조상인 경우, 해당 단편화 흐름의 나머지를 "가두어야" 합니다: 단편화레이아웃 포함 경계를 넘을 수 없으며, 해당 경계 내의 마지막 단편화 컨테이너는 해당 단편화 컨텍스트에서 마지막 단편화 컨테이너로 취급됩니다.

    이후의 단편화 컨테이너단편화 컨텍스트에서 단편화 흐름에 콘텐츠가 남을 때만 생성된다면, 생성되지 않습니다. 그렇지 않고 항상 존재해야 한다면, 단편화 컨텍스트의 일부로 남지만, 단편화 흐름에서 콘텐츠를 할당받지 않습니다.

    참고: 작성 시점에서는 이 조항에 영향을 받는 안정된 명세는 없습니다. 일부(전체가 아닌) 단편화 컨테이너만 레이아웃 포함(또는 그 자손)이 될 수 있도록 하는 명세에만 적용되며, [CSS-PAGE-3][CSS-MULTICOL-1]에는 해당하지 않습니다. 하지만 여러 메커니즘이 고려된 바 있어(예: [CSS-REGIONS-1], ::nth-fragment(), 멀티컬럼의 개별 컬럼용 가상 선택자 등), 만약 이런 메커니즘이 이 규칙을 따르지 않는다면 레이아웃 포함이 제공하려는 보장을 실현할 수 없기 때문에 이 요구사항을 포함했습니다. [CSS-REGIONS-1]에는 레이아웃 포함이 regions에 미치는 영향에 대한 세부 내용이 있습니다.

    <article>Lorem ipsum…</article>
    <div id=a></div>
    <aside>
      <div id=b></div>
      <div id=c></div>
    </aside>
    <aside>
      <div id=d></div>
      <div id=e></div>
    </aside>
    <div id=f></div>
    
    article {flow-into: foo;}
    #a, #b, #c, #d, #e, #f {flow-from: foo;}
    aside {contain: layout}
    

    [CSS-REGIONS-1] 예시에서는 콘텐츠가 #a에서 #b로, #b에서 #c로 흐를 수 있습니다. 하지만 #c가 첫 번째 레이아웃 포함 박스의 마지막 단편화 컨테이너이므로 나머지 콘텐츠는 여기서 모두 가두어지고, #d, #e, #f로는 아무것도 흐르지 않습니다.

  3. overflow 속성의 계산 값이 visible 또는 clip 또는 그 조합이라면, 모든 오버플로우는 잉크 오버플로우로 처리해야 합니다.

  4. 레이아웃 포함 박스절대 위치 포함 블록고정 위치 포함 블록을 생성합니다.

  5. 레이아웃 포함 박스스태킹 컨텍스트를 생성합니다.

  6. 강제 분할레이아웃 포함 박스 내에서 허용되지만, CSS Fragmentation 3 § 3.1 박스 사이의 분할: break-before 및 break-after 속성에서 설명한 것처럼 부모로 전파되지 않습니다.

    참고: 이로 인해 강제 분할이 박스와 그 컨테이너 사이에 발생할 수 있는 새로운 가능성이 생깁니다(참고: CSS Fragmentation 3 § 4.1 가능한 분할 지점).

  7. vertical-align 속성이나 기타 레이아웃 포함 박스의 기준선을 자손이 아닌 다른 것과 비교해야 하는 속성에서는, 포함 박스는 기준선이 없는 것으로 취급됩니다.

하지만 요소에 레이아웃 포함을 적용해도 다음 조건 중 하나라도 해당되면 아무 효과가 없습니다:

3.2.1. 레이아웃 포함 최적화 가능성

이 섹션은 비규범적입니다.

레이아웃 포함으로 활성화할 수 있는 최적화(이에 국한되지 않음)에는 다음과 같은 것이 있습니다:

  1. 페이지를 레이아웃할 때, 별개의 포함 박스의 콘텐츠를 서로 영향을 주지 않으므로 병렬로 레이아웃할 수 있습니다.

  2. 페이지를 레이아웃할 때, 포함 박스가 화면 밖에 있거나 가려져 있고, 화면에 보이는 부분의 레이아웃이 포함 박스의 크기에 의존하지 않는 경우(예: 포함 박스가 블록 컨테이너의 끝 근처에 있고, 사용자가 블록 컨테이너의 처음을 보고 있을 때), 포함 박스의 콘텐츠 레이아웃을 지연하거나 우선순위를 낮게 처리할 수 있습니다.

    (크기 포함과 함께 사용하면, 이 최적화를 더 자유롭게 적용할 수 있습니다.)

3.3. 스타일 포함

요소에 스타일 포함을 지정하면 다음과 같은 효과가 있습니다:

  1. counter-incrementcounter-set 속성은 반드시 요소의 서브트리에 범위가 지정되어 새로운 카운터를 생성해야 합니다.

  2. content 속성의 open-quote, close-quote, no-open-quote, no-close-quote의 효과는 요소의 서브트리에 범위가 지정되어야 합니다.

    참고: 이는 서브트리 내 인용부호 중첩 깊이가 변경되지 않고, 해당 컨텍스트가 암시하는 값에서 시작된다는 의미입니다. 하지만 서브트리 내에서 이러한 값으로 인용부호 중첩 깊이가 변경되어도, 서브트리 외부에는 영향을 주지 않습니다.

참고: [CSS-REGIONS-1]스타일 포함이 region에 어떻게 영향을 주는지에 대한 규범 요구사항을 포함합니다.

범위가 지정된 속성은 특정 요소나 서브트리에만 효과가 미칩니다.

counter-increment가 요소의 서브트리에 범위가 지정되어 있으므로, 서브트리 내 첫 번째 사용은 해당 요소에서 해당 카운터가 0으로 설정된 것처럼 동작합니다. 이는 범위 지정 요소 외부에서 해당 카운터가 사용되었는지와 상관없습니다. 서브트리 내에서 이루어진 증가분은 동일한 이름의 카운터라도 범위 지정 요소 외부에는 영향을 주지 않습니다. 하지만 counter()counters() 값은 content 속성에서 범위가 지정되지 않아, 서브트리 외부에서 생성된 카운터도 참조할 수 있습니다. 따라서 다음 코드는 1 1.2가 표시됩니다:
<div></div>
div {
  contain: style;
  counter-increment: n;
}
div::before, div::after {
  content: counters(n, '.') " ";
}
div::after {
  counter-increment: n 2;
}

3.3.1. 스타일 포함 최적화 가능성

이 섹션은 비규범적입니다.

스타일 포함으로 활성화할 수 있는 최적화(이에 국한되지 않음)에는 다음과 같은 것이 있습니다:

  1. 스타일 포함된 요소의 자손에서 속성이 변경될 때, DOM 트리의 어느 부분이 "더럽혀졌는지"(스타일을 다시 계산해야 하는지) 판단하는 계산을 스타일 포함된 요소에서 멈출 수 있습니다.

3.4. 페인트 포함

요소에 페인트 포함을 지정하면 해당 요소의 주 박스페인트 포함 박스가 되며 다음과 같은 효과가 있습니다:

  1. 요소의 콘텐츠(모든 잉크 또는 스크롤 가능한 오버플로우 포함)는 오버플로우 클립 경계를 기준으로 페인트 포함 박스 안에서 잘려야 하며, [[css-backgrounds-3#corner clipping|코너 클리핑]]을 고려해야 합니다. 이때 잘린 콘텐츠를 접근하거나 표시하는 메커니즘을 생성하지 않으며, 다른 속성(예: overflow, resize, text-overflow 등)을 통해 그런 메커니즘을 만드는 것도 방해하지 않습니다.

    참고: 이 클리핑 형태는 overflow-clip-margin을 존중하므로, 페인트 포함된 요소가 정상 경계를 약간 벗어날 수도 있습니다.

    참고: 이 문단에 설명된 동작은 overflow-x: visibleoverflow-x: clip으로, overflow-y: visibleoverflow-y: clip으로 계산하는 것과 동등하며, overflow-xoverflow-y의 다른 값은 그대로 둡니다.

  2. 페인트 포함 박스절대 위치 포함 블록고정 위치 포함 블록을 생성합니다.

  3. 페인트 포함 박스스태킹 컨텍스트를 생성합니다.

  4. 페인트 포함 박스독립적인 포맷팅 컨텍스트를 생성합니다.

하지만 요소에 페인트 포함을 적용해도 다음 조건 중 하나라도 해당되면 아무 효과가 없습니다:

3.4.1. 페인트 포함 최적화 가능성

이 섹션은 비규범적입니다.

페인트 포함으로 활성화할 수 있는 최적화(이에 국한되지 않음)에는 다음과 같은 것이 있습니다:

  1. 포함 박스가 화면 밖에 있거나 가려져 있으면, UA는 일반적으로 그 내용의 페인팅을 시도하지 않아도 됩니다. 왜냐하면 내용도 화면 밖/가려짐이 보장되기 때문입니다.

    참고: blur() 필터([FILTER-EFFECTS-1])처럼 일부 페인트 효과는 비지역적 영향을 가질 수 있습니다. 사용자 에이전트는 이런 효과를 추적할 필요가 있는데, 해당 필터가 적용된 요소의 자손이 변경될 때 부분적으로 다시 페인팅해야 할 수도 있기 때문입니다. 이 경우 페인트 포함이 적용되어 있어도 페인팅을 생략할 수 없습니다.

  2. 클리핑된 콘텐츠가 overflow, resize, text-overflow 등 별도의 메커니즘으로 접근 가능하지 않다면, UA는 박스의 크기만큼만 "캔버스" 공간을 예약할 수 있습니다. (비슷하게 스크롤 가능한 상황, 예를 들어 overflow: hidden일 때, 현재 클리핑된 콘텐츠로 스크롤할 수 있으므로, UA는 예측적으로 약간 더 그려두어 스크롤 시 바로 보이게 처리하는 경우가 많습니다. 한 프레임 뒤가 아니라 즉시 보이도록.)

  3. 스태킹 컨텍스트가 보장되므로, 스크롤 요소는 하나의 GPU 레이어에 페인팅할 수 있습니다.

4. 요소의 콘텐츠를 완전히 숨기기: content-visibility 속성

이름: content-visibility
값: visible | auto | hidden
초기값: visible
적용 대상: 레이아웃 포함을 적용할 수 있는 요소
상속됨: no
백분율: 해당 없음
계산된 값: 명시된 대로
정식 순서: 문법에 따름
애니메이션 유형: 애니메이션 불가

content-visibility 속성은 요소가 실제로 콘텐츠를 렌더링할지 여부를 제어하며, 강력한 포함도 강제하여, 사용자 에이전트가 필요할 때까지 레이아웃과 렌더링 작업을 대폭 생략할 수 있게 합니다. 다음과 같은 값을 가집니다:

visible

아무 효과 없음. 요소의 콘텐츠가 평소대로 레이아웃되고 렌더링됩니다.

hidden

요소가 자신의 콘텐츠를 건너뜁니다.

건너뛴 콘텐츠절대 사용자 에이전트 기능(페이지 내 찾기, 탭 순서 탐색 등)에 접근할 수 없어야 하며, 선택 또는 포커스도 될 수 없습니다.

참고: 이는 콘텐츠에 display: none을 적용하는 것과 유사합니다.

auto

요소에 레이아웃 포함, 스타일 포함, 페인트 포함을 활성화합니다.

요소가 사용자에게 관련 있음이 아니라면, 자신의 콘텐츠를 건너뜁니다.

hidden과 달리, 건너뛴 콘텐츠는 사용자 에이전트 기능(페이지 내 찾기, 탭 순서 탐색 등)에 평소대로 접근 가능해야 하며, 선택 및 포커스도 평소처럼 가능합니다.

요소가 자신의 콘텐츠를 건너뛸 때, 사용자 에이전트는 사용된 값을 변경하여 contain 속성에 레이아웃 포함, 스타일 포함, 페인트 포함, 크기 포함을 켜야 합니다. 또한 콘텐츠 (요소의 평면 트리 자손, 텍스트와 요소 모두 포함, 또는 치환 요소의 치환 콘텐츠) 는 페인팅되지 않으며 (마치 visibility: hidden인 것처럼), 히트 테스트에도 반응하지 않습니다 (마치 pointer-events: none인 것처럼), 그리고 대부분의 경우 스타일도 갱신되지 않습니다(스크립트에서 명시적으로 요청하지 않는 한, 자세한 내용은 § 4.4 제약 및 명확화 참고).

사용자 에이전트는 건너뛴 콘텐츠에 대해 레이아웃/렌더링 작업을 최대한 회피해야 하며, 강력한 포함과 콘텐츠를 보이지 않고 터치 불가로 만드는 조합은 대규모 최적화를 가능하게 합니다. 나중에 렌더링 작업을 하게 되면, 사용자 에이전트는 이전에 계산한 레이아웃 상태를 최대한 유지하여, 건너뛴 콘텐츠가 빠르게 표시될 수 있게 해야 합니다.

요소가 content-visibility: visible이 아닌 값을 가지면 다음 속성이 적용됩니다:
  • 레이아웃 포함은 건너뛴 서브트리에서 레이아웃 작업을 생략할 수 있게 하며, 해당 레이아웃 결과가 외부 요소에 영향을 주지 않기 때문입니다.

  • 스타일 포함은 카운터 처리를 건너뛴 서브트리에서 생략할 수 있게 하며, 해당 카운터가 외부 요소에 영향을 주지 않기 때문입니다.

  • 페인트 포함은 페인팅된 콘텐츠의 잉크 오버플로우를 클리핑하며, 이는 사용자 에이전트가 요소의 보이는 부분이 뷰포트에 접근할 때를 신뢰성 있게 판별할 수 있게 해줍니다 (그리고 content-visibility: auto에서는 페인팅을 시작할 수 있습니다).

  • 크기 포함은 건너뛴 서브트리에서 레이아웃을 생략할 수 있게 하며, 해당 레이아웃 결과가 컨테이너 요소의 크기에 영향을 주지 않기 때문입니다.

단, content-visibility: auto의 경우, 레이아웃 포함, 스타일 포함, 페인트 포함은 요소가 건너뛰지 않아도 계속 유지됩니다. 이는 요소가 건너뛰는 상태에 출입할 때 포함 변경으로 인한 레이아웃 변경을 방지하기 위함입니다.

요소가 사용자에게 관련 있음이 되려면 다음 조건 중 하나라도 충족해야 합니다:

4.1. content-visibility: hidden 사용하기

이 섹션은 비규범적입니다.

content-visibility: hidden은 요소에 강력한 제약을 부여하므로 신중하게 사용해야 합니다. 하지만 매우 유용한 시나리오도 가능하게 하며, 기존 기법보다 개선되는 경우가 많습니다. 그 중 일부를 아래에 소개합니다.

  1. 페이지에서 실제로 렌더링하지 않을 요소나 텍스트의 크기를 측정해야 할 때, 일반적으로 측정할 내용을 화면 밖에 위치시키는 방식(예: position: absolute; left: -100000px;)을 사용하고, getBoundingClientRect() 같은 API를 호출합니다.

    문제는 이런 콘텐츠를 화면에 표시할 의도가 없더라도, 사용자 에이전트는 혹시나 화면에 영향을 줄 수 있으므로 스타일링, 레이아웃, 렌더링을 모두 수행해야만 한다는 점입니다. 작성자는 추가 작업 없이는 해당 콘텐츠가 실수로 화면에 나타나지 않을 것임을 확신할 수도 없습니다; 매우 큰 left 값(위처럼)을 써도 콘텐츠에 따라 충분하지 않을 수 있습니다.

    이 콘텐츠를 content-visibility: hidden 컨테이너로 감싸면 이런 문제를 모두 해결할 수 있습니다. 래퍼에 테두리, 배경 등이 없다면, 래퍼와 건너뛴 콘텐츠는 아무리 커져도 화면에 절대 렌더링되지 않습니다. 콘텐츠가 건너뛰기되므로, 사용자 에이전트도 스타일링이나 레이아웃을 스크립트가 실제로 요청하기 전까지는 하지 않아도 됩니다.

  2. "싱글 페이지 앱"은 여러 개의 독립적인 패널 또는 "뷰"로 구성되는 경우가 많으며, 한 번에 하나만 표시됩니다.

    비활성 뷰에 대해 스타일링/레이아웃/렌더링 등의 비용을 피하려면, 문서에서 완전히 제거하거나, 최소한 display:none을 적용할 수 있습니다. 하지만 이렇게 하면 뷰가 표시될 때 모든 스타일/레이아웃/렌더링 작업을 한 번에 처리해야 하므로 실제로 표시될 때 눈에 띄는 지연이 발생할 수 있습니다.

    다른 방법으로 뷰를 화면 밖에 위치시킬 수도 있습니다. 이 방식은 사용 시 즉시 준비되지만, 항상 스타일링/레이아웃/렌더링 비용을 지불해야 하며, 비활성 뷰가 많으면 영향이 커집니다. 비활성 뷰가 접근성 도구에 표시되어 스크린 리더 사용자, Ctrl-F로 페이지 내 검색하는 사람 등에게 혼란을 줄 수도 있습니다.

    content-visibility: hidden은 이런 두 가지 방식보다 더 나은 방법을 제공합니다. 콘텐츠가 건너뛰기되므로, 사용자 에이전트는 비활성 상태일 때 시간 낭비를 하지 않습니다. 또한 스크린 리더, 페이지 내 찾기 등 도구에도 보이지 않습니다. 그리고 사용자 에이전트는 가능한 경우 이전 스타일/레이아웃 작업을 보존해야 하므로, 이전에 표시된 뷰라면 다시 렌더링하는 속도가 매우 빠를 수 있습니다.

  3. 작성자가 요소를 "보이지 않게" 하면서도 레이아웃에는 남기고 싶다면, visibility: hidden을 사용할 수 있습니다. 하지만 visibility: hidden 요소의 자손이 visibility: visible을 지정하면 다시 보이게 되므로, 직관적이지 않거나 기대와 다를 수 있습니다.

    content-visibility: hidden은 매우 유사한 목적을 수행하지만, 자손이 "끔"을 해제해 다시 표시되지는 않습니다; 상위 요소가 해제할 때까지 계속 "숨김" 상태로 유지됩니다.

    content-visibility: hidden은 또한 여러 containment 값을 컨테이너에 적용하므로, 항상 visibility: hidden만큼 편리하지는 않지만, 제약이 허용된다면 요소의 콘텐츠를 숨기는 더 신뢰할 수 있고 일관성 있는 방법이 될 수 있습니다.

4.2. content-visibility: auto 사용하기

이 섹션은 비규범적입니다.

content-visibility: autohidden보다 더 복잡한 값입니다; display: none과 유사하기보다는, 요소의 콘텐츠가 사용자에게 관련 있음 상태가 될 때에만 적응적으로 숨기거나 표시합니다. 또한 건너뛴 콘텐츠를 사용자 에이전트로부터 숨기지 않으므로, 스크린 리더, 페이지 내 찾기 등 도구로 계속 상호작용할 수 있습니다.

이를 containment의 업그레이드로 생각하는 것이 가장 좋습니다: 작성자가 자주 화면 밖에 있게 될 대량의 콘텐츠(예: 긴 스크롤 목록)를 표시해야 하고, 해당 콘텐츠가 강력한 containment를 허용할 수 있다면, content-visibility: auto를 사용해 모든 containment을 한 번에 적용하는 것을 고려해야 합니다. 이는 사용자 에이전트에 콘텐츠 작업을 생략해도 된다는 강력한 힌트를 제공하며 (콘텐츠가 화면에 등장할 때 약간의 지연이 있을 수 있음), 문서에 대량의 콘텐츠가 있는 것이 더 중요하고 대부분은 어차피 보이지 않을 것임을 의미합니다.

참고: content-visibility: auto는 복잡한 "가상 리스트" 기법 대신에 사용할 수 있습니다(적어도 많은 경우).

content-visibility: auto는 요소의 콘텐츠가 사용자에게 관련 있음이 아닐 때만 건너뛰기하므로, 적당히 세분화해서 사용하는 것이 가장 좋습니다.

예를 들어, 트위터에서 전체 타임라인에 content-visibility: auto를 적용해도 효과가 거의 없습니다—항상 화면에 있으므로, 콘텐츠를 건너뛰기하지 않습니다.

대신, content-visibility각 트윗에 개별적으로 적용해 각각이 화면에서 벗어날 때 건너뛰기되도록 해야 합니다.

content-visibility: auto는 요소가 콘텐츠를 건너뛸 때 크기 포함을 적용하므로, 요소가 자신의 콘텐츠에 따라 크기가 결정된다면 페이지 레이아웃(또는 최소한 스크롤바 위치)이 요소가 화면에서 벗어나 건너뛰기 상태가 될 때마다 "이동"할 수 있습니다.

이를 해결하는 방법은 여러 가지가 있습니다:

예를 들어, 트위터에서는 평균 트윗 높이가 약 200px이므로, contain-intrinsic-size: auto 500px 200px을 지정하면 스크롤바 손잡이 크기와 위치가 트윗 앞뒤가 건너뛰기되어도 거의 정확하게 맞게 되고, 트윗이 화면에 있을 때는 실제 콘텐츠에 맞춰 크기가 조정됩니다. 트윗을 한 번이라도 봤다면 (그리고 건너뛰기 상태일 때 크기가 바뀌지 않았다면), 건너뛰기 상태에서도 크기가 정확히 맞으므로, 스크롤바 손잡이도 정확해집니다; 단지 신규 로드된 트윗(예: 타임라인 맨 위에 새로 로드된 트윗 등)만 200px 높이 예상치를 사용하게 됩니다.

4.3. content-visibility: auto 상태 변화를 감지하기: contentvisibilityautostatechanged 이벤트

contentvisibilityautostatechanged 이벤트는 content-visibility: auto 스타일을 가진 요소에서 렌더링 상태가 변하고 요소가 사용자에게 관련 있음이 되거나 아니게 될 때 발생합니다.

이 이벤트는 상태 변화 발생 시 태스크를 게시하여 디스패치됩니다.

[Exposed=Window]
interface ContentVisibilityAutoStateChangedEvent : Event {
  constructor(DOMString type, optional ContentVisibilityAutoStateChangedEventInit eventInitDict = {});
  readonly attribute boolean skipped;
};
dictionary ContentVisibilityAutoStateChangedEventInit : EventInit {
  boolean skipped = false;
};

ContentVisibilityAutoStateChangedEvent 속성 설명:

skipped, 타입 boolean, 읽기 전용

대상이 콘텐츠 건너뛰기 상태로 변경되면 true, 아니면 false입니다.

ContentVisibilityAutoStateChangedEventInit 멤버 설명:

skipped, 타입 boolean, 기본값 false

skipped 속성 설명을 참고하세요.

content-visibility: auto 서브트리의 요소들은 콘텐츠를 건너뛴다 하더라도 의미상 계속 관련이 있습니다. 즉, 이 신호를 이용해 스킵된 서브트리의 DOM 업데이트를 무기한 건너뛰는 것은 적절하지 않습니다. 대신, 업데이트 우선순위를 낮추되, 콘텐츠가 의미상 계속 관련 있고, 적당히 최신 상태를 유지하도록 해야 합니다. 특히 접근성 기술에서는 상위가 콘텐츠 건너뛰기 상태여도 해당 콘텐츠를 소비하므로 중요합니다.

4.4. 제약 및 명확화

  1. IntersectionObserver의 관점에서, 요소의 건너뛴 콘텐츠는 절대 intersection root와 교차하지 않습니다. 이는 root와 target 요소가 모두 건너뛴 콘텐츠에 있더라도 마찬가지입니다.

  2. ResizeObserver의 관점에서, 요소의 건너뛴 콘텐츠는 크기가 절대 변하지 않습니다. 이 요소들이 나중에 건너뛰지 않는 상태가 되면, 새로운 크기가 마지막으로 resize observer에 알린 크기와 다를 경우 resize observation이 전달됩니다.

  3. 요소가 콘텐츠 건너뛰기를 시작하거나 멈추면, 이 변화는 해당 변화의 효과를 렌더링하는 프레임의 requestAnimationFrame 콜백이 실행된 후에 발생합니다. 구체적으로, 이런 변화는 Processing Model의 Update the Rendering 단계의 13단계와 14단계 사이에서 발생합니다 ("애니메이션 프레임 콜백 실행"과 "업데이트 intersection 관찰 단계 실행" 사이).

    요소의 뷰포트 교차 여부는 내부 IntersectionObserver 버전으로 판별할 수 있습니다. 하지만 이 관찰 결과는 Update the Rendering의 14단계에서 전달되므로, 건너뛴(즉 페인팅된) 상태에 대한 변경은 다음 프레임의 처리까지 사용자에게 보이지 않습니다. 이 때문에 건너뛴 상태(및 포함 조정 등) 업데이트도 그 프레임으로 연기됩니다. 이로써 예를 들어 스크립트가 이 두 이벤트(내부 intersection 관찰과 건너뛴 상태 업데이트) 사이에 요소의 포함 값을 조회할 때 최신 페인팅 상태와 일치하는 값을 얻고, 강제 레이아웃이 발생하지 않도록 보장할 수 있습니다.
  4. content-visibility: auto의 가시성 최초 판정은 새로운 content-visibility: auto 요소의 존재가 판정된 그 프레임에서 이루어져야 합니다.

    요소가 처음 content-visibility: auto를 얻게 될 때, 화면에 배치되는지 여부는 다를 수 있습니다. 이 상태 판정과 건너뛰기 여부 판정은 동일 프레임에서 반드시 이루어져야 합니다. 그렇지 않으면 가시성 판정과 건너뛴 상태 업데이트가 다음 프레임으로 미뤄져 요소 자리의 내용이 비어 보일 가능성이 생깁니다.
  5. 스크롤 동작(scrollIntoView() 등)에서는, content-visibility: auto이면서 콘텐츠를 건너뛰기 상태인 요소의 크기와 위치는 여전히 크기 포함이 활성화된 상태에서 판정됩니다.

    참고: 요소가 뷰포트로 스크롤되면 더 이상 콘텐츠를 건너뛰지 않게 되므로, 크기 포함이 없어질 수 있습니다; 이로 인해 요소의 크기가 바뀌면 뷰포트에서 정확히 요청한 위치에 정렬되지 않을 수 있습니다.

    요소가 사용자 에이전트 기능에서 사용할 수 없는 경우 (예: 상위에 건너뛴 상태의 content-visibility: hidden이 있을 때), 스크롤 동작은 해당 요소로 스크롤하지 않아야 하며, 마치 레이아웃 박스가 없는 것처럼 처리해야 합니다.

  6. content-visibility: auto이면서 콘텐츠를 건너뛰기 상태인 요소가 포커스되거나 (또는 그 콘텐츠가 포커스된 경우), 사용자에게 관련 있음 상태가 되고(콘텐츠를 건너뛰기가 해제됨) 포커싱으로 인해 뷰포트로 스크롤되기 전에 이 변화가 일어납니다.

    참고: 따라서 앞선 항목과 달리, 요소가 뷰포트에 정확한 크기와 위치로 정렬됩니다. 이는 focus() 메서드의 단계 순서와 일치합니다.

  7. iframe콘텐츠를 건너뛰기 상태이거나, 어떤 요소의 건너뛴 콘텐츠 일부라면, 사용자 에이전트는 가능하다면 해당 iframe의 이벤트 루프에서 Update The Rendering 단계를 완전히 생략해야 합니다.

    참고: iframe건너뛰기 상태가 되자마자, 페인팅 출력을 제거하기 위해 그 단계를 최소 한 번은 실행해야 합니다.

  8. 건너뛴 콘텐츠innerText 결과에 기여하지 않습니다.

  9. 요소가 건너뛴 상태일 때, 그 요소의 CSS 트랜지션과 애니메이션은 업데이트되지 않습니다:

    • 새로운 애니메이션은 새 스타일이 적용되어도 생성되지 않습니다.

    • 기존 애니메이션은 타임라인에서 진행되지 않습니다.

    • 실행 중인 애니메이션은 종료되지 않습니다.

    스크립트가 건너뛴 요소의 스타일을 조회하여 (스타일 변경 이벤트 발생) 애니메이션 또는 트랜지션의 상태를 알아야 하는 경우, 애니메이션과 트랜지션은 해당 스타일 변경 이벤트 시점의 스타일에 따라 샘플링됩니다:

    CSS Animations 2 § 4 Animation EventsCSS Transitions 2 § 5 Transition Events에서는 애니메이션/트랜지션이 업데이트될 때 어떤 객체가 생성되고 어떤 이벤트가 어떤 데이터로 발생하는지 정의합니다.

    요소가 더 이상 건너뛴 상태가 아니게 되면, 애니메이션과 트랜지션은 샘플링되고 그 시점부터 정상적으로 타임라인을 따라 진행됩니다.

    참고: 전체적으로, 이는 백그라운드 탭이 다시 포그라운드로 돌아올 때 트랜지션/애니메이션 동작과 비슷하며, 사용자 에이전트가 불필요한 애니메이션 작업을 최대한 생략하면서도, 다시 관련이 생길 때 애니메이션을 과도하게 방해하지 않도록 해줍니다.

  10. 요소가 건너뛴 상태일 때, 트랜지션을 시작하면 안 되며, 스타일 변경 이벤트가 계산된 스타일에 영향을 주더라도 마찬가지입니다.

    요소가 더 이상 건너뛴 상태가 아니게 되면, 해당 스타일 변경 이벤트로 인해 트랜지션을 시작하면 안 됩니다.

    참고: 이는 요소가 display:none에서 비-none 값으로 전환될 때와 유사합니다—이 경우 스타일이 기술적으로 변경되지만 (초기 값에서 cascade를 거친 "정상" 값으로), 트랜지션이 시작되지 않습니다.

  11. 요소의 상위에 content-visibility: hidden이 있고, 그 요소가 top layer에 배치되면, 박스를 생성하지 않으며, display: none인 것처럼 동작합니다.

    참고: 건너뛴 상태가 다른 이유(예: 상위가 content-visibility: auto인 경우)라면, 박스를 정상적으로 생성하며, 그로 인해 건너뛰기가 해제될 수 있습니다.

4.5. 접근성 영향

만약 사용자 에이전트가 "접근성 트리" 형태를 노출한다면, DOM 트리와 유사하지만 접근성 사용 사례(예: 스크린리더)에 특화된 것으로, 접근성 API에 관련된 요소의 위치 등(포커스 가능한 요소 등)을 제공하는 것이라면, 건너뛴 콘텐츠content-visibility: hidden 요소에 속한 경우, 접근성 트리에서도 "건너뛴"(생략된) 상태가 되어야 합니다 (즉 display: none 요소가 문서의 모든 뷰에서 생략되는 것과 유사하게).

건너뛴 콘텐츠content-visibility: auto 요소에 속한 경우, 접근성 트리를 통해 사용자가 페이지와 상호작용하고 있다는 사실이 드러나지 않아야 하며, 시각적으로 화면에 렌더링하는 것과 구분되어서는 안 됩니다. 특히, 사용자 에이전트가 content-visibility: auto를 사용해 화면에 표시되지 않는 콘텐츠의 레이아웃/페인팅 작업을 생략한다면, 접근성 트리에서도 동일하게 작업을 생략해야 합니다. 만약 이것이 불가능하다면 (예: 접근성 트리에서 포커스 가능한 요소의 위치를 알아야 하므로 해당 요소와 주변 내용을 완전히 레이아웃해야 하는 경우), 사용자 에이전트는 건너뛴 콘텐츠를 접근성 트리에서 반드시 완전히 생략해야 합니다.

참고: 이 요구사항은 접근성 도구를 활용하는 사용자가 타이밍 채널을 통해 식별·프로파일링 되는 것을 방지하기 위한 것입니다. 만약 사용자 에이전트가 시각적 렌더링에서 대규모 작업을 생략할 수 있는데, 접근성 트리 렌더링에서는 모든 작업을 수행해야 한다면, 작성자는 레이아웃 작업의 타이밍을 관찰함으로써 사용자가 페이지를 어떻게 상호작용하는지 알 수 있습니다.

4.6. 예시

<style>
.sv {
  content-visibility: auto;
  min-height: 50px;
}
</style>

<div class=sv>
  ... some content goes here ...
</div>

.sv 요소의 content-visibility: auto 값은 사용자 에이전트가 해당 요소를 건너뛸지 관리할 수 있게 합니다. 특히 이 요소가 뷰포트 근처에 있을 때, 사용자 에이전트는 요소의 페인팅을 시작합니다. 요소가 뷰포트에서 멀어지면, 페인팅을 중단하게 됩니다. 또한, 요소가 건너뛴 상태라면 사용자 에이전트는 가능한 한 많은 렌더링 작업을 생략해야 합니다.

<style>
.sv {
  content-visibility: hidden;
}
</style>

<div class=sv>
  ... some content goes here ...
</div>

이 경우, 요소는 뷰포트 교차 여부와 관계없이 건너뛴 상태입니다. 즉, contents가 페인팅되려면 스크립트가 값을 갱신하여 content-visibility를 제거하거나 값을 변경해야만 합니다. 앞서와 같이, 사용자 에이전트는 contents의 렌더링을 최대한 생략해야 합니다.

렌더링을 건너뛰면 추가로, contents의 레이아웃 상태를 사용자 에이전트가 보존할 수 있으므로, 나중에 content-visibility 속성을 제거하면 contentsdisplay: none 등으로 숨겼을 때보다 더 빠르게 렌더링됩니다.

<style>
body {
  margin: 0;
}
.sv {
  content-visibility: hidden;
  position: relative;
  left: 10px;
  top: 20px;
}
#child {
  position: relative;
  left: 1px;
  top: 2px;
  width: 100px;
  height: 200px;
}
</style>

<div id=target class=sv>
  <div id=child></div>
  ... some other content goes here ...
</div>
<script>
  ...
  // UA가 이전에 렌더링 작업(레이아웃 포함)을 생략했다면,
  // 이 코드는 강제로 렌더링 작업을 수행합니다.
  target.firstElementChild.getBoundingClientRect();
  ...
</script>

앞선 예시와 마찬가지로 해당 요소는 건너뛴 상태입니다. 사용자 에이전트는 렌더링 작업을 최대한 생략해야 합니다. 하지만 이 예시에서는 스크립트가 요소의 contents의 레이아웃 값을 접근합니다. 이 경우 사용자 에이전트는 렌더링 작업을 피할 수 없으며, 정답을 반환하려면 이전에 건너뛴 렌더링 작업까지 모두 처리해야 합니다. 이 예시에서 getBoundingClientRect()의 결과는 (11, 22) 위치에 크기가 100x200인 rect입니다.

동일한 레이아웃 값을 반복 조회하더라도 추가적인 렌더링 작업이 발생하지 않아야 하며, 사용자 에이전트가 마지막으로 갱신한 렌더링 상태를 유지해야 합니다.

또한 스크립트 등으로 렌더링 작업이 필요한 상황은 이 예시뿐만 아니라 다른 경우에도 있을 수 있습니다. 사용자 에이전트가 렌더링 작업을 피할 수 없는 상황이 더 있을 수 있다는 점에 유의하세요.

5. 개인정보 고려사항

이 명세의 기능에는 알려진 개인정보 영향이 없습니다.

6. 보안 고려사항

이 명세의 기능에는 알려진 보안 영향이 없습니다.

다른 CSS 명세와 마찬가지로, 문서 렌더링에 영향을 주지만, 다른 CSS 모듈에서도 이미 가능한 방식 외에 특별히 오해를 유발하는 형태로 콘텐츠를 표시할 수 있는 기능을 추가하지 않습니다. 이는 문서를 포맷하는 행위에 본질적으로 포함된 것이 아닙니다.

부록 A. 변경 사항

이 부록은 참고용입니다.

2020-12-16 워킹 드래프트 이후 변경 사항

2020-06-03 워킹 드래프트 이후 변경 사항

2019-11-11 워킹 드래프트 이후 변경 사항

CSS 포함 Level 1 이후 변경 사항

적합성

문서 규칙

적합성 요구사항은 설명적 단언과 RFC 2119 용어의 조합으로 표현됩니다. 규범적 부분에 사용되는 “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, “OPTIONAL” 등의 단어는 RFC 2119에서 설명한 대로 해석해야 합니다. 단, 가독성을 위해 이 명세에서는 이러한 단어들이 모두 대문자로 표기되지는 않습니다.

이 명세의 모든 텍스트는 명시적으로 비규범적임을 표시한 섹션, 예시, 참고 사항을 제외하고 규범적입니다. [RFC2119]

이 명세의 예시는 “for example”이라는 단어로 도입되거나 class="example"와 같이 규범 텍스트와 구분되어 표시됩니다. 예시:

이것은 정보성 예시입니다.

정보성 참고 사항은 “Note”로 시작하며 class="note"로 규범 텍스트와 구분되어 표시됩니다. 예시:

Note, 이것은 정보성 참고 사항입니다.

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

적합성 분류

이 명세의 적합성은 세 가지 적합성 분류에 대해 정의됩니다:

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

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

렌더러가 이 명세에 적합하려면, 적절한 명세에 따라 스타일 시트를 해석함과 더불어, 이 명세에서 정의한 모든 기능을 올바르게 파싱하고 문서를 이에 맞게 렌더링해야 합니다. 단, 장치의 한계로 인해 UA가 문서를 올바르게 렌더링하지 못하는 경우는 비적합으로 간주되지 않습니다. (예를 들어, UA가 흑백 모니터에서 색상을 렌더링할 필요는 없습니다.)

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

부분 구현

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

불안정 및 독점 기능 구현

향후 안정적인 CSS 기능과의 충돌을 피하기 위해, CSSWG는 미래 호환성 모범 사례를 따르며 불안정 기능 및 독점 확장 구현을 권고합니다.

비실험적 구현

명세가 Candidate Recommendation 단계에 도달하면, 비실험적 구현이 가능하며, 구현자는 명세에 따라 올바르게 구현한 CR 수준 기능에 대해 접두어 없이 구현을 배포해야 합니다.

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

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

색인

이 명세에서 정의한 용어

참고에서 정의된 용어

참고문헌

규범적 참고문헌

[CSS-BACKGROUNDS-3]
Bert Bos; Elika Etemad; Brad Kemper. CSS Backgrounds and Borders Module Level 3. 2021년 7월 26일. CR. URL: https://www.w3.org/TR/css-backgrounds-3/
[CSS-BOX-4]
Elika Etemad. CSS Box Model Module Level 4. 2020년 4월 21일. WD. URL: https://www.w3.org/TR/css-box-4/
[CSS-BREAK-3]
Rossen Atanassov; Elika Etemad. CSS Fragmentation Module Level 3. 2018년 12월 4일. CR. URL: https://www.w3.org/TR/css-break-3/
[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-CONTAIN-1]
Tab Atkins Jr.; Florian Rivoal. CSS Containment Module Level 1. 2020년 12월 22일. REC. URL: https://www.w3.org/TR/css-contain-1/
[CSS-CONTENT-3]
Elika Etemad; Dave Cramer. CSS Generated Content Module Level 3. 2019년 8월 2일. WD. URL: https://www.w3.org/TR/css-content-3/
[CSS-DISPLAY-3]
Tab Atkins Jr.; Elika Etemad. CSS Display Module Level 3. 2021년 9월 3일. CR. URL: https://www.w3.org/TR/css-display-3/
[CSS-IMAGES-3]
Tab Atkins Jr.; Elika Etemad; Lea Verou. CSS Images Module Level 3. 2020년 12월 17일. CR. URL: https://www.w3.org/TR/css-images-3/
[CSS-INLINE-3]
Dave Cramer; Elika Etemad; Steve Zilles. CSS Inline Layout Module Level 3. 2020년 8월 27일. WD. URL: https://www.w3.org/TR/css-inline-3/
[CSS-LISTS-3]
Elika Etemad; Tab Atkins Jr.. CSS Lists and Counters Module Level 3. 2020년 11월 17일. WD. URL: https://www.w3.org/TR/css-lists-3/
[CSS-OVERFLOW-3]
David Baron; Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2021년 12월 23일. WD. URL: https://www.w3.org/TR/css-overflow-3/
[CSS-POSITION-3]
Elika Etemad; Tab Atkins Jr.. CSS Positioned Layout Module Level 3. 2022년 9월 1일. WD. URL: https://www.w3.org/TR/css-position-3/
[CSS-PSEUDO-4]
Daniel Glazman; Elika Etemad; Alan Stearns. CSS Pseudo-Elements Module Level 4. 2020년 12월 31일. WD. URL: https://www.w3.org/TR/css-pseudo-4/
[CSS-SCOPING-1]
Tab Atkins Jr.; Elika Etemad. CSS Scoping Module Level 1. 2014년 4월 3일. WD. URL: https://www.w3.org/TR/css-scoping-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-TRANSITIONS-1]
David Baron; et al. CSS Transitions. 2018년 10월 11일. WD. URL: https://www.w3.org/TR/css-transitions-1/
[CSS-UI-3]
Tantek Çelik; Florian Rivoal. CSS Basic User Interface Module Level 3 (CSS3 UI). 2018년 6월 21일. REC. URL: https://www.w3.org/TR/css-ui-3/
[CSS-UI-4]
Florian Rivoal. CSS Basic User Interface Module Level 4. 2021년 3월 16일. WD. URL: https://www.w3.org/TR/css-ui-4/
[CSS-VALUES-3]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 3. 2019년 6월 6일. CR. URL: https://www.w3.org/TR/css-values-3/
[CSS-VALUES-4]
Tab Atkins Jr.; Elika Etemad. CSS Values and Units Module Level 4. 2021년 12월 16일. WD. URL: https://www.w3.org/TR/css-values-4/
[CSS-WRITING-MODES-3]
Elika Etemad; Koji Ishii. CSS Writing Modes Level 3. 2019년 12월 10일. REC. URL: https://www.w3.org/TR/css-writing-modes-3/
[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/
[CSS2]
Bert Bos; et al. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS21/
[CSSOM-VIEW-1]
Simon Pieters. CSSOM View Module. 2016년 3월 17일. WD. URL: https://www.w3.org/TR/cssom-view-1/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[FULLSCREEN]
Philip Jägenstedt. Fullscreen API Standard. Living Standard. URL: https://fullscreen.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INTERSECTION-OBSERVER]
Stefan Zager; Emilio Cobos Álvarez. Intersection Observer. 2022년 7월 6일. WD. URL: https://www.w3.org/TR/intersection-observer/
[RESIZE-OBSERVER-1]
Aleks Totic; Greg Whitworth. Resize Observer. 2020년 2월 11일. WD. URL: https://www.w3.org/TR/resize-observer-1/
[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
[SVG2]
Amelia Bellamy-Royds; et al. Scalable Vector Graphics (SVG) 2. 2018년 10월 4일. CR. URL: https://www.w3.org/TR/SVG2/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

참고용 참고문헌

[CSS-GRID-2]
Tab Atkins Jr.; Elika Etemad; Rossen Atanassov. CSS Grid Layout Module Level 2. 2020년 12월 18일. CR. URL: https://www.w3.org/TR/css-grid-2/
[CSS-MULTICOL-1]
Florian Rivoal; Rachel Andrew. CSS Multi-column Layout Module Level 1. 2021년 10월 12일. CR. URL: https://www.w3.org/TR/css-multicol-1/
[CSS-OVERFLOW-4]
David Baron; Florian Rivoal. CSS Overflow Module Level 4. 2017년 6월 13일. WD. URL: https://www.w3.org/TR/css-overflow-4/
[CSS-PAGE-3]
Elika Etemad; Simon Sapin. CSS Paged Media Module Level 3. 2018년 10월 18일. WD. URL: https://www.w3.org/TR/css-page-3/
[CSS-REGIONS-1]
Rossen Atanassov; Alan Stearns. CSS Regions Module Level 1. 2014년 10월 9일. WD. URL: https://www.w3.org/TR/css-regions-1/
[CSS-SIZING-4]
Tab Atkins Jr.; Elika Etemad; Jen Simmons. CSS Box Sizing Module Level 4. 2021년 5월 20일. WD. URL: https://www.w3.org/TR/css-sizing-4/
[FILTER-EFFECTS-1]
Dirk Schulze; Dean Jackson. Filter Effects Module Level 1. 2018년 12월 18일. WD. URL: https://www.w3.org/TR/filter-effects-1/

속성 색인

이름 초기값 적용 대상 상속 %값 애니메이션 타입 정식 순서 계산된 값
contain none | strict | content | [ size || layout || style || paint ] none 아래 참조 no 해당 없음 애니메이션 불가 문법에 따름 키워드 none 또는 size, layout, paint 중 하나 이상
content-visibility visible | auto | hidden visible 레이아웃 포함을 적용할 수 있는 요소 no 해당 없음 애니메이션 불가 문법에 따름 명시된 대로

IDL 색인

[Exposed=Window]
interface ContentVisibilityAutoStateChangedEvent : Event {
  constructor(DOMString type, optional ContentVisibilityAutoStateChangedEventInit eventInitDict = {});
  readonly attribute boolean skipped;
};
dictionary ContentVisibilityAutoStateChangedEventInit : EventInit {
  boolean skipped = false;
};