같은 상품 카드를 만들었다. 넓은 본문에 한 줄로 늘어놓을 땐 사진 옆에 제목과 설명이 가지런히 붙어 보기 좋다. 그런데 그 똑같은 카드를 좁은 사이드바에 넣는 순간, 사진이 칸을 다 잡아먹고 제목은 두 글자마다 줄이 바뀌며 우습게 잘린다. 화면 크기는 그대로인데 말이다.
왜 미디어 쿼리로는 이 문제가 안 풀리나
지난 10년간 반응형의 기준은 오직 하나, 브라우저 화면(뷰포트)의 너비였다. 미디어 쿼리는 "화면이 768px보다 좁으면 세로로 쌓아라" 같은 규칙만 쓸 수 있다. 문제는 같은 화면 안에서도 요소가 놓인 칸의 크기는 제각각이라는 점이다. 데스크톱 화면 한 장 안에 넓은 본문 칸과 좁은 사이드바 칸이 동시에 있으면, 화면 너비 하나만 보는 규칙으로는 두 칸을 동시에 만족시킬 수 없다. 한쪽을 살리면 다른 쪽이 깨진다.
그래서 지금까지는 같은 카드를 본문용·사이드바용으로 두 벌 만들거나, 자바스크립트로 칸 너비를 재서 클래스를 갈아끼우는 식으로 우회했다. 코드는 두 배가 되고 유지보수는 골치가 된다.
컨테이너 쿼리는 무엇이 다른가
컨테이너 쿼리(Container Queries)는 기준을 바꾼다. 화면 전체가 아니라 그 요소가 실제로 담겨 있는 부모 칸의 크기를 보고 반응한다. 카드를 감싼 칸이 좁으면 사진을 위로 올리고 글씨를 줄이고, 그 칸이 넓으면 사진을 옆에 두고 설명을 펼친다. 카드는 한 벌만 만들어 두면, 본문에 넣든 사이드바에 넣든 자기가 놓인 칸을 스스로 읽고 알아서 모양을 바꾼다.
덕분에 컴포넌트가 맥락에서 독립한다. "이 카드는 어느 페이지의 어느 위치에 들어갈까"를 미리 걱정할 필요가 없다. 어디에 떨어뜨려도 그 칸에 맞게 행동하는, 진짜 재사용 가능한 부품이 된다.
cqw·cqi 같은 새 단위도 함께 왔다
컨테이너 기준의 새 길이 단위도 생겼다. 칸 너비의 1%를 뜻하는 단위로 글자 크기를 지정하면, 칸이 넓어질수록 제목이 자연스럽게 커지고 좁아지면 작아진다. 화면이 아니라 담긴 공간에 비례해 타이포가 숨 쉬는 셈이다.
실무에서 이렇게 쓰인다
- 상품·블로그 카드: 한 벌로 만들어 본문 그리드와 사이드바에 동시에 재사용
- 대시보드 위젯: 위젯을 좁은 칸에 끌어다 놓으면 숫자만, 넓히면 그래프까지 펼쳐 보여주기
- 네비게이션·필터 바: 들어가는 영역 폭에 따라 가로 메뉴와 햄버거 메뉴를 스스로 전환
- 디자인 시스템: 컴포넌트 한 개의 동작을 페이지마다 다시 손보지 않아도 되는 구조
지금 도입해도 될까
컨테이너 쿼리는 이미 크롬·사파리·파이어폭스 최신 버전에서 모두 정식 지원된다. 2023년부터 주요 브라우저에 자리를 잡았고, 지금은 실무에 충분히 쓸 만큼 안정적이다. 구형 브라우저가 걱정된다면 미디어 쿼리를 기본값으로 두고 컨테이너 쿼리를 그 위에 얹는 식으로, 깨지지 않게 점진적으로 적용할 수 있다.
핵심은 발상의 전환이다. "화면이 얼마나 큰가"가 아니라 "이 요소가 지금 얼마만 한 칸에 담겼는가"를 묻기 시작하면, 페이지마다 예외 처리로 덧대던 군더더기가 사라진다.
CYAN은 작은 회사 웹사이트를 만들 때도 이렇게 한 번 만들어 어디서나 안 깨지는 구조를 기본으로 삼는다. 화면이 아니라 콘텐츠가 놓인 자리를 기준으로 설계해 두면, 나중에 페이지를 늘리거나 레이아웃을 바꿔도 카드 하나하나를 다시 손볼 일이 줄어들기 때문이다. 눈에 보이는 화려함보다, 어디에 두어도 무너지지 않는 단단함이 오래가는 사이트를 만든다.