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

이제 컨테이너 쿼리를 사용할 수 있습니다.

기쁜 소식입니다! 가장 많은 요청이 있었던 개발자 기능 중 하나가 웹 브라우저에 도입되기 시작했습니다. 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 규칙을 사용하여 가장 가까운 상위 요소를 기준으로 스타일을 설정할 수 있습니다. 카드가 1열에서 2열로 이동할 수 있는 위 이미지와 같은 디자인의 경우 다음과 같이 작성합니다.

@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;
}

이 코드는 글꼴 크기를 컨테이너 인라인 크기의 15% 로 만듭니다. 즉, 인라인 크기 (너비)가 커질수록 커지고 작아질수록 작아집니다. 여기서 더 나아가 clamp() 함수를 사용하여 서체에 최소 및 최대 크기 제한을 부여하고 컨테이너 크기에 따라 반응형으로 크기를 조절합니다.

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

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

이 데모에서는 한 단계 더 나아가 더 넓은 카드가 2열 뷰에 표시되는 것과 같이 더 작은 크기 범위를 갖도록 업데이트합니다.

컨테이너 쿼리 폴리필

컨테이너 쿼리는 매우 강력한 기능이므로, Google에서는 개발자가 편하게 이를 프로젝트에 통합할 수 있도록 하고, 브라우저 지원이 거기에서 큰 부분을 차지한다는 점을 인지할 수 있기를 바랍니다. 이러한 이유로 Google에서는 컨테이너 쿼리 Polyfill을 개선하기 위해 노력해 왔습니다. 이 폴리필은 다음에서 일반적으로 지원됩니다.

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

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

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

컨테이너 쿼리 폴리필 사용

polyfill을 사용하려면 문서 헤드에 다음 스크립트 태그를 추가하세요.

<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 구문 지원 (구문적으로 유효한 위치에 주석을 다는 데 더 이상 문제가 없습니다.)
  • 세로 쓰기 모드 (쓰기 모드를 통해)
  • 컨테이너 상대 단위 (cqw, cqh 등)는 쿼리 조건, 속성 선언 및 애니메이션 키프레임 내에서 지원됩니다. remem는 쿼리 조건에서 지원됩니다.
  • 확장된 컨테이너 쿼리 구문:
    • 범위 구문 (예: (200px < width < 400px))
    • 등호 쿼리 (예: (width = 200px))
  • ::before::after와 같은 가명 요소
  • :is(...)/:where(...)가 없는 브라우저는 선택적 해결 방법을 통해 지원됩니다.
  • orientationaspect-ratio 기능 쿼리
  • 기능에 따라 쿼리를 올바르게 필터링 (예: container: inline-size에서 height를 쿼리하는 것은 가로 쓰기 모드에서 올바르게 허용되지 않음)
  • DOM 변형 (예: 런타임에 <style><link> 요소 삭제)

Polyfill 제한사항 및 경고

컨테이너 쿼리 폴리필을 사용하는 경우 주의해야 할 몇 가지 누락된 기능이 있습니다.

  • 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% 에 합격했습니다. 따라서 통과율은 의도적으로 70%에 가까워집니다.
  • 다음보다 오래된 브라우저 사용자 2.23% 의 경우 :where() 해결 방법이 필요합니다.
    • 사파리 14
    • 크롬 88
    • 에지 88
    • 삼성 인터넷 15
    • 파이어폭스 78