컨테이너 쿼리

반응형

컨테이너 쿼리

Container Query

컨테이너 쿼리는 배치를 화면 전체가 아니라 그 요소를 담은 부모 컨테이너의 크기에 반응해 바꾸는 방식으로, 같은 컴포넌트를 어디에 놓아도 자리에 맞게 적응시킵니다.

반응하는 카드컨테이너 폭에 맞춰 배치가 바뀝니다.
컨테이너 300px
컨테이너 폭300px

정의

컨테이너 쿼리는 배치를 바꾸는 기준을 화면 전체가 아니라 그 요소를 담고 있는 부모 컨테이너의 크기로 삼는 방식입니다. 같은 카드 컴포넌트라도 넓은 자리에 놓이면 이미지와 글을 가로로 나란히 펼치고, 좁은 자리에 놓이면 위아래로 쌓아 스스로 모양을 바꿉니다. 브레이크포인트가 창문 전체의 크기를 보고 판단한다면, 컨테이너 쿼리는 그 요소가 실제로 서 있는 자리의 폭을 보고 판단합니다. 최신 CSS의 @container 규칙으로 사용하며, 컴포넌트가 놓인 문맥에 따라 알아서 적응하도록 설계할 때 쓰입니다.

왜 중요한가

현대의 화면은 하나의 컴포넌트를 여러 자리에서 재사용합니다. 같은 상품 카드가 넓은 본문에도, 좁은 사이드바에도, 두 칼럼 그리드 안에도 들어갑니다. 화면 너비만 기준으로 삼으면 사이드바처럼 좁은 자리에 놓인 카드도 화면이 넓다는 이유만으로 가로 배치를 고집해 우스꽝스럽게 찌그러집니다. 컨테이너 쿼리는 각 카드가 자기 자리의 폭을 직접 보고 판단하므로, 어디에 놓여도 그 공간에 맞는 모습으로 나타납니다. 덕분에 한 번 잘 만든 컴포넌트를 자리마다 따로 손보지 않고 여러 곳에 그대로 재사용할 수 있어, 디자인 시스템의 일관성과 유지보수성이 크게 올라갑니다. 컴포넌트가 자기 문맥을 스스로 책임지므로, 나중에 레이아웃을 바꾸거나 새 자리에 옮겨 놓아도 카드를 다시 손볼 필요가 없다는 점이 특히 든든합니다.

흔한 실수

  • 부모 요소에 컨테이너로 쓰겠다는 선언을 빠뜨리는 것입니다. @container는 대상이 될 부모에 container-type을 지정해 두어야 작동하는데, 이 선언을 잊으면 규칙이 조용히 무시되어 아무 변화도 일어나지 않습니다.
  • 모든 경우에 컨테이너 쿼리를 밀어붙이는 것입니다. 페이지 전체의 큰 골격을 바꾸는 일은 여전히 브레이크포인트가 더 적합합니다. 컨테이너 쿼리는 자리마다 재사용되는 독립 컴포넌트에 쓸 때 가장 빛납니다.
  • 컨테이너로 지정한 부모 자신의 크기를 그 안의 자식이 되받아 바꾸려는 것입니다. 컨테이너가 자식의 크기에 따라 다시 커지는 순환이 생기면 배치가 요동칠 수 있으니, 크기를 정하는 부모와 그에 반응하는 자식의 역할을 분명히 나눠 두어야 합니다.

실무 팁

  • 화면 전체가 아니라 그 요소가 놓인 자리를 기준으로 삼아야 할 때 컨테이너 쿼리를 떠올리세요. 사이드바든 본문이든 카드가 자기 폭에 맞춰 알아서 적응하므로, 어디서든 재사용 가능한 컴포넌트를 만들기에 특히 잘 맞습니다.
  • 아직 지원이 완전하지 않은 환경을 대비해 @supports로 폴백을 준비하세요. 컨테이너 쿼리가 없어도 기본 세로 배치처럼 무난한 형태로 보이도록 해 두면, 어느 브라우저에서든 콘텐츠가 깨지지 않고 안전하게 나타납니다.
  • 컨테이너에 이름을 붙여 두면 여러 겹으로 중첩된 상황에서도 어느 부모를 기준으로 삼을지 명확히 고를 수 있습니다. 카드가 카드 안에 들어가는 복잡한 구조에서도 의도한 컨테이너에 정확히 반응하게 되어 예상 밖의 배치 변화를 막아 줍니다.

관련 개념