@container 쿼리 — 컴포넌트 단위 반응형의 표준
viewport가 아닌 컨테이너 크기로 분기하는 표준. 사이드바·메인·그리드 어디에 놓여도 자기 크기에 맞게 적응하는 카드/위젯 패턴을 만듭니다.
미디어 쿼리는 viewport 기준으로 동작합니다. 그러나 카드 컴포넌트가 사이드바에 들어갔을 때와 메인에 들어갔을 때, 같은 viewport에서도 다르게 보여야 하는 경우가 많습니다. @container 쿼리는 컨테이너 자체의 크기를 기준으로 스타일을 분기해, 컴포넌트가 어디에 놓이든 자기 크기에 맞게 적응하게 해줍니다.
1. 기본 문법
1.card-container { 2 container-type: inline-size; 3 /* 가로 크기를 컨테이너 쿼리 기준으로 */ 4} 5 6.card { 7 display: block; 8} 9 10@container (min-width: 480px) { 11 .card { 12 display: grid; 13 grid-template-columns: 120px 1fr; 14 gap: 16px; 15 } 16}
.card-container가 480px 이상이면 카드가 2열로 바뀝니다. viewport가 아니라 컨테이너 크기 기준입니다.
2. 이름이 있는 컨테이너
여러 컨테이너가 중첩될 때 어떤 컨테이너 기준인지 명시할 수 있습니다.
1.sidebar { container-type: inline-size; container-name: sidebar; } 2.main { container-type: inline-size; container-name: main; } 3 4@container sidebar (max-width: 240px) { 5 .nav-label { display: none; } 6} 7@container main (min-width: 720px) { 8 .article-aside { float: right; width: 240px; } 9}
이름을 통해 정확히 어떤 컨테이너의 크기를 보고 분기할지 결정합니다.
3. 카드 그리드에 응용
같은 카드를 1컬럼/2컬럼/3컬럼 그리드 어디에 넣어도 자기 크기에 맞게 변형됩니다.
1.grid { 2 display: grid; 3 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); 4 gap: 16px; 5} 6 7.grid > article { 8 container-type: inline-size; 9} 10 11article > .layout { 12 display: grid; 13 grid-template-columns: 1fr; /* 좁을 때 */ 14 gap: 12px; 15} 16 17@container (min-width: 480px) { 18 article > .layout { 19 grid-template-columns: 120px 1fr; /* 넓을 때 가로 배치 */ 20 } 21}
같은 카드가 모바일에선 세로, 태블릿에선 가로로 — 위에 있는 viewport 미디어 쿼리 없이.
4. 컨테이너 단위 (cqw / cqi / cqh)
컨테이너 기준 단위도 같이 쓸 수 있습니다.
1.title { 2 font-size: clamp(14px, 4cqi, 18px); 3 /* 컨테이너 inline 크기의 4% */ 4}
cqi (inline), cqb (block), cqw (width), cqh (height) 등 viewport 단위(vw, vh)의 컨테이너 버전입니다.
5. 주의할 점
- 컨테이너로 지정된 요소는 자식의
position: fixed/absolute의 기준이 아닙니다. 별도position: relative가 필요합니다. container-type: inline-size는 가로만,size는 가로/세로 모두입니다.size는 자식의100%기반 레이아웃에 영향을 줄 수 있어 주의.- 미디어 쿼리를 완전히 대체하지 않습니다. 폰트 크기, 다크 모드, 모션 선호 등은 여전히 미디어 쿼리.
- 브라우저 지원: Chrome 105+, Safari 16+, Firefox 110+.
6. 정리
| 미디어 쿼리 | 컨테이너 쿼리 |
|---|---|
| viewport 기준 | 컨테이너 기준 |
| 페이지 전체 레이아웃 | 컴포넌트 자기 크기 |
min-width: 768px | @container (min-width: 480px) |
컴포넌트가 "어디 놓일지"를 신경 쓰지 않고 "내가 얼마나 크냐"만 보면 됩니다. 디자인 시스템 카드/위젯이 페이지 어디에 들어가도 자연스럽게 동작하는 게 가장 큰 효과입니다.
참고: MDN — CSS Container Queries / Web.dev container queries.