Reference/At-rules/@supports

김동현·2026년 3월 28일

mdn 학습 번역 - CSS

목록 보기
185/190

@supports

Baseline | Widely available

Chrome, Edge, Firefox, Safari에서 지원돼요.

이 기능은 잘 확립되어 있고 많은 기기와 브라우저 버전에서 작동해요. 2015년 9월부터 모든 브라우저에서 사용 가능했어요.

@supports CSS at-rule을 사용하면 브라우저의 CSS 기능 지원 여부에 따라 달라지는 CSS 선언을 지정할 수 있어요. 이 at-rule을 사용하는 것을 일반적으로 기능 쿼리라고 불러요. 이 규칙은 코드의 최상위 레벨에 배치되거나 다른 조건부 그룹 at-rule 내부에 중첩되어야 해요.

JavaScript에서 @supports는 CSS 객체 모델 인터페이스 CSSSupportsRule을 통해 접근할 수 있어요.

직접 해보세요 (Try it)

이 데모에서는 @supports를 사용해서 브라우저가 display: flex를 지원하는지에 따라 레이아웃과 그림자 효과를 어떻게 다르게 주는지 보여줍니다.

CSS

.flex-container > * {
  padding: 0.3em;
  list-style-type: none;
  text-shadow: 0 0 2px red;
  float: left; /* 플렉스를 지원하지 않는 경우를 위한 기본값 */
}

/* 브라우저가 display: flex를 지원한다면 이 블록을 실행해요 */
@supports (display: flex) {
  .flex-container > * {
    text-shadow: 0 0 2px blue;
    float: none;
  }

  .flex-container {
    display: flex;
  }
}

HTML

<ul class="flex-container">
  <li><a href="#">홈 (Index)</a></li>
  <li><a href="#">소개 (About me)</a></li>
  <li><a href="#">연락처 (Contact)</a></li>
</ul>

구문 (Syntax)

@supports (<supports-condition>) {
  /* 조건이 참(true)이면 이 블록 안의 CSS를 사용해요. */
}

@supports (<supports-condition>) and (<supports-condition>) {
  /* 두 조건이 모두 참(true)일 때만 이 블록 안의 CSS를 사용해요. */
}

@supports 앳 규칙은 하나 이상의 기능 지원 조건(supports condition)으로 구성된 블록이에요. 조건들은 논리곱(and), 논리합(or), 부정(not)을 사용해서 결합할 수 있고, 괄호를 써서 우선순위를 정할 수도 있답니다.

기능 지원 조건은 속성: 값 형태의 선언문 구문이나 함수() 형태의 함수 구문을 사용할 수 있어요. 각 방식에 대해 자세히 알아볼까요?


선언문 구문 (Declaration syntax)

선언문 구문은 브라우저가 특정 속성: 값 선언을 지원하는지 확인해요. 이때 선언문은 반드시 괄호로 감싸야 합니다. 아래 예제는 브라우저가 transform-origin: 5% 5%라는 표현을 지원하면 true를 반환해요.

@supports (transform-origin: 5% 5%) {
  /* 지원될 때 적용할 스타일 */
}

함수 구문 (Function syntax)

함수 구문은 함수 안에 적힌 값이나 표현식을 브라우저가 지원하는지 확인해요. 지원되는 함수들은 다음과 같습니다.

selector()

이 함수는 브라우저가 특정 선택자 구문을 지원하는지 평가해요. 아래 예제는 브라우저가 자식 결합자(child combinator)를 지원하면 true를 반환하고 스타일을 적용합니다.

@supports selector(h2 > p) {
  /* 자식 결합자가 지원될 때 적용 */
}

font-tech()

레이아웃과 렌더링에 사용되는 특정 폰트 기술을 지원하는지 확인해요. 아래 예제는 브라우저가 COLRv1 폰트 기술을 지원하면 true가 됩니다.

@supports font-tech(color-COLRv1) {
  /* 컬러 폰트 기술이 지원될 때 적용 */
}

font-tech()로 쿼리할 수 있는 폰트 기술들(<font-tech>)은 다음과 같아요.

기술 (Technology)지원 내용 (Supports)
<color-font-tech>
color-colrv0COLR 버전 0 테이블을 통한 다색 글리프
color-colrv1COLR 버전 1 테이블을 통한 다색 글리프
color-svgSVG 다색 테이블
color-sbix표준 비트맵 그래픽 테이블
color-cbdt컬러 비트맵 데이터 테이블
<font-features-tech>
features-opentypeOpenType GSUBGPOS 테이블
features-aatTrueType morxkerx 테이블
features-graphiteGraphite 기능 (Silf, Glat, Gloc, Feat, Sill 테이블)
기타 <font-tech>
incremental-patch패치 서브셋 방식을 이용한 점진적 폰트 로딩
incremental-range범위 요청 방식을 이용한 점진적 폰트 로딩
incremental-auto방식 협상을 이용한 점진적 폰트 로딩
variationsTrueType/OpenType 폰트의 가변(Variations) 기능 제어
palettes폰트 내 여러 컬러 팔레트 중 하나를 선택하는 font-palette 기능

font-format()

브라우저가 특정 폰트 포맷을 지원하는지 확인해요. 아래 예제는 opentype 포맷을 지원하면 true가 됩니다.

@supports font-format(opentype) {
  /* 오펜타입 포맷 지원 시 적용 */
}

사용 가능한 폰트 포맷(<font-format>) 목록입니다.

포맷설명파일 확장자
collectionOpenType Collection.otc, .ttc
embedded-opentypeEmbedded OpenType.eot
opentypeOpenType.ttf, .otf
svgSVG 폰트 (폐기됨).svg, .svgz
truetypeTrueType.ttf
woffWOFF 1.0.woff
woff2WOFF 2.0.woff2

not 연산자 (The not operator)

not 연산자는 뒤에 오는 표현식을 부정해요. 즉, 결과가 반대로 뒤집히는 거죠. 아래 예제는 브라우저가 transform-origin 속성에서 10em 10em 10em이라는 값을 지원하지 않을 때(무효하다고 판단할 때) true를 반환합니다.

@supports not (transform-origin: 10em 10em 10em) {
  /* 지원하지 않을 때 적용할 폴백 스타일 */
}

not 연산자는 아무리 복잡한 선언문에도 적용할 수 있어요. 아래 예시들은 모두 유효합니다.

@supports not (not (transform-origin: 2px)) {
}
@supports (display: grid) and (not (display: inline-grid)) {
}

참고: 최상위 레벨에서는 not 연산자를 괄호로 또 감쌀 필요는 없어요. 하지만 andor 같은 다른 연산자와 섞어 쓸 때는 반드시 괄호가 필요하답니다.


and 연산자 (The and operator)

and 연산자는 두 개의 짧은 표현식을 결합해서 새로운 표현식을 만들어요. 두 조건이 모두 참이어야만 전체 결과가 true가 됩니다.

@supports (display: table-cell) and (display: list-item) {
  /* 둘 다 지원해야 실행돼요 */
}

여러 개의 and를 나열할 때는 괄호를 추가로 쓸 필요가 없어요. 아래 두 줄은 똑같이 작동합니다.

@supports (display: table-cell) and (display: list-item) and (display: contents) { }
@supports (display: table-cell) and ((display: list-item) and (display: contents)) { }

or 연산자 (The or operator)

or 연산자는 두 조건 중 하나라도, 혹은 둘 다 참이면 true를 반환합니다.

@supports (transform-style: preserve) or (-moz-transform-style: preserve) {
  /* 둘 중 하나만 지원해도 실행돼요 */
}

or 역시 여러 개를 나열할 때 괄호를 굳이 더 쓰지 않아도 돼요.

@supports (transform-style: preserve) or (-moz-transform-style: preserve) or (-webkit-transform-style: preserve) { }

참고: andor 연산자를 함께 섞어서 쓸 때는 반드시 괄호를 사용해서 어떤 것을 먼저 계산할지 명시해줘야 해요. 그러지 않으면 구문 오류로 간주되어 규칙 전체가 무시됩니다.


형식적인 구문 (Formal syntax)

@supports = 
  @supports <supports-condition> { <rule-list> }  

이 구문은 CSS Conditional Rules Module Level 3의 최신 표준을 따르고 있습니다.


예제 (Examples)

특정 CSS 속성 지원 여부 테스트

@supports (animation-name: test) {
  /* 접두사 없이 애니메이션을 지원할 때 적용되는 CSS */
  @keyframes {
    /* 다른 앳 규칙들도 이 안에 중첩할 수 있어요 */
  }
}

특정 속성 혹은 접두사 버전 지원 여부 테스트

@supports (text-stroke: 10px) or (-webkit-text-stroke: 10px) {
  /* text-stroke가 그냥 지원되든, -webkit- 접두사를 달고 지원되든 적용돼요 */
}

특정 CSS 속성을 지원하지 않는 경우 테스트

@supports not ((text-align-last: justify) or (-moz-text-align-last: justify)) {
  /* text-align-last: justify를 지원하지 않는 브라우저를 위한 대체 스타일 */
}

선택자 지원 여부 테스트

CSS 조건부 규칙을 사용하면 :has() 같은 최신 선택자를 지원하는지도 확인할 수 있어요.

/* :has()를 지원하지 않는 브라우저에서는 이 규칙이 아예 적용되지 않아요 */
ul:has(> li li) {
  /* :has() 의사 클래스가 지원될 때만 스타일 적용 */
}

@supports not selector(:has(a, b)) {
  /* :has()가 지원되지 않을 때를 위한 폴백 스타일 */
  ul > li, ol > li {
    /* :has() 없이 풀어쓴 스타일들 */
  }
}

/* 참고: 현재 :nth-child(...)의 of 인자를 지원하는 브라우저는 아직 거의 없습니다 */
@supports selector(:nth-child(1n of a, b)) {
  /* of 인자를 지원할 때만 이 안의 복잡한 규칙을 적용해요. 
     그렇지 않으면 브라우저가 규칙을 부분적으로만 해석해서 스타일이 깨질 수 있거든요. */
  :is(:nth-child(1n of ul, ol) a, details > summary) {
    /* :is() 선택자와 :nth-child()의 of 인자가 모두 지원될 때 적용 */
  }
}

폰트 기술 지원 여부 테스트

아래 예제는 브라우저가 COLRv1 기술을 지원할 때만 Bungee Spice 컬러 폰트를 적용해요.

@supports font-tech(color-COLRv1) {
  body {
    font-family: "Bungee Spice", fantasy;
  }
}

또한 @font-face 규칙 안에서도 tech() 함수를 써서 기술별로 폰트를 고르게 할 수 있습니다. 아래 예제에서 컬러 폰트 기술을 지원하지 않으면 일반 bungee.woff2 폰트를 사용하게 되죠.

@font-face {
  font-family: "Bungee Spice";
  src:
    url("bungee-spice.woff2") tech(color-COLRv1) format("woff2"),
    url("bungee.woff2") format("woff2");
}

폰트 포맷 지원 여부 테스트

@font-face {
  font-family: "Open Sans WOFF";
  src: url("open-sans.woff") format("woff");
}

@font-face {
  font-family: "Open Sans WOFF2";
  src: url("open-sans.woff2") format("woff2");
}

body {
  font-family: "Open Sans WOFF", sans-serif;
}

@supports font-format(woff2) {
  body {
    font-family: "Open Sans WOFF2", sans-serif;
  }
}

하지만 더 효율적인 방법은 아래처럼 하나의 @font-face 규칙 안에서 src 디스크립터에 우선순위대로 나열하는 거예요.

@font-face {
  font-family: "Open Sans";
  src:
    url("open-sans.woff2") format("woff2"),
    url("open-sans.woff") format("woff");
}

body {
  font-family: "Open Sans", sans-serif;
}

더 많은 예제가 궁금하시다면 미디어 쿼리 사용하기 페이지를 참고해 보세요.

@supports는 "프로그레시브 인핸스먼트(Progressive Enhancement)"를 실천하기 위한 최고의 도구예요.

profile
프론트에_가까운_풀스택_개발자

0개의 댓글