컨테이너 쿼리 사용해 보기
기쁜 소식입니다. 가장 많은 요청이 있었던 개발자 기능 중 하나가 웹브라우저에 출시되기 시작했습니다. 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;
}
이 코드는 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: 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 구문 지원 (구문적으로 유효한 위치에 주석을 넣어도 더 이상 문제가 없음)
- 세로 쓰기 모드(writing-mode를 통해)
- 컨테이너 상대 단위(
cqw
,cqh
등)는 쿼리 조건, 속성 선언, 애니메이션 키프레임 내에서 지원됩니다.rem
및em
는 쿼리 조건에서 지원됩니다. - 확장된 컨테이너 쿼리 문법:
- 범위 문법(예:
(200px < width < 400px)
) - 등식 쿼리(예:
(width = 200px)
)
- 범위 문법(예:
::before
및::after
와 같은 가상 요소:is(...)
/:where(...)
가 없는 브라우저는 선택적 해결 방법을 통해 지원됩니다.orientation
및aspect-ratio
기능 쿼리- 기능을 기반으로 쿼리를 올바르게 필터링합니다. 예를 들어
container: inline-size
에서height
를 쿼리하는 것이 가로 쓰기 모드에서 올바르게 허용되지 않습니다. - DOM 변형(예: 런타임에
<style>
및<link>
요소 삭제)
폴리필 제한사항 및 경고
컨테이너 쿼리 폴리필을 사용하는 경우 다음과 같은 몇 가지 누락된 기능에 주의해야 합니다.
- 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%에 가깝습니다.
- 다음보다 오래된 브라우저를 사용하는 사용자의 2.23%에게는
:where()
해결 방법이 필요합니다.- Safari 14
- Chromium 88
- 에지 88
- Samsung Internet 15
- Firefox 78