폴리필이 대대적으로 업데이트되는 동안 컨테이너 쿼리가 안정적인 브라우저에 도입되기 시작함

컨테이너 쿼리 사용해 보기

기쁜 소식입니다. 가장 많은 요청이 있었던 개발자 기능 중 하나가 웹브라우저에 출시되기 시작했습니다. Chromium 105Safari 16부터 이제 이러한 브라우저에서 크기 기반 컨테이너 쿼리를 만들고 컨테이너 쿼리 단위 값을 사용할 수 있습니다. 크기 기반 컨테이너 쿼리와 cq 단위를 더 쉽게 사용할 수 있도록 Chrome의 Aurora팀은 더 많은 브라우저와 사용 사례를 지원하도록 컨테이너 쿼리 폴리필을 업데이트하기 위해 노력해 왔습니다. 이제 이 강력한 기능을 안심하고 사용하실 수 있습니다.

컨테이너 쿼리란 무엇인가요?

컨테이너 쿼리는 상위 요소의 지형지물을 타겟팅하여 하위 요소의 스타일을 지정하는 스타일 지정 로직을 작성할 수 있는 CSS 기능입니다. 상위 요소의 크기를 쿼리하여 진정한 구성요소 기반 반응형 디자인을 만들 수 있습니다. 이는 뷰포트의 크기 정보만 제공하는 미디어 쿼리와 같은 것보다 훨씬 더 세부적이고 유용한 정보입니다.

ALT_TEXT_HERE

컨테이너 쿼리를 사용하면 페이지의 위치에 따라 다르게 표시될 수 있는 재사용 가능한 구성요소를 작성할 수 있습니다. 이렇게 하면 페이지와 템플릿에서 훨씬 더 탄력적이고 반응성이 향상됩니다.

컨테이너 쿼리 사용

다음과 같은 HTML이 있다고 가정해 보겠습니다.

<!-- card parent -->
<div class=”card-parent”>
  <div class=”card>
     <!-- card contents -->
      …
  </div>
</div>

컨테이너 쿼리를 사용하려면 먼저 추적하려는 상위 요소에 포함을 설정해야 합니다. container-type 속성을 설정하거나 container 약어를 사용하여 컨테이너 유형과 컨테이너 이름을 동시에 설정하면 됩니다.

.card-parent {
  /* query the inline-direction size of this parent */
  container-type: inline-size;
}

이제 @container 규칙을 사용하여 가장 가까운 상위 요소를 기반으로 스타일을 설정할 수 있습니다. 카드가 한 열에서 두 열로 이동할 수 있는 위의 이미지와 같은 디자인의 경우 다음과 같이 작성합니다.

@container (min-width: 300px) {
  .card {
    /* styles to apply when the card container (.card-parent in this case) is >= 300px */
    /* I.e. shift from 1-column to 2-column layout: */
    grid-template-columns: 1fr 1fr;
  }
}

더 깔끔하고 명시적으로 하려면 상위 요소 컨테이너에 이름을 지정합니다.

.card-parent {
  container-type: inline-size;
  /* set name here, or write this in one line using the container shorthand */
  container-name: card-container;
}

그런 다음 이전 코드를 다음과 같이 다시 작성합니다.

@container card-container (min-width: 300px) {
  .card {
    grid-template-columns: 1fr 1fr;
  }
}
를 참고하세요.

컨테이너 쿼리 단위

컨테이너 쿼리를 더욱 유용하게 만들려면 컨테이너 기반 단위 값도 사용할 수 있습니다. 다음 표에는 가능한 컨테이너 단위 값과 컨테이너 크기와의 대응 방식이 나와 있습니다.

단위상대적
cqw쿼리 컨테이너 너비의 1%
cqh쿼리 컨테이너 높이의 1%
cqi쿼리 컨테이너의 인라인 크기의 1%
cqb쿼리 컨테이너의 블록 크기의 1%
cqmincqi 또는 cqb 중 더 작은 값
cqmaxcqi 또는 cqb의 더 큰 값

컨테이너 기반 단위를 사용하는 한 가지 예는 반응형 서체입니다. 뷰포트 기반 단위(예: vh, vb, vw, vi)는 화면의 모든 요소 크기를 조절하는 데 사용할 수 있습니다.

.card h2 {
  font-size: 15cqi;
}

이 코드는 font-size를 컨테이너의 인라인 크기의 15%로 설정합니다. 즉, 인라인 크기(너비)가 증가하면 더 커지고 감소하면 더 작아집니다. 더 나아가 clamp() 함수를 사용하여 서체에 최소 및 최대 크기 제한을 적용하고 컨테이너 크기에 따라 반응형으로 크기를 조정할 수 있습니다.

.card h2 {
  font-size: clamp(1.5rem, 15cqi, 3rem);
}

이제 헤더가 3rem보다 크거나 .5rem보다 작아지지는 않지만 그 사이 어디든 컨테이너 인라인 크기의 15% 를 차지합니다.

이 데모에서는 한 걸음 더 나아가 2열 뷰에 표시되므로 더 넓은 카드의 크기 범위를 더 작게 업데이트합니다.

컨테이너 쿼리 폴리필

컨테이너 쿼리는 매우 강력한 기능이므로 프로젝트에 이를 통합하는 데 편안함을 느끼고 브라우저 지원이 상당한 부분이라는 점을 알 수 있도록 하고자 합니다. 이에 따라 Container Query Polyfill을 개선하기 위해 노력하고 있습니다. 이 폴리필은 다음에서 일반적인 지원을 제공합니다.

  • Firefox 69 이상
  • Chrome 79 이상
  • Edge 79 이상
  • Safari 13.4 이상

압축 시 크기가 9KB 미만이며 MutationObserver와 함께 ScalingObserver를 사용하여 현재 안정적인 브라우저에서 사용할 수 있는 전체 @container 쿼리 구문을 지원합니다.

  • 개별 쿼리(width: 300pxmin-width: 300px)
  • 범위 쿼리(200px < width < 400pxwidth < 400px)
  • 속성 및 키프레임의 컨테이너 상대 길이 단위(cqw, cqh, cqi, cqb, cqmin, cqmax)

컨테이너 쿼리 폴리필 사용

폴리필을 사용하려면 문서 헤드에 다음 스크립트 태그를 추가합니다. :

<script type="module">
  if (!("container" in document.documentElement.style)) {
    import("https://unpkg.com/container-query-polyfill@^0.2.0");
  }
</script>

User-Agent를 기반으로 폴리필을 조건부로 전송하는 서비스를 사용하거나 자체 출처에서 자체 호스팅할 수도 있습니다.

최상의 사용자 환경을 위해 처음에는 폴백 콘텐츠에만 폴백을 사용하고 폴백을 표시할 준비가 될 때까지 @supports 쿼리를 사용하여 일시적으로 로드 표시기로 대체하는 것이 좋습니다.

@supports not (container-type: inline-size) {
  .container,
  footer {
    display: none;
  }

  .loader {
    display: flex;
  }
}

충분히 빠른 네트워크 및 기기 또는 컨테이너 쿼리를 기본적으로 지원하는 기기에서는 이 로드 표시기가 표시되지 않습니다.

새로운 Polyfill 기능

업데이트된 폴리필은 다음을 지원합니다.

  • 중첩된 @container 규칙
  • @supports@media 쿼리 아래에 @container 규칙을 중첩하거나 그 반대로 하는 것이 지원됩니다.
  • @supports (container-type: inline-size)와 같은 조건부 CSS는 폴리필이 로드된 후에 통과합니다.
  • 완전한 CSS 구문 지원 (구문적으로 유효한 위치에 주석을 넣어도 더 이상 문제가 없음)
  • 세로 쓰기 모드(writing-mode를 통해)
  • 컨테이너 상대 단위(cqw, cqh 등)는 쿼리 조건, 속성 선언, 애니메이션 키프레임 내에서 지원됩니다. remem는 쿼리 조건에서 지원됩니다.
  • 확장된 컨테이너 쿼리 문법:
    • 범위 문법(예: (200px < width < 400px))
    • 등식 쿼리(예: (width = 200px))
  • ::before::after와 같은 가상 요소
  • :is(...)/:where(...)가 없는 브라우저는 선택적 해결 방법을 통해 지원됩니다.
  • orientationaspect-ratio 기능 쿼리
  • 기능을 기반으로 쿼리를 올바르게 필터링합니다. 예를 들어 container: inline-size에서 height를 쿼리하는 것이 가로 쓰기 모드에서 올바르게 허용되지 않습니다.
  • DOM 변형(예: 런타임에 <style><link> 요소 삭제)

폴리필 제한사항 및 경고

컨테이너 쿼리 폴리필을 사용하는 경우 다음과 같은 몇 가지 누락된 기능에 주의해야 합니다.

  • Shadow DOM은 아직 지원되지 않습니다.
  • 컨테이너 상대 단위 (예: cqwcqh)는 @media 쿼리 조건에서 지원되지 않습니다.
    • Safari: 15.4 이전의 애니메이션 키프레임에서는 컨테이너 상대 단위가 지원되지 않습니다.
  • calc(), min(), max() 또는 기타 수학 함수는 아직 쿼리 조건에서 지원되지 않습니다.
  • 이 폴리필은 인라인 및 동일한 출처 CSS에서만 작동합니다. 교차 출처 스타일시트와 iframe의 스타일시트(폴리필이 수동으로 로드되는 경우 제외)는 지원되지 않습니다.
  • layoutstyle 컨테이너는 기본 브라우저 지원이 필요합니다.
    • Safari 15.4 이상
    • Firefox는 현재 스타일 컨테이닝을 지원하지 않지만 작업 중입니다.

경고

  • FIDCLS에 영향을 미치지 않도록 폴리필은 동기식으로 로드되더라도 첫 번째 레이아웃이 언제 발생할지 보장하지 않습니다. 단, LCP가 부당하게 지연되지 않도록 하기 위해 노력합니다. 즉, 첫 페인트에 의존해서는 안 됩니다.
  • ResizeObserver Loop Errors를 생성합니다. 원래 폴리필도 이렇게 하지만 언급할 가치가 있습니다. 이는 쿼리를 평가한 후 container-type: inline-size의 블록 크기가 변경될 가능성이 높지만 ResizeObserver에는 블록 크기 변경사항을 신경 쓰지 않는다고 알릴 방법이 없기 때문입니다.
  • 이 폴리필은 웹 플랫폼 테스트를 기준으로 테스트되었으며, JavaScript API와 같은 특정 기능은 폴리필되지 않으므로 통과율이 의도적으로 70%에 가깝습니다.
  • 다음보다 오래된 브라우저를 사용하는 사용자의 2.23%에게는 :where() 해결 방법이 필요합니다.
    • Safari 14
    • Chromium 88
    • 에지 88
    • Samsung Internet 15
    • Firefox 78