← 목록으로

"지원됨!" CSS @supports의 달콤한 거짓말, 브라우저가 외면하는 진실

2026. 5. 11.

"지원됨!" CSS @supports의 달콤한 거짓말, 브라우저가 외면하는 진실

최근 CSS의 발전 속도는 정말 놀랍습니다. 그중에서도 조건부 규칙인 @supports는 특정 CSS 기능의 지원 여부에 따라 스타일을 선택적으로 적용할 수 있게 해주는 강력한 도구로 자리매김했죠. 특히 CSS Nesting 스펙이 등장하면서 @supports를 중첩된 스타일 규칙 안에서도 사용할 수 있게 되었습니다. 마치 부모 셀렉터의 컨텍스트 안에서 유연하게 기능을 체크할 수 있을 것 같은 기대감을 주면서 말이죠.

하지만 여기서 우리가 예상치 못한 함정이 숨어있습니다. 시각적으로는 분명 중첩된 것처럼 보이지만, @supports 규칙은 주변 셀렉터의 영향을 받지 않는다는 사실입니다. 브라우저는 이 규칙을 마치 최상위 레벨에 작성된 것처럼 평가해 버립니다.

.my-class {
  @supports (property: value) {
    /* ...스타일... */
  }
}

위 코드만 보면, 마치 .my-class 내에서 (property: value)의 지원 여부를 확인하는 것처럼 느껴집니다. 하지만 실상은 다릅니다. 이 @supports 규칙은 전역적인 방식으로 적용됩니다. 그 위치가 마치 특정 스코프에 종속된 듯한 착각을 불러일으키지만, 실제 동작 방식은 그렇지 않죠. 이처럼 배치와 실제 작동 방식 간의 불일치가 바로 중첩된 @supports가 우리를 혼란에 빠뜨리는 주된 이유입니다.

조금 더 구체적인 예시를 살펴볼까요? li::marker- 기호를 넣고 빨간색으로 표시하고 싶을 때가 있습니다.

li::marker {
  @supports (content: " - ") {
    content: " - ";
    color: red;
  }
}

이 코드는 대부분의 최신 브라우저에서 잘 작동할 것 같습니다. Chrome, Safari, Firefox 모두 ::marker를 지원하고, content: " - " 역시 일반적인 CSS 속성으로 지원하니까요. 그러나 여기에 미묘한 함정이 있습니다. Safari는 ::marker 내부에서 content 속성을 지원하지 않습니다.

결과적으로 Chrome과 Firefox에서는 빨간색 - 기호가 리스트 마커로 잘 나타납니다. 하지만 Safari에서는 여전히 기본 빨간색 원형 마커가 표시될 뿐이죠.

제가 실무에서 이 부분을 테스트해 봤을 때 정말 황당했던 기억이 생생합니다. 분명 @supports 조건이 true로 성공했다고 나오는데, Safari에서는 의도한 대로 동작하지 않는 거예요. 한참을 디버깅하면서 왜 이런 현상이 발생하는지 파고들다가, @supports의 숨겨진 동작 방식을 이해하게 됐습니다. 핵심은 @supports 조건이 특정 컨텍스트 내에서 해당 선언이 실제로 작동하는지 여부를 검사하는 것이 아니라는 점입니다. 그저 해당 선언이 일반적으로 유효한 문법인지만 확인할 뿐이죠.

이러한 현상은 브라우저가 중첩된 @supports 규칙을 최상위 레벨로 '이동'시키거나 '파싱'해서 생기는 문제가 아닙니다. 오히려 @supports 자체가 어떻게 정의되어 있는지에 더 가깝습니다. @supports는 특정 선언이 전반적으로 유효한지만 확인합니다. 특정 셀렉터나 가상 요소 컨텍스트 내에서 문법적으로도 유효한지, 그리고 실제로 렌더링 엔진이 그것을 처리할 수 있는지는 고려하지 않는다는 의미죠.

@supports의 한계를 넘어설 아이디어

이러한 오해의 소지를 해결하기 위한 몇 가지 아이디어를 생각해볼 수 있습니다.

1. 조합 검증을 위한 확장

@supports를 확장하여 독립적인 기능이 아닌, 특정 조합의 유효성을 검증할 수 있는 새로운 연산자나 함수를 도입하는 방안입니다.

@supports selector(::marker) and (content: " - ")

혹은 명시적인 "컨텍스트 내 지원"을 나타내는 키워드를 쓸 수도 있겠죠.

@supports selector(::marker) xand (content: " - ")

아니면 아예 규칙 자체를 검사하는 방식도 있을 수 있습니다.

@supports rule(::marker { content: " - " })

이렇게 되면 단순히 문법 인식을 넘어, 주어진 렌더링 컨텍스트 내에서 특정 선언이 진정으로 작동하는지 여부를 테스트할 수 있게 될 겁니다.

2. 스코프 상대적 평가 (궁극적인 해결책)

가장 이상적인 해결책은 브라우저가 @supports 규칙을 등장한 스코프에 상대적으로 평가하는 것입니다. 이 방식이 구현된다면, 개발자는 더 직관적으로 코드를 작성할 수 있게 되겠죠. 물론, 이런 복잡한 평가에는 상당한 연산량이 필요할 수 있다는 우려도 있습니다. 하지만 과거 :has() 셀렉터에 대해서도 비슷한 이야기가 나왔지만, 지금은 대부분의 브라우저에서 훌륭하게 작동하고 있지 않나요? 기술적인 한계는 언제나 극복되어 왔습니다.

물론, 컨테이너 쿼리나 스타일 쿼리 같은 대안도 어느 정도 도움이 될 수 있습니다. 하지만 현재로서는 부분적인 지원에 머물러 있고, 선언(declaration)이 아닌 커스텀 프로퍼티(custom properties)만 체크할 수 있다는 한계가 명확합니다. 따라서 중첩된 @supports가 지닌 오해의 소지나 제한적인 특성을 완전히 제거할 수는 없을 것입니다.

@supports는 분명 유용한 CSS 기능입니다. 하지만 그 동작 방식을 정확히 이해하지 못하면 뜻밖의 버그를 마주할 수 있습니다. 특히 중첩된 @supports를 사용할 때는 반드시 **"이것은 전역적인 지원 여부 체크일 뿐, 특정 스코프 내 동작을 보장하지 않는다"**는 점을 기억해야 합니다. 개발자들은 브라우저의 진화와 함께 CSS 스펙의 미묘한 부분까지도 깊이 이해하고 활용해야 하는 숙명을 가지고 있죠. 앞으로 @supports가 더욱 강력하고 직관적인 도구로 발전하기를 기대해 봅니다.


원문: https://dev.to/alvaromontoro/supports-lies-when-css-says-yes-but-browsers-say-lol-no-2bjh 수집일: 2026-05-11 01:52:15