CSS
CSS Container Queries, 미디어 쿼리의 상위 호환이 온다
뷰포트가 아닌 부모 요소 너비에 반응하는 컨테이너 쿼리를 정리했습니다. 사이드바·카드 같은 컴포넌트 단위 반응형이 훨씬 쉬워집니다.
핵심 3줄 요약
- 컨테이너 쿼리는 브라우저 뷰포트 대신 특정 부모 요소의 크기에 따라 스타일을 바꿀 수 있는 CSS 기능입니다.
- 사이드바가 접히든 펼치든, 카드가 2열이든 1열이든 — 컴포넌트 자기 영역 너비만 보면 되니까 미디어 쿼리보다 직관적이고 유지보수가 쉬워집니다.
- IE를 제외한 모든 주요 브라우저에서 지원되고, Tailwind CSS v4에서는
@container/@md:같은 유틸리티로 바로 쓸 수 있습니다.
미디어 쿼리 vs 컨테이너 쿼리
| 구분 | 미디어 쿼리 (@media) | 컨테이너 쿼리 (@container) |
|---|---|---|
| 기준 | 브라우저 뷰포트 너비 | 부모 요소 너비 |
| 사이드바 영향 | 사이드바 열림/닫힘에 따라 별도 분기 필요 | 본문 영역 너비만 보면 됨 |
| 재사용성 | 같은 컴포넌트도 배치 위치마다 따로 작성 | 어디에 놓든 한 벌로 해결 |
| 브라우저 지원 | 전 브라우저 | IE 제외 전 브라우저 |
미디어 쿼리 시절에는 사이드바 '확장 모드'와 '심플 모드'를 각각 계산해서 @media 를 두 벌 써야 했습니다. 컨테이너 쿼리를 쓰면 본문 main 요소 하나만 컨테이너로 잡아 놓고, 그 안에서 너비 기준으로 한 번만 작성하면 됩니다.
사용법 3단계
1단계: 컨테이너 등록
반응형을 적용하고 싶은 부모 요소에 container-type과 선택적으로 container-name을 지정합니다.
.card-wrapper {
container-name: card;
container-type: inline-size;
}
/* 단축 표기 */
.card-wrapper {
container: card / inline-size;
}
container-type 값은 보통 inline-size(너비 기준)를 가장 많이 씁니다. size는 높이까지 감지하지만 실무에서는 드뭅니다.
2단계: @container 규칙 작성
@media를 쓰던 방식과 거의 동일합니다.
/* 이름 없이 → 가장 가까운 컨테이너에 반응 */
@container (min-width: 500px) {
.card { flex-direction: row; }
}
/* 이름 지정 → 특정 컨테이너에만 반응 */
@container card (min-width: 500px) {
.card { flex-direction: row; }
}
3단계: 컨테이너 단위 활용 (선택)
vw/vh 처럼 컨테이너 기준 단위도 있습니다.
| 단위 | 의미 |
|---|---|
cqw | 컨테이너 너비의 1% |
cqh | 컨테이너 높이의 1% |
cqi | 인라인 방향 크기의 1% |
cqb | 블록 방향 크기의 1% |
@container (min-width: 400px) {
h2 { font-size: calc(1rem + 2cqi); }
}
Tailwind CSS v4에서 쓰기
Tailwind v4는 컨테이너 쿼리를 코어에 내장하고 있어서 별도 플러그인 없이도 됩니다.
<!-- 부모를 컨테이너로 -->
<div class="@container">
<!-- 컨테이너 너비 28rem 이상이면 row 배치 -->
<div class="flex flex-col @md:flex-row">
...
</div>
</div>
@sm, @md, @lg … @7xl 까지 기본 제공되고, @[500px]: 처럼 임의 값도 쓸 수 있습니다.
실무 팁
- 카드 컴포넌트를 만들 때 부모에
@container를 걸어 두면, 2열/3열 그리드 어디에 넣든 카드가 알아서 최적의 모양을 잡습니다. - 기존
@media를 전부 바꿀 필요는 없습니다. 전체 레이아웃은 미디어 쿼리, 컴포넌트 내부는 컨테이너 쿼리로 나누는 게 현실적입니다. - 구형 브라우저가 걱정되면
container-query-polyfill을 스크립트 한 줄로 붙일 수 있습니다.
출근한입 한 줄: "이 카드, 사이드바 열어도 깨지나요?" — 이제 이런 질문 자체가 사라집니다.