출근한입

IT 뉴스 · 짧은 요약

← 목록으로
CSS

CSS Container Queries, 미디어 쿼리의 상위 호환이 온다

뷰포트가 아닌 부모 요소 너비에 반응하는 컨테이너 쿼리를 정리했습니다. 사이드바·카드 같은 컴포넌트 단위 반응형이 훨씬 쉬워집니다.

핵심 3줄 요약

  1. 컨테이너 쿼리는 브라우저 뷰포트 대신 특정 부모 요소의 크기에 따라 스타일을 바꿀 수 있는 CSS 기능입니다.
  2. 사이드바가 접히든 펼치든, 카드가 2열이든 1열이든 — 컴포넌트 자기 영역 너비만 보면 되니까 미디어 쿼리보다 직관적이고 유지보수가 쉬워집니다.
  3. 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을 스크립트 한 줄로 붙일 수 있습니다.

출근한입 한 줄: "이 카드, 사이드바 열어도 깨지나요?" — 이제 이런 질문 자체가 사라집니다.