Containment/Container queries

김동현·2026년 3월 21일

mdn 학습 번역 - CSS

목록 보기
70/190

안녕하세요! 프론트엔드 개발자 취업을 목표로 컴포넌트 주도 개발(CDD)과 스토리북(Storybook) 같은 최신 기술 생태계에 관심을 가지고 계신 걸로 알고 있는데요. 오늘 배우실 컨테이너 쿼리(Container Queries)는 바로 그 컴포넌트 주도 개발의 '꽃'이라고 할 수 있는, CSS 역사상 가장 혁신적이고 핫한 기능 중 하나입니다!

기존의 미디어 쿼리가 브라우저 화면 전체(뷰포트)를 기준으로 했다면, 컨테이너 쿼리는 컴포넌트가 속한 '부모 컨테이너'를 기준으로 스타일을 변경할 수 있게 해줍니다. 뷰포트의 제약에서 벗어나 컴포넌트 스스로 자신의 형태를 결정할 수 있게 되는 것이죠. 기술 및 임원 면접에서도 "미디어 쿼리와 컨테이너 쿼리의 차이점"이나 "컴포넌트 재사용성을 높이는 방법"을 묻는 질문이 자주 나오니 이번 기회에 확실히 다져두시면 정말 큰 무기가 될 겁니다. 자, 그럼 MDN 문서를 함께 살펴볼까요?


CSS 컨테이너 쿼리 (CSS container queries)

컨테이너 쿼리를 사용하면 부모 컨테이너의 특정 속성들을 기반으로 요소에 스타일을 적용할 수 있습니다. 그 기준이 되는 속성들은 다음과 같습니다:

  • 컨테이너의 크기 (size)
  • 컨테이너에 적용된 스타일 (styles)
  • 컨테이너 또는 스크롤 가능한 조상의 스크롤 상태 (scroll-state)

컨테이너 쿼리는 뷰포트(화면) 크기나 기기 특성에 따라 요소에 스타일을 적용하는 미디어 쿼리(media queries)의 훌륭한 대안입니다.

이 문서는 컨테이너 쿼리 사용에 대한 소개를 제공하며, 그중에서도 특히 '크기(size)' 컨테이너 쿼리에 초점을 맞추어 설명합니다. 다른 가이드에서는 스타일(style)스크롤 상태(scroll-state) 컨테이너 쿼리에 대해 자세히 다루고 있습니다.

Two different query types. First, a media query based on the viewport's width, which is the full width of the browser. Second, a container query based on the width of a container element.

이 문서에서 다룰 내용 (In this article)


컨테이너 크기 쿼리 사용하기 (Using container size queries)

컨테이너 쿼리가 컨테이너의 유형에 따라 스타일을 적용한다면, 컨테이너 '크기(size)' 쿼리는 컨테이너의 치수(dimensions)에 특별히 기반하여 스타일을 적용합니다. 컨테이너 크기 쿼리를 사용하려면, 요소에 격리 문맥(containment context)을 선언해야 합니다. 그래야 브라우저가 "아, 이 개발자가 나중에 이 컨테이너의 치수를 조회하려고 하겠구나"라고 알 수 있거든요.
이렇게 하려면 container-type 속성에 size, inline-size, 또는 normal 값을 지정해서 사용하면 됩니다.

이 값들은 각각 다음과 같은 효과를 가집니다:

size

이 쿼리는 컨테이너의 인라인(inline) 및 블록(block) 치수를 기준으로 작동합니다. 컨테이너에 레이아웃, 스타일, 그리고 크기 격리(containment)를 적용합니다.

inline-size

이 쿼리는 컨테이너의 인라인(inline) 치수를 기준으로 작동합니다. 요소에 레이아웃, 스타일, 그리고 인라인 크기 격리를 적용합니다.

normal

이 요소는 크기 컨테이너 쿼리의 대상 컨테이너가 되지 않지만, 스타일 컨테이너 쿼리의 대상 컨테이너로는 유지됩니다.

🧐 강사의 부연 설명: inline-size를 가장 많이 쓰는 이유
실무에서는 웹 페이지나 리스트 컴포넌트가 세로로 스크롤(블록 방향)되는 경우가 대부분입니다. 가로 너비(인라인 방향)의 변화에 따라 카드 UI의 형태가 바뀌는 경우가 압도적으로 많기 때문에, inline-size를 가장 흔하게 사용하게 됩니다.

제목과 약간의 텍스트가 있는 블로그 게시물용 카드 컴포넌트를 예로 들어 보겠습니다:

<div class="post">
  <div class="card">
    <h2>Card title</h2>
    <p>Card content</p>
  </div>
</div>

container-type 속성을 사용하여 이 카드에 대한 격리 문맥을 생성할 수 있습니다:

.post {
  container-type: inline-size;
}

그런 다음, @container @규칙을 사용하여 컨테이너 쿼리를 정의합니다.
아래 예제의 쿼리는 격리 문맥이 선언된 가장 가까운 조상 요소(이 경우 .post)의 크기를 기준으로 안쪽 요소들에게 스타일을 적용합니다. 구체적으로 말하자면, 컨테이너의 너비가 700px보다 넓을 경우 카드 제목(h2)에 더 큰 폰트 크기를 적용합니다:

/* Default heading styles for the card title */
.card h2 {
  font-size: 1em;
}

/* If the container is larger than 700px */
@container (width > 700px) {
  .card h2 {
    font-size: 2em;
  }
}

컨테이너 쿼리를 사용하면, 이 카드가 나중에 페이지의 어느 곳에 배치될지 매번 구체적으로 알 필요 없이 페이지의 여러 영역에서 카드를 마음껏 재사용할 수 있습니다. 카드를 감싸는 컨테이너가 700px보다 좁으면 카드 제목의 폰트가 작아지고, 700px보다 넓은 컨테이너 안에 있다면 카드 제목의 폰트가 자동으로 커질 것입니다.

컨테이너 쿼리의 문법에 대한 더 자세한 정보는 @container 페이지를 참고하세요.

격리 문맥 이름 지정하기 (Naming containment contexts)

이전 섹션에서는 컨테이너 쿼리가 격리 문맥이 있는 가장 가까운 조상을 찾아서 스타일을 적용했습니다. 하지만 container-name 속성을 사용하면 격리 문맥에 직접 이름을 지어줄 수도 있습니다. 이렇게 이름을 지정하고 나면, @container 쿼리에서 특정 컨테이너를 딱 집어서 타겟팅할 수 있게 됩니다.
다음 예제는 sidebar라는 이름의 격리 문맥을 생성합니다:

.post {
  container-type: inline-size;
  container-name: sidebar;
}

이제 @container @규칙을 사용하여 이 특정 격리 문맥을 타겟팅할 수 있습니다:

@container sidebar (width > 700px) {
  .card {
    font-size: 2em;
  }
}

격리 문맥의 이름 지정에 대한 더 많은 정보는 container-name 페이지에서 확인하실 수 있습니다.

단축 컨테이너 구문 (Shorthand container syntax)

격리 문맥을 선언하는 단축(shorthand) 방법으로 container 속성을 사용할 수 있습니다. / 를 기준으로 이름과 타입을 한 번에 작성합니다:

.post {
  container: sidebar / inline-size;
}

이 속성에 대한 더 자세한 내용은 container 레퍼런스에서 확인하세요.

컨테이너 쿼리 길이 단위 (Container query length units)

컨테이너 쿼리를 사용하여 컨테이너에 스타일을 적용할 때, 컨테이너 쿼리 전용 길이 단위를 사용할 수 있습니다.
이 단위들은 쿼리 대상인 컨테이너의 치수에 상대적인 길이를 지정합니다. 자신의 부모 컨테이너에 상대적인 길이 단위를 사용하는 컴포넌트들은 굳이 구체적인 길이 값을 다시 계산할 필요가 없기 때문에, 다양한 형태의 컨테이너 안에서 훨씬 더 유연하게 사용할 수 있습니다.

만약 쿼리에 적합한 대상 컨테이너가 없다면, 컨테이너 쿼리 길이 단위는 해당 축의 작은 뷰포트 단위(small viewport unit) (sv*)를 기본값으로 사용하게 됩니다.

컨테이너 쿼리의 길이 단위들은 다음과 같습니다:

  • cqw: 쿼리 컨테이너 너비의 1%
  • cqh: 쿼리 컨테이너 높이의 1%
  • cqi: 쿼리 컨테이너 인라인 크기의 1%
  • cqb: 쿼리 컨테이너 블록 크기의 1%
  • cqmin: cqicqb 중 더 작은 값
  • cqmax: cqicqb 중 더 큰 값

💡 강사의 실무 팁!
화면 전체를 기준으로 하는 vw, vh 단위에 익숙하시죠? 이것을 컴포넌트 관점으로 좁힌 것이 cqw, cqh라고 생각하시면 됩니다. 이 단위들을 max(), min(), clamp() 함수와 결합하면 부모 영역의 너비에 따라 폰트 크기가 물 흐르듯 자연스럽게 커지고 작아지는 플루이드 타이포그래피(Fluid Typography)를 컴포넌트 레벨에서 완벽하게 구현할 수 있습니다!

다음 예제는 cqi 단위를 사용하여 컨테이너의 인라인 크기를 기반으로 제목의 폰트 크기를 동적으로 설정하는 모습을 보여줍니다:

@container (width > 700px) {
  .card h2 {
    font-size: max(1.5em, 1.23em + 2cqi);
  }
}

이 단위들에 대한 추가 정보는 컨테이너 쿼리 길이 단위(Container query length units) 레퍼런스에서 확인하실 수 있습니다.


컨테이너 쿼리를 위한 대체 수단 (Fallbacks for container queries)

아직 컨테이너 쿼리를 지원하지 않는 구형 브라우저를 위해서는, gridflex를 사용하여 이 페이지에서 만든 카드 컴포넌트와 유사한 효과를 낼 수 있습니다.
다음 예제는 grid-template-columns 선언을 사용하여 카드 컴포넌트에 대한 2단 레이아웃을 생성합니다.

.card {
  display: grid;
  grid-template-columns: 2fr 1fr;
}

만약 더 작은 뷰포트를 가진 기기를 위해 단일 열(1단) 레이아웃을 사용하고 싶다면, 미디어 쿼리를 사용하여 그리드 템플릿을 변경할 수 있습니다:

@media (width <= 700px) {
  .card {
    grid-template-columns: 1fr;
  }
}

같이 보기 (See also)


MDN 개선에 참여하기 (Help improve MDN)

이 페이지가 도움이 되셨나요?

기여하는 방법 알아보기 (Learn how to contribute)

이 페이지는 MDN 기여자들에 의해 2025년 11월 7일에 마지막으로 수정되었습니다 (MDN contributors).

profile
프론트에_가까운_풀스택_개발자

0개의 댓글