미디어 쿼리는 뷰포트(화면 전체) 크기를 기준으로, 컨테이너 쿼리는 각 HTML 요소의 크기를 기준으로 삼는다.출처: https://web.dev/blog/cq-stable?hl=ko

미디어 쿼리의 단점

CSS에서 미디어 쿼리를 사용하는 이유는 주로 웹 페이지의 반응성과 유연성을 높이기 위해서입니다. 현제 HTML 문서를 조회하는 디바이스의 뷰포트 크기에 따라 화면의 요소를 유동적으로 조정하고 사용자에게 더 나은 경험을 제공합니다. 하지만 미디어 쿼리는 몇 가지 문제점을 가지고 있습니다. 그중 가장 큰 문제점은 바로 전체 화면 크기만을 고려한다는 점입니다. 프론트 엔드 개발에서 각 요소는 컴포넌트화되어 상대적인 위치를 가지게 됩니다. 다시 말해, 부모 컴포넌트가 차지하는 공간 내에서 문서의 흐름에 따라 배치됩니다.

 

이런 상황에서 뷰포트의 크기에 따라 컴포넌트를 조정하는 것은 쉬운 일이 아닐 수 있습니다. 특히, 부모 컨테이너가 존재하는 경우, 부모 컨테이너가 바뀌는 것에 따라 자식컨테이너의 크기와 배치가 변화해야 할 때, 중첩된 레이아웃 아래에서 반응성이 필요할 때 예상보다 더 많은 종단점을 설정해야 할 수 있습니다.

 

현대의 CSS는 이미 이 문제를 해결하는 방법을 몇 가지 가지고 있습니다. flex와 grid가 대표적인 방법입니다. 두 방법 모두 특정 요소 내에서 각자의 상대적인 위치와 간격을 조정할 때 아주 유용합니다. 화면의 정확한 크기를 알지 못해도 적절히 배치할 수 있습니다. 하지만 화면의 크기에 따라 더 많은 것을 변경해야 된다면 어떨까요? 미디어 쿼리를 사용해야 한다고 생각할 수 있습니다. 대부분의 상황에서는 정답입니다. 하지만 여러 단계로 중첩된 레이아웃에서 미디어 쿼리를 사용하는 건 복잡한 일입니다. 대안으로 컨테이너 쿼리를 사용하는 것이 좋을 수 있습니다.

컨테이너 쿼리

컨테이너 쿼리는 기존의 미디어 쿼리가 뷰포트(Viewport)나 디바이스 크기를 기준으로 스타일을 적용하는 것과는 다르게, 개별 요소(컨테이너)의 크기를 기준으로 스타일을 변경할 수 있습니다. 쉽게 말해 화면의 크기가 아닌 컨테이너의 크기(차지하고 있는 크기)에 따라 스타일을 적용할 수 있게 해줍니다. 이 방식은 부모 컨테이너의 크기에 따라 자식 요소의 스타일을 조정할 수 있어 더 세밀한 레이아웃 조정이 가능합니다.

 

컨테이너 쿼리의 조건은 크게 두 가지로 나누어 볼 수 있습니다. 컨테이너 크기컨테이너 스타일입니다. 크기 쿼리는 포함 요소의 현재 크기(방향 및 종횡비 포함)에 따라 스타일을 적용할 수 있게 해줍니다. 스타일 쿼리는 포함 요소의 스타일 특성에 따라 스타일을 적용할 수 있게 해줍니다.

 

현재 스타일 쿼리에서 지원하는 쿼리 요소는 CSS 커스텀 속성이 유일합니다. 이 경우 쿼리는 포함 요소의 커스텀 속성의 계산된 값에 따라 참 또는 거짓을 반환합니다. 컨테이너 스타일 쿼리가 완전히 지원되면, 컨테이너가 display: inline flex인지, 투명하지 않은 배경색이 있는지 등과 같은 모든 속성, 선언 또는 계산된 값을 기준으로 요소에 스타일을 적용할 수 있게 될 것이라고 합니다.

컨테이너 크기 쿼리

컨테이너 크기 쿼리에서 <container-condition>은 하나 이상의 <size-query>를 포함합니다. 각 크기 쿼리는 크기 기능 이름, 비교 연산자 및 값입니다. 컨테이너 쿼리는 미디어 쿼리와 동일한 구문 규칙과 논리 연산자를 사용합니다. 쿼리할 수 있는 크기 기능은 width, height, inline-size, block-size, aspect-ratioorientation(가로 모드 (landscape), 세로 모드 (portrait))으로 제한되어 있습니다. 

 

다음의 코드는 크기를 조절할 수 있는 박스의 너비가 150 픽셀 이상 700 픽셀 이하일 때 글자 크기를 5배 크게 만들어 주는 코드입니다.

 

See the Pen 컨테이너 사이즈 쿼리 by 최도훈 (@Dohun-choi-the-selector) on CodePen.

 

 

 

 

 

주의할 점

사이즈 쿼리를 사용할 때는 컨테이너의 이름을 지정하는 등의 방법으로 CSS containment를 적용하여야 합니다. 서로 다른 컨테이너를 구분해 예상치 못한 동작과 무한 루프를  막고, DOM의 모든 요소 크기를 쿼리하는 것을 방지하는 방식으로 성능적인 측면을 개선할 수 있습니다. 다음과 같은 방법으로 컨테이너의 이름을 지정할 수 있습니다.

.class-name {
    container: <container-name> / inline-size;
}

@container <container-name> <container-query> {
  /* <stylesheet> */
}

컨테이너 스타일 쿼리

컨테이너 스타일 쿼리는 @container 쿼리 중 하나로, 컨테이너 요소의 계산된 스타일을 평가하여 스타일 쿼리를 실행합니다. 이러한 스타일 쿼리는 style() 함수 표기법에 정의된 하나 이상의 스타일 특성을 기반으로 평가됩니다. 다음과 같이 사용할 수 있습니다.

@container style(<style-feature>),
    not style(<style-feature>),
    style(<style-feature>) and style(<style-feature>),
    style(<style-feature>) or style(<style-feature>) {
  /* <stylesheet> */
}

style() 함수의 매개변수(<style-feature>)로는 유효한 CSS 선언, CSS 속성, 또는 <custom-property-name>이 있습니다. 만약 <style-feature>에 값이 포함되어 있다면, 스타일 쿼리는 해당 쿼리된 컨테이너에 대해 스타일 쿼리로 전달된 커스텀 속성이 참인지 거짓인지 평가합니다. 값이 없는 스타일의 경우, 해당 속성의 초기 값과 다를 경우 true로 평가합니다. 현재 (24년 8월 기준) 지원되지 않지만, 향후에는 max-width: 100vw와 같은 일반 CSS 선언도 쿼리할 수 있게 됩니다. 일반 CSS 선언과 속성에 대한 스타일 쿼리가 지원되기 전까지는, style() 매개변수로 커스텀 속성만 포함할 수 있습니다.

@container style(--themeBackground),
    style(--themeColor: blue) or style(--themeColor: purple) {
  /* <stylesheet> */
}

 

다음은 스타일 쿼리의 사용 예제입니다.

See the Pen 컨테이너 스타일 쿼리 by 최도훈 (@Dohun-choi-the-selector) on CodePen.

 

 

 

 

 

결론

전체 페이지는 미디어 쿼리로 조정하고, 특정 컴포넌트의 레이아웃은 컨테이너 쿼리로 조정하여 더 쉽게 반응형 디자인을 만들 수있습니다. 이렇게 한다면 웹 페이지를 보다 높은 반응성을 가지도록 제작하기 쉬워질 것입니다. 깊게 다루지는 못한 스타일 쿼리에 더 자세히 알아보고 싶다면 MDN 문서를 참고해 주세요.

 

그리고 아직(2024년 8월) 제한적인 스타일 쿼리는 향후 display: inline flex와 같은 속성은 트리의 상위 요소에 의해 적용될 수 있으며, 이를 통해 자식 요소에서 특정 스타일을 트리거할 수 있을 것입니다. 스타일 쿼리가 완전히 지원되면 컨테이너 쿼리 내에서 모든 스타일 특성을 확인할 수 있습니다.

참고 자료

MDN, Using container size and style queries
Web.dev, 컨테이너 쿼리 사용 방법

[번역] CSS 미디어 쿼리, 그 너머로

 

 

 

'개발 > HTML, CSS' 카테고리의 다른 글

다양한 CSS 작성법을 간단하게 알아보자  (0) 2024.01.09

+ Recent posts