@supports

@supportsCSSアット規則で、宣言をブラウザーが1つまたは複数の特定の CSS 機能に対応しているかによって、宣言を指定することができます。これは機能クエリと呼ばれます。規則はコードの最上位または他の条件付きグループアット規則の中に配置することができます。

@supports (display: grid) {
  div {
    display: grid;
  }
}
@supports not (display: grid) {
  div {
    float: right;
  }
}

JavaScript では @supports は CSS オブジェクトモデルインターフェイスの CSSSupportsRule からアクセスできます。

構文

@supports アット規則は、ステートメントのブロックを対応条件に関連付けます。対応条件は1つまたは複数の名前と値の組を結合条件 (and)、非結合条件(or)、否定 (not) で組み合わせたものです。演算子の結合順位は、括弧を使用して変更できます。

宣言の構文

もっとも基本的な対応条件は、単純な宣言 (プロパティ名に続けて、コロンで区切って値) です。宣言は括弧で囲む必要があります。以下の例は、ブラウザーが transform-origin プロパティの値として 5% 5% を有効とみなすのであれば true を返します。

@supports (transform-origin: 5% 5%) {}

関数構文

第二の基本的な対応状況は関数の対応であり、これらの構文はすべてのブラウザーで対応されていますが、関数自体はまだ標準化の過程にあります。

selector() 

ブラウザーがテストされたセレクターの構文に対応しているかどうかを検査します。以下の例は、ブラウザーが子結合子に対応していれば true を返します。

@supports selector(A > B) {}

not 演算子

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 演算子

and 演算子は 2 つの式から、元の式の論理積で構成される新たな式を作成します。元の式の両方が true になる場合に限り、新たな式が true になります。以下の例では 2 つの式が同時に true になる場合に限り、全体の式も true になります。

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

括弧を増やすことなく、複数の論理積を並記することができます。以下の式はどちらも等価です。

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

or 演算子

or 演算子は 2 つの式から、元の式の論理和で構成される新たな式を作成します。元の式の一方または両方が true になる場合に限り、新たな式が true になります。以下の例では 2 つの式の少なくとも 1 つが true になる場合に限り、全体の式も true になります。

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

括弧を増やすことなく、複数の論理和を並記することができます。以下の式はどちらも等価です。

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

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

: and 演算子と or 演算子を両方とも使用するときは、これらを適用する順序を定義するために括弧を使用しなければなりません。そうしなければ、アット規則全体を無視させる無効な条件になります。

形式文法

@supports <supports-condition> {
  <group-rule-body>
}

ここで
<supports-condition> = not <supports-in-parens> | <supports-in-parens> [ and <supports-in-parens> ]* | <supports-in-parens> [ or <supports-in-parens> ]*

ここで
<supports-in-parens> = ( <supports-condition> ) | <supports-feature> | <general-enclosed>

ここで
<supports-feature> = <supports-decl> | <supports-selector-fn>
<general-enclosed> = [ <function-token> <any-value> ) ] | ( <ident> <any-value> )

ここで
<supports-decl> = ( <declaration> )
<supports-selector-fn> = selector( <complex-selector> )

ここで
<complex-selector> = <compound-selector> [ <combinator>? <compound-selector> ]*

ここで
<compound-selector> = [ <type-selector>? <subclass-selector>* [ <pseudo-element-selector> <pseudo-class-selector>* ]* ]!
<combinator> = '>' | '+' | '~' | [ '||' ]

ここで
<type-selector> = <wq-name> | <ns-prefix>? '*'
<subclass-selector> = <id-selector> | <class-selector> | <attribute-selector> | <pseudo-class-selector>
<pseudo-element-selector> = ':' <pseudo-class-selector>
<pseudo-class-selector> = ':' <ident-token> | ':' <function-token> <any-value> ')'

ここで
<wq-name> = <ns-prefix>? <ident-token>
<ns-prefix> = [ <ident-token> | '*' ]? |
<id-selector> = <hash-token>
<class-selector> = '.' <ident-token>
<attribute-selector> = '[' <wq-name> ']' | '[' <wq-name> <attr-matcher> [ <string-token> | <ident-token> ] <attr-modifier>? ']'

ここで
<attr-matcher> = [ '~' | | | '^' | '$' | '*' ]? '='
<attr-modifier> = i | s

指定した CSS プロパティの対応状況を確認する

@supports (animation-name: test) {/* 接頭辞がないプロパティでアニメーションに対応する場合に適用する CSS */
  @keyframes { /* 他のアット規則を含むことができる */}
}

指定した CSS プロパティの対応状況を、接頭辞付きも含めて確認する

@supports ((perspective: 10px) or (-moz-perspective: 10px) or (-webkit-perspective: 10px) or
         (-ms-perspective: 10px) or (-o-perspective: 10px)) {/* 接頭辞つきを含めて 3D transforms を対応する場合に適用する CSS */
}

指定した CSS プロパティに対応していないことを確認する

@supports not ((text-align-last: justify) or (-moz-text-align-last: justify)) {/* text-align-last:justify をシミュレートするために適用する CSS */
}

カスタムプロパティの対応状況を確認する

@supports (--foo: green) {
  body {
    color: var(--varName);
  }
}

セレクターの対応の検査 (例: :is())

Experimental

これは実験的な機能です。
本番で使用する前にブラウザー互換性一覧表をチェックしてください。

/* この規則は :is() に対応していないブラウザーでは適用されません */
:is(ul, ol) > li {/* :is(…) セレクターに対応している場合に CSS が適用される */
}

@supports not selector(:is(a, b)) {
  /* :is() に対応していない場合の代替 */
  ul > li,
  ol > li {/* 上記のものは :is(…) に対応していないブラウザーのために展開しています */
  }
}

/* Note: By far, there's no browser that supports the `of` argument of :nth-child(…) */
@supports selector(:nth-child(1n of a, b)) {
  /* This rule needs to be inside the @supports block, otherwise
     it will be partially applied in browsers which don't support
     the `of` argument of :nth-child(…) is supported */
  :is(
      :nth-child(1n of ul, ol) a,
      details > summary
  ) {/* CSS applied when the :is(…) selector and
         the `of` argument of :nth-child(…) are both supported */
  }
}

仕様書

仕様書 状態 備考
CSS Conditional Rules Module Level 4
@supports の定義
編集者草案 selector() 関数を追加
CSS Conditional Rules Module Level 3
@supports の定義
勧告候補 初回定義

ブラウザーの互換性

BCD tables only load in the browser

関連情報