컨테이너 쿼리가 출시되었습니다
기쁜 소식입니다. 가장 많은 요청이 있었던 개발자 기능 중 하나가 웹브라우저에 출시되기 시작했습니다. Chromium 105 및 Safari 16부터 이제 이러한 브라우저에서 크기 기반 컨테이너 쿼리를 만들고 컨테이너 쿼리 단위 값을 사용할 수 있습니다. 크기 기반 컨테이너 쿼리와 cq
단위를 더욱 쉽게 사용할 수 있도록 Chrome의 Aurora팀은 컨테이너 쿼리 폴리필을 업데이트하여 더 많은 브라우저와 사용 사례를 지원하고 있습니다. 이제 여러분은 이 강력한 기능을 자신 있게 사용할 수 있습니다.
컨테이너 쿼리란 무엇인가요?
컨테이너 쿼리는 상위 요소의 지형지물을 타겟팅하는 스타일 지정 로직을 작성하여 그 하위 요소의 스타일을 지정할 수 있게 하는 CSS 기능입니다. 상위 요소의 크기를 쿼리하여 진정한 구성요소 기반의 반응형 디자인을 만들 수 있습니다. 이는 표시 영역에 대한 크기 정보만 제공하는 미디어 쿼리와 같은 것보다 훨씬 세분화되고 유용한 정보입니다.
컨테이너 쿼리를 사용하면 페이지 내 위치에 따라 다르게 표시될 수 있는 재사용 가능한 구성요소를 작성할 수 있습니다. 이렇게 하면 페이지와 템플릿에서 훨씬 더 탄력적이고 반응성이 향상됩니다.
컨테이너 쿼리 사용
다음과 같은 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% |
cqmin | cqi 또는 cqb의 더 작은 값 |
cqmax | cqi 또는 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은 컨테이너 쿼리 폴리필을 개선하기 위한 작업을 진행해 왔습니다. 이 폴리필은 다음에서 일반적인 지원을 제공합니다.
- Firefox 69 이상
- Chrome 79 이상
- Edge 79 이상
- Safari 13.4 이상
압축 시 크기가 9KB 미만이며 MutationObserver와 함께 ReduceObserver를 사용하여 현재 안정적인 브라우저에서 사용할 수 있는 전체 @container 쿼리 문법을 지원합니다.
- 불연속 쿼리 (
width: 300px
및min-width: 300px
) - 범위 쿼리 (
200px < width < 400px
및width < 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 구문 지원 (구문적으로 유효한 위치에 주석을 넣어도 더 이상 문제가 없음)
- 세로 쓰기 모드 (쓰기 모드를 통함).
- 컨테이너 상대 단위 (
cqw
,cqh
등)는 쿼리 조건, 속성 선언, 애니메이션 키프레임 내에서 지원됩니다.rem
및em
는 쿼리 조건에서 지원됩니다. - 확장된 컨테이너 쿼리 구문:
<ph type="x-smartling-placeholder">
- </ph>
- 범위 구문 (예:
(200px < width < 400px)
) - 등호 쿼리 (예:
(width = 200px)
)
- 범위 구문 (예:
::before
및::after
와 같은 유사 요소:is(...)
/:where(...)
가 없는 브라우저는 선택적 해결 방법을 통해 지원됩니다.orientation
및aspect-ratio
기능 쿼리- 기능을 기반으로 쿼리를 올바르게 필터링 (예:
container: inline-size
에서height
을 쿼리하는 것은 가로 쓰기 모드에서 올바르게 허용되지 않음) - DOM 변형 (예: 런타임 시 삭제되는
<style>
및<link>
요소)
Polyfill 제한사항 및 경고
컨테이너 쿼리 폴리필을 사용하는 경우 다음 사항에 유의해야 합니다.
- Shadow DOM은 아직 지원되지 않습니다.
- 컨테이너 상대 단위 (예:
cqw
및cqh
)는@media
쿼리 조건에서 지원되지 않습니다.- Safari: 15.4 이전의 애니메이션 키프레임에서는 컨테이너 상대 단위가 지원되지 않습니다.
calc()
,min()
,max()
또는 기타 수학 함수는 아직 쿼리 조건에서 지원되지 않습니다.- 이 폴리필은 인라인 및 동일한 출처 CSS에서만 작동합니다. 교차 출처 스타일시트와 iframe의 스타일시트 (폴리필이 수동으로 로드되지 않은 경우)는 지원되지 않습니다.
layout
및style
포함에는 기본 브라우저 지원이 필요합니다. <ph type="x-smartling-placeholder">- </ph>
- Safari 15.4 이상
- Firefox는 현재 스타일 포함을 지원하지 않지만 이를 지원하기 위해 작업 중입니다.
경고
- FID 및 CLS에 영향을 주지 않기 위해 폴리필은 첫 번째 레이아웃이 발생하는 시점을 보장하지 않습니다. 단, 폴리필은 동기식으로 로드되더라도 LCP를 부당하게 지연시키려고 시도하지 않습니다. 즉, 첫 페인트에 의존해서는 안 됩니다.
ResizeObserver Loop Errors
를 생성합니다. 원래의 폴리필도 이 작업을 수행하지만 주목할 가치가 있습니다. 이는 쿼리를 평가한 후에container-type: inline-size
의 블록 크기가 변경될 가능성이 높지만ResizeObserver
가 블록 크기 변경에 관심이 없다고 말할 방법이 없기 때문입니다.- 이 폴리필은 웹 플랫폼 테스트로 테스트되었으며 JavaScript API와 같은 특정 기능은 폴리필되지 않아 70% 에 도달했으며 통과율은 의도적으로 70%에 가까워졌습니다.
- 다음보다 이전 버전 브라우저를 사용하는 2.23% 의 사용자에게는
:where()
해결 방법이 필요합니다. <ph type="x-smartling-placeholder">- </ph>
- Safari 14
- 크로미엄 88
- 에지 88
- 삼성 인터넷 15
- Firefox 78