[CSS] @container 컨테이너 쿼리 사용하기

김방울·2024년 8월 5일
1

HTML / CSS

목록 보기
5/6

@mixin mb-lg {
  @media (max-width: $size__mb-lg) {
    @content;
  }
}

반응형 웹을 제작할 때, 위와 같이 미디어 쿼리를 사용하는 것이 일반적이었을 것입니다. 미디어 쿼리는 브라우저 전체의 크기를 기준으로 스타일을 적용하기 때문에 특정 요소의 크기에 따라 스타일을 적용하고자 하면 em, % 등의 단위를 사용하거나 JavaScript를 사용하여 요소의 크기를 감지해 주여야 했습니다. @container 쿼리를 사용하면 브라우저 뷰포트 기준이 아닌, 🌟특정 요소의 크기🌟에 따른 반응형 웹 구현이 가능합니다.

기준이 될 컨테이너 지정하기

.container{
	container-type: inline-size; /* 컨테이너 타입 지정 */
    container-name: parent-container; /* 컨테이너 이름 지정 */
    container: parent-container / inline-size; /* background, margin처럼 단축 형태로 사용할 경우 */

}

기준이 될 요소의 CSS에 container-type을 사용하여 쿼리 컨테이너로 지정할 수 있습니다. 또한, container-name 속성을 지정하여 포함 컨텍스트(컨테이너 쿼리를 적용할 범위 지정 시 사용)를 명명할 수 있습니다.

container-type 속성

  • size: 인라인 및 블록 축에 대해서 컨테이너 쿼리를 설정합니다. 높이를 기반으로 자식 요소의 콘텐츠를 제어할 때 사용합니다.
  • inline-size: 인라인 축에 대하여 컨테이너 쿼리를 설정합니다. 너비를 기반으로 자식 요소의 콘텐츠를 제어할 수 있으며, 가장 일반적으로 사용됩니다.
  • normal: 해당 요소는 어떠한 쿼리 컨테이너도 아니지만, 컨테이너 스타일 쿼리에 대한 쿼리 컨테이너로 남아 있습니다. (일반적으로 지정할 필요가 없습니다.)

sizeinline-size에 대한 개념이 헷갈렸는데,
일반적으로 너비 기준으로 자식 요소의 스타일을 조정할 수 있는 inline-size를 많이 사용할 것이고 컨테이너에 이미 높이가 지정되어 있으며,orientation: portrait 등 높이를 기반으로 자식 요소의 스타일을 지정할 때에는 size를 사용하는 것으로 이해하였습니다. (https://stackoverflow.com/questions/74825464/what-is-the-difference-between-size-and-inline-size-of-container-type-css-pr)

컨테이너 쿼리 등록하기

.container{
  container-type: inline-size; /* 컨테이너 타입 지정 */
  border: 1px solid red;
  max-width: 800px;
  padding: 24px;
}

.box{
  width: 100px;
  height: 100px;
  background: #000;
}

@container (min-width: 500px) {
  .box{
    width: 200px;
    height: 200px;
    border-radius: 100%;
  }
}

미디어 쿼리를 등록했던 것과 마찬가지로, @container 구문을 사용하여 스타일을 지정해 줍니다. 위 코드는 .container 요소가 500px 이상일 경우, width와 height 속성이 200px로 지정되고 사각형 형태에서 원 형태로 변경됩니다.

.container{
  container-name: container-name; /* 컨테이너 이름 지정 */
  container-type: inline-size; /* 컨테이너 타입 지정 */
...
}
@container container-name (min-width: 500px) {
  .box{
	...(컨테이너 쿼리 스타일 지정)
  }
}

여러 컨테이너가 중첩되어 있을 경우, @container <컨테이너 이름> 구문을 통해 특정 컨테이너에 대한 스타일만 지정할 수 있습니다.

컨테이너 조건 내 사용할 수 있는 설명자

min-width, max-width 뿐만이 아닌 여러 설명자를 조건으로 사용할 수 있습니다.

  • aspect-ratio: 컨테이너의 너비와 높이의 비, 즉 종횡비 값을 표현
  • block-size: 컨테이너의 블록 축의 값
  • inline-size: 컨테이너의 인라인 축의 값
  • orientation: 컨테이너의 방향(landscape, portrait)
  • width: 컨테이너의 너비
  • height: 컨테이너의 높이

container-typesize로 지정하고, orientation: portrait 를 조건에 사용해 보았습니다.

.container{
  container-name: container-name;
  container-type: size; /* 컨테이너 타입 지정 */
  border: 1px solid red;
  max-width: 600px;
  height: 500px;
  padding: 24px;
}

.box{
  width: 100px;
  height: 100px;
  background: #000;
}

@container container-name (orientation: portrait) {
  .box{
    width: 200px;
    height: 200px;
    border-radius: 100%;
  }
}


컨테이너의 높이가 너비보다 길어질 경우, 사진과 같이 컨테이너 쿼리가 적용된 것을 확인할 수 있습니다.

컨테이너 쿼리 길이 단위

컨테이너 쿼리를 사용할 경우 %, em 뿐만이 아닌 컨테이너 쿼리 길이 단위를 상대 단위로 사용할 수 있습니다.

  • cqw: 전체 컨테이너 너비의 1%
  • cqh: 쿼리 컨테이너 높이의 1%
  • cqi: 쿼리 컨테이너의 인라인 크기의 1%
  • cqb: 쿼리 컨테이너의 블록 크기의 1%
  • cqmin: cqb, cqi 중 더 작은 값
  • cqmax: cqb, cqi 중 더 큰 값
.container{
  container-name: container-name;
  container-type: inline-size; /* 컨테이너 타입 지정 */
  border: 1px solid red;
  max-width: 1000px;
  padding: 24px;
}

@container container-name (min-width: 500px) {
  .text-title{
    font-size: 5cqi; /* 컨테이너 쿼리 길이 단위로 설정 */
  }
}

컨테이너 쿼리 지원 범위

2024년 8월 기준으로 IE를 제외한 Chrome, Edge, Safari 등 대부분의 모던 브라우저에서는 컨테이너 쿼리를 지원하고 있는 모습을 볼 수 있습니다.👀
다만 대체적으로 2022년 이전 버전의 브라우저들은 지원하고 있지 않아서, 미디어 쿼리를 대체해서 바로 실무에서 사용하기에는 조금 어려워 보입니다.💦

하지만 개인적으로 컴포넌트 기반으로 개발하는 리액트, 뷰 등 모던 프론트엔드 생태계와 컴포넌트 기반으로 UI를 문서화하는 Storybook과 찰떡궁합인 기능이라고 생각이 듭니다. 이제는 너무나도 많이 쓰이는 grid 속성처럼 머지않아 컨테이너 쿼리도 어렵지 않게 볼수 있지 않을까 조심스럽게 생각해봅니다.

참고자료

profile
코딩하는 고양이🐱 / UI Developer, Front-end Developer

0개의 댓글