@custom-media
요약
CSS의 @custom-media at-rule을 사용하여 미디어 쿼리에 대한 별칭을 생성하는 방법을 설명합니다. 복잡한 미디어 쿼리를 재사용 가능한 식별자로 정의하여 코드의 가독성과 유지보수성을 높일 수 있습니다.
핵심 포인트
- @custom-media를 통한 미디어 쿼리 별칭 생성 가능
- 두 개의 대시(--)로 시작하는 식별자 사용 규칙
- 전역 스코프(Global Scope)에서 작동하는 특성
- 코드베이스 내 미디어 쿼리 재사용성 및 가독성 향상
CSS @custom-media at-rule을 사용하면 미디어 쿼리 (queries)에 대한 별칭(alias)을 생성할 수 있습니다. 이는 코드베이스 전체에서 여러 번 사용하는 길거나 복잡한 미디어 쿼리가 있는 경우 특히 유용합니다. 이 기능은 성격상 CSS 사용자 정의 속성 (CSS custom properties/CSS variables)의 미디어 쿼리 버전과 유사합니다.
구문 (Syntax)
별칭을 정의하는 구문은 다음과 같습니다:
@media (<dashed-ident>) [<media-query-list> | true | false ];
예를 들어:
@custom-media --modern-touch (pointer: coarse) and (min-width: 1024px);
...여기서 대시 식별자 (dashed ident)는 --modern-touch입니다.
별칭을 사용하는 구문은 일반적인 미디어 쿼리를 사용하는 것과 동일하지만, 미디어 유형(media types)이나 미디어 기능(media features)을 제공하는 대신 정의된 @custom-media의 <dashed-ident>를 제공합니다:
@media <dashed-ident> {
/* ... */
}
인자 및 기술자 (Arguments and Descriptors)
<dashed-ident>: 함수나 사용자 정의 속성과 유사하게 반드시 두 개의 대시(--)로 시작해야 하는 사용자 정의 식별자입니다. 사용자 정의 속성과 마찬가지로 이름은 대소문자를 구분합니다. 예를 들어,--mobile-breakpoint와--Mobile-Breakpoint는 서로 다른 커스텀 미디어 정의를 참조하게 됩니다.<media-query-list>: 연산자로 구분된 미디어 쿼리 목록입니다.true/false: 항상 일치 / 절대 일치하지 않음 토글입니다.
이들이 스코프(scope)가 지정되는 방식, 불리언(boolean)과 함께 사용하는 법, 복잡한 로직 정의, CSS 범위 구문(CSS range syntax)을 사용한 규칙 설정, 그리고 별칭을 중첩하는 방법 등 다양한 문맥에서 어떻게 작동하는지 살펴보겠습니다.
스코프 및 배치 (Scope and Placement)
커스텀 속성 (Custom Properties)이 정의된 요소(및 그 자식 요소)에 스코프가 지정되는 (scoped to the element they are defined on) 것과 달리, @custom-media 규칙은 전역적 (global)입니다. 이들은 스타일시트의 전역 스코프 (global scope)에서 평가되며 항상 문서 전체에 적용됩니다. 만약 동일한 이름으로 여러 개의 @custom-media 규칙이 정의된다면, 평가 시점에 스코프 내에 있는 규칙이 사용됩니다.
@media 규칙이 커스텀 별칭 (custom alias), 즉 대시로 시작하는 식별자 (dashed ident)를 사용할 때, 스타일시트의 해당 시점에 있는 그 별칭의 현재 정의를 참조합니다. 만약 나중에 별칭이 재정의되더라도, 이미 처리된 미디어 쿼리 (media queries)들이 "업데이트"되지는 않습니다. 예를 들어, 이 경우 margin-block: 1rem은 나중에 동일한 이름을 사용하는 선언이 있더라도, fullscreen일 때만 body에 적용되며 browser일 때는 적용되지 않습니다.
@custom-media --screen-display (display-mode: fullscreen);
@media (--screen-display) {
...
참고: 이러한 스코프 동작 방식은 여전히 논의 중이며 향후 변경될 수 있습니다.
불리언 상수 (Boolean Constants)
위의 구문 (Syntax) 섹션에서, @custom-media 규칙을 명시적으로 true 또는 false로 설정할 수 있음에 유의하세요. 이는 개발 중에 CSS 블록 전체를 "토글 (toggling)"하거나 기능 플래그 (feature flagging)를 설정할 때 유용합니다.
연산자 및 복합 로직 (Operators and Complex Logic)
@custom-media는 @media와 정확히 동일한 논리 연산자 (and, ,, or, not, only) 및 그룹화 규칙을 사용하므로, 평소와 같이 괄호로 그룹화된 복잡한 로직을 구축할 수 있습니다. 연산자 사용법, 기능 부정(negate), 또는 오래된 브라우저에서 스타일시트 숨기기에 대한 자세한 분석은 @media 연감의 논리 및 연산자 섹션을 참조하세요. 복잡한 쿼리를 구축할 때는 중첩 및 복잡한 의사 결정에 관한 섹션을 참조하는 것도 가치가 있습니다.
예를 들어, and 논리 연산자를 사용하여 쿼리를 구성하려면 다음과 같이 작성할 수 있습니다:
@custom-media --modern-touch (pointer: coarse) and (min-width: 1024px);
범위 구문 (Range Syntax)
다른 모든 <media-query-list>와 마찬가지로, @custom-media는 조건 평가를 위해 크다(>), 작다(<), 같다(=)와 같은 연산자를 사용하는 범위 미디어 쿼리 구문 (ranged media query syntax)을 지원합니다:
/* 기존 방식 */
@custom-media --tablet (min-width: 768px) and (max-width: 1024px);
...
중첩된 별칭 (Nested Aliases)
@custom-media 별칭(alias)의 한 가지 독특한 특징은 서로를 참조할 수 있다는 점입니다. 이를 통해 계층화된 의미론적(semantic) 조건을 구축할 수 있습니다:
@custom-media --narrow-window (width < 30rem);
@custom-media --small-and-hover (--narrow-window) and (hover: hover);
...
하지만 루프(loop)가 감지되면 관련된 모든 커스텀 미디어 쿼리는 정의되지 않은(undefined) 것으로 처리됩니다. 예를 들어, --query-a가 --query-b를 참조한다면, --query-b는 --query-a를 참조할 수 없습니다. 마찬가지로, 커스텀 미디어 쿼리는 자기 자신을 참조할 수 없습니다.
또한 과도한 중첩(over-nesting)에 주의하세요. 과도한 중첩은 브라우저 개발자 도구에서 디버깅을 어렵게 만들고, 어떤 계층의 쿼리가 관련 영향을 미치고 있는지 식별하는 것을 매우 어렵게 만들 수 있습니다.
예시: 공통 중단점 (Breakpoints) 정의하기
당신의 “태블릿 (tablet)” 중단점 (breakpoint)이 768px인지 800px인지 기억하는 대신, 스타일시트 상단에 한 번만 정의할 수 있습니다.
@custom-media --tablet (min-width: 768px);
.sidebar {
...
예시: 기존 속성에 대한 축약형 (Shorthands) 정의하기
(prefers-reduced-motion: reduce)와 같은 표준 상용구 (boilerplate)는 코드베이스 전체에서 여러 번 사용될 수 있으며, 이러한 바이트가 쌓이면 무시할 수 없게 됩니다. @custom-media를 사용하여 더 간단한 대안을 정의할 수 있습니다:
@custom-media --prefers-reduced-motion (prefers-reduced-motion: reduce);
@media (--prefers-reduced-motion) {
...
사용을 고려해 볼 만한 수많은 Open Props @custom-media 레시피 (Recipes)가 있습니다.
JavaScript 지원
@custom-media 별칭 (aliases)은 JavaScript matchMedia() 메서드에 노출되지 않습니다. 즉, 페이지 어딘가에 별칭을 정의해 두었더라도 다음 코드는 작동하지 않습니다.
matchMedia("(--tablet)")
명세 (Specification)
@custom-media At-rule은 Media Queries Level 5 명세에 정의되어 있습니다.
브라우저 지원
지원되지 않는 브라우저는 대체로 @custom-media를 무시하므로, 폴백 (fallback) 선언과 점진적 향상 (progressive enhancement) 전략을 사용하는 것이 유리할 수 있습니다. 다음과 같이 @supports를 사용하여 사용자의 브라우저에서 @custom-media가 지원되는지 확인할 수 있습니다:
@supports (at-rule(@custom-media)) {
/* ... */
}
하지만 아이러니하게도, 이 글을 쓰는 시점에 @supports At-rule 평가 기능은 브라우저 전반에 걸쳐 완전한 지원을 제공하지 않으므로 (Chrome 148+ 전용), 귀하의 사례에서 지원되는지 확인이 필요합니다. 이에 대한 논의는 CSS Drafts Issue #2463에서 확인할 수 있습니다.
또 다른 접근 방식은 PostCSS Custom Media와 같은 도구를 사용하는 것입니다. 이 도구는 빌드 단계 (build step)에서 규칙을 확장하여 더 넓은 브라우저 지원 (browser support)을 가능하게 합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 CSS-Tricks의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기