이제 컨테이너 쿼리를 사용할 수 있습니다.
기쁜 소식입니다! 가장 많은 요청이 있었던 개발자 기능 중 하나가 웹 브라우저에 도입되기 시작했습니다. 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
규칙을 사용하여 가장 가까운 상위 요소를 기준으로 스타일을 설정할 수 있습니다. 카드가 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% |
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에서는 개발자가 편하게 이를 프로젝트에 통합할 수 있도록 하고, 브라우저 지원이 거기에서 큰 부분을 차지한다는 점을 인지할 수 있기를 바랍니다. 이러한 이유로 Google에서는 컨테이너 쿼리 Polyfill을 개선하기 위해 노력해 왔습니다. 이 폴리필은 다음에서 일반적으로 지원됩니다.
- Firefox 69 이상
- Chrome 79 이상
- Edge 79 이상
- Safari 13.4 이상
압축하면 크기가 9KB 미만이며 MutationObserver와 함께 ResizeObserver를 사용하여 현재 안정적인 브라우저에서 사용할 수 있는 전체 @container 쿼리 구문을 지원합니다.
- 불연속 쿼리 (
width: 300px
및min-width: 300px
). - 범위 쿼리 (
200px < width < 400px
및width < 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
등)는 쿼리 조건, 속성 선언 및 애니메이션 키프레임 내에서 지원됩니다.rem
및em
는 쿼리 조건에서 지원됩니다. - 확장된 컨테이너 쿼리 구문:
- 범위 구문 (예:
(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
격리에는 기본 브라우저 지원이 필요합니다.- Safari 15.4 이상
- Firefox는 현재 스타일 포함을 지원하지 않지만, 이를 지원하기 위해 작업 중입니다.
경고
- FID 및 CLS의 영향을 방지하기 위해 폴리필은 LCP가 불합리하게 지연되지 않도록 하는 경우를 제외하고 첫 번째 레이아웃이 동기식으로 로드되더라도 첫 번째 레이아웃이 발생하는 시기를 보장하지 않습니다. 즉, 첫 페인트에 의존해서는 안 됩니다.
ResizeObserver Loop Errors
를 생성합니다. 원래 폴리필도 이 작업을 수행하지만, 주목할 만한 가치가 있습니다. 이는 쿼리를 평가한 후에container-type: inline-size
의 블록 크기가 변경될 가능성이 높지만ResizeObserver
에서는 블록 크기 변경에 신경 쓰지 않는다는 것을 알릴 방법이 없기 때문입니다.- 이 폴리필은 웹 플랫폼 테스트를 거쳐 테스트되었으며 JavaScript API와 같은 특정 기능은 폴리필되지 않아 70% 에 합격했습니다. 따라서 통과율은 의도적으로 70%에 가까워집니다.
- 다음보다 오래된 브라우저 사용자 2.23% 의 경우
:where()
해결 방법이 필요합니다.- 사파리 14
- 크롬 88
- 에지 88
- 삼성 인터넷 15
- 파이어폭스 78