미디어 쿼리를 사용하는 것은 한때 다양한 화면 크기에 맞게 조정되는 반응형 사용자 인터페이스(UI) 디자인을 만드는 가장 효과적인 방법으로 간주되었습니다. 하지만 이 접근 방식에는 몇 가지 한계가 있었습니다. 미디어 쿼리에 의존하는 한 가지 중요한 단점은 화면 크기의 수정만으로 개별 요소의 스타일을 지정할 수 있지만 가장 가까운 컨테이너 요소는 지정할 수 없다는 것이었습니다.

컨테이너 쿼리의 등장은 앞서 언급한 문제를 해결하는 데 중요한 역할을 했으며, 모듈식 사용자 인터페이스 ‘컴포넌트’를 구성할 수 있다는 특징이 있는 React 및 Vue.js와 같은 기술의 보급 증가와도 궤를 같이 합니다. 컨테이너 쿼리를 활용하면 CSS 요소 스타일링에 대한 적응력 있고 반응적인 접근 방식을 개발할 수 있습니다.

본 발행물에 사용된 코드는 앞서 언급한 GitHub 저장소를 통해 액세스할 수 있으며, MIT 라이선스 조건에 따라 제한 없이 액세스할 수 있습니다. 해당 라이선스는 소프트웨어 제품의 자유로운 사용, 수정 및 배포를 허용하는 오픈 소스 계약으로, 비용이나 제한 없이 사용할 수 있습니다.

CSS 컨테이너 쿼리를 사용해야 하는 이유는 무엇인가요?

컨테이너 쿼리의 중요성을 이해하기 위해 아이디어를 쉽게 이해할 수 있는 시나리오를 제시하겠습니다. 데모를 진행하기 전에 앞서 언급한 GitHub 리포지토리에서 스타터 코드를 복제해 주세요.

리포지토리 복제에 성공하면 다음 코드를 실행합니다. 결과 페이지는 묘사된 이미지와 유사해야 하며, 체계적이고 구조화된 방식으로 정보를 표시하는 전자 인터페이스를 연상시키는 특성을 나타내야 합니다.

본원 구성은 두 개의 별개의 부분이 있는 직사각형 배열을 포함하며, 여기서 기본 영역은 만족스러운 것으로 보이는 반면, 기본 콘텐츠보다 상당히 작은 사이드바는 다소 압축된 것으로 보인다.

레이아웃의 구성은 브라우징 창의 크기 변화에 적응할 수 있으므로, 창의 크기가 줄어들면 카드의 방향이 수평 배열에서 수직으로 쌓인 형태로 변경됩니다.

미디어 쿼리를 활용함으로써 디스플레이의 전체 치수에 대응하여 구성 요소의 치수를 수정하는 것이 가능해집니다. 텍스트의 크기가 작아 읽을 수 없게 되면 시각적 요소가 쓰여진 콘텐츠 위에 겹쳐지는 세로 열로 배열이 변경됩니다.

이 글도 확인해 보세요:  Vite로 React 앱을 설정하는 방법

화면 크기가 800픽셀보다 작은 경우 플렉스박스 정렬을 활용하면 모든 요소가 서로 위에 배치됩니다. 반대로 화면 크기가 큰 경우 콘텐츠가 나란히 표시됩니다.

 @media(max-width: 800px) {
  .card {
    flex-direction: column;
  }
  .card-header {
    width: 100%;
  }
}

미디어 쿼리는 CSS를 사용한 웹 디자인의 기본 원칙으로 시작된 이래로 다양한 화면 크기와 기기에 반응하는 적응형 레이아웃을 만드는 데 없어서는 안 될 도구로 입증되었습니다. 하지만 미디어 쿼리만으로는 충분하지 않거나 미디어 쿼리의 한계로 인해 실용적이지 않은 경우도 있습니다.

앞의 그림과 같은 보조 요소가 존재하는 경우 사이드바 카드를 직접 선택하여 크기를 줄여야 합니다.

 .sidebar .card {
  /* Make the sidebar card smaller */
}

@media(max-width: 800px) {
  /* Style the page when the screen is narrower than 800px */
}

개별 요소를 선택하고 크기를 수동으로 조정해야 하므로 많은 수의 요소를 조작하는 것이 복잡해질 수 있습니다. 이로 인해 코드의 양이 증가하고 복잡성이 증가합니다.

컨테이너 쿼리는 이 문제에 대한 잠재적인 해결책을 제공합니다. 뷰포트를 크기 참조로 사용하는 것에 국한되지 않고 페이지의 모든 요소가 컨테이너 역할을 할 수 있으며, 그 치수가 미디어 쿼리의 기초가 될 수 있습니다.

컨테이너 쿼리를 만드는 방법

효과적인 컨테이너 쿼리를 구성하려면 먼저 컨테이너 역할을 할 특정 요소(이 예에서는 기본 구성 요소와 사이드바)를 식별해야 합니다. 그 후, 둘러싸는 블록 내에서 컨테이너 유형을 “인라인 크기”로 지정해야 최적의 결과를 얻을 수 있습니다.

 main, .sidebar {
  container-type: inline-size
}

앞서 언급한 코드 스니펫을 사용하면 컨테이너 조회를 통해 기본 세그먼트와 사이드바 영역 내부에 배치된 카드의 배치를 수정할 수 있습니다. 특히, 화면 너비가 500픽셀 이하인 경우 카드가 기본 배열이 아닌 세로로 배열된 열로 변환됩니다.

 @container(max-width: 500px) {
  .card {
     flex-direction: column;
  }
  .card-header {
    width: 100%;
  }
}

“이 미디어 쿼리는 디스플레이 화면의 크기를 측정하는 대신 상위 요소에 포함된 메인 및 사이드바 섹션의 크기를 평가합니다. 이 두 섹션의 너비를 합친 값이 500픽셀을 초과하면 가로 레이아웃이 사용됩니다. 반대로 너비가 이 임계값에 미치지 못하면 기본 세로 배열(플렉스박스의 일반적인 배열)이 사용됩니다.

이 글도 확인해 보세요:  슬랙에서 나만의 사용자 지정 슬래시 명령 만들기

이미지에 표시된 정보에 따르면 뷰포트의 너비가 500픽셀 이하인 경우 사이드바는 주 콘텐츠 영역에 비해 크기가 작기 때문에 세로 방향으로 배치되는 것으로 나타났습니다.반대로 뷰포트의 너비가 500픽셀보다 크면 메인 콘텐츠가 사이드바보다 크기 때문에 가로로 정렬된 구성이 유지됩니다. 뷰포트의 크기가 줄어들면 사이드바와 메인 콘텐츠의 너비가 모두 500픽셀 미만이 되면 세로 방향이 적용됩니다.

컨테이너 쿼리를 사용하여 컴포넌트의 크기를 조정하면 전체 탐색 영역이 아닌 컨테이너를 기준으로 크기를 조정할 수 있으므로 매우 유용합니다. 이는 여러 컴포넌트를 다루는 React 및 Vue 사용자에게 특히 유용합니다.

컨테이너 쿼리를 활용하면 지정된 컨테이너에 따라 사용자 인터페이스 요소의 크기를 조정할 수 있으므로 철저하게 캡슐화된 컴포넌트를 쉽게 생성할 수 있습니다.

컨테이너 이름 지정

“메인 컨테이너”가 정확히 무엇을 의미하는지 더 자세히 설명해 주시겠습니까? 또한 컨테이너가 유효한 것으로 간주되기 위해 충족해야 하는 특정 요구 사항이 있나요?

카드 요소가 다른 컨테이너 내에 중첩되어 있더라도 스타일 규칙은 지정된 클래스 이름을 가진 카드 요소의 바로 상위 컨테이너만 대상으로 합니다. 이는 더 정확한 선택기가 덜 구체적인 선택기보다 우선하는 CSS 선택기 특이성 원칙을 준수합니다.

다음 인스턴스는 본문 요소를 캡슐화 엔티티로 활용하는 것을 보여줍니다.

 body {
  container-type: inline-size;
}

본 시나리오에서는 본문, 메인 섹션 및 사이드 섹션의 세 가지 컨테이너를 활용합니다. 일반적으로 컨테이너 쿼리의 대상은 본문보다는 메인 섹션이나 사이드바에 더 가깝게 위치하는 경향이 있습니다. 따라서 컨테이너 쿼리는 앞서 언급한 섹션과의 근접성을 고려하여 메인 섹션과 사이드바 섹션을 컨테이너로 사용할 수밖에 없습니다.

본문 요소에 정의된 컨테이너 이름이 없는 기본 기능을 수정하려면 두 단계를 수행해야 합니다. 첫 번째 단계는 본문 요소에 특정 컨테이너 이름을 할당하는 것이고, 후속 단계는 페이지 내의 다른 HTML 요소에 본문 요소에 할당된 컨테이너 이름과 동일한 컨테이너 이름이 없는지 확인하는 것입니다.

 body {
  container-type: inline-size;
  container-name: body;
}

컨테이너 쿼리를 공식화할 때는 기호 ‘@’ 뒤에 특정 컨테이너 이름을 포함해야 합니다.

 @container body (max-width: 1000px){
  /* CSS rules that target the body container */
}

이 접근 방식을 사용하면 지정된 요소에 대해 가장 가까운 컨테이너를 선택하는 기본 옵션에 의존하지 않고 특정 요소를 의도적으로 선택하여 리셉터클 역할을 할 수 있습니다.간단히 말해서, 이 방법론을 사용하여 특정 용기를 선택하고 내용물의 위치를 세분화할 수 있습니다.

이 글도 확인해 보세요:  Vite 시작하기: 최고의 빌드 툴

컨테이너 유닛

컨테이너는 컨테이너 유닛을 활용할 수 있다는 점에서 추가적인 이점을 제공합니다. 이러한 단위는 뷰포트 단위와 유사하며 동일한 용도로 사용되지만 너비와 높이 설정을 위한 명명 규칙이 다릅니다. 컨테이너 단위는 컨테이너의 정확한 치수를 결정합니다.

CSS 미디어 쿼리에 대해 자세히 알아보기

CSS 컨테이너 쿼리를 활용하면 특정 컴포넌트를 미디어 쿼리의 참조로 활용할 수 있습니다. 이 방법은 호스팅 컨테이너에 관계없이 자율적으로 존재할 수 있는 독립적인 모듈형 요소를 만드는 데 매우 유용합니다. 그러나 컨테이너 쿼리의 원리는 미디어 쿼리의 원리와 유사하며, 이 분야에 대한 숙련도는 엘리트 CSS 개발자의 지위를 달성하는 데 매우 중요합니다.

By 최은지

윈도우(Windows)와 웹 서비스에 대한 전문 지식을 갖춘 노련한 UX 디자이너인 최은지님은 효율적이고 매력적인 디지털 경험을 개발하는 데 탁월한 능력을 발휘합니다. 사용자의 입장에서 생각하며 누구나 쉽게 접근하고 즐길 수 있는 콘텐츠를 개발하는 데 주력하고 있습니다. 사용자 경험을 향상시키기 위해 연구를 거듭하는 은지님은 All Things N 팀의 핵심 구성원으로 활약하고 있습니다.