@supportsとは?CSSでブラウザ対応判別と条件分岐できる機能を紹介!

@supportsとは?CSSでブラウザ対応判別と条件分岐できる機能を紹介!

この記事を書いた人

もなか

30歳を過ぎてからプログラミングの勉強を独学で始め、現在コーダー3年目。毎日JavaScriptについて勉強中。趣味はパンを焼くこと。2人の男の子のママ。

新しいCSSプロパティを使いたい!

けど、非対応ブラウザには別のプロパティで対応させないといけない….。

このような状況のとき、CSSだけでブラウザごとに表示を変える方法があるのを知ってますか?

そこで今回は、ブラウザ対応を判別して条件分岐でCSSの表示を変更できる@supportsをご紹介します。

  • @supportsとは
  • @supportsを使った条件分岐の書き方
  • @supportsの具体的な使用例

以上のことを知りたい方は、ぜひ最後までチェックしてくださいね!

CSS @supportsとは?

@supportsは、指定するプロパティのブラウザ対応可否を判断するCSSの機能です。

@supports後ろの()に記述したプロパティや値を判定し、条件判定します。

使用したいプロパティがあるけど対応しているブラウザが少ない、そんな時にフォールバックとセットで指定することで柔軟にCSSの指定ができるようになります。

ブラウザ対応状況(Can I Use調べ)

CanIuseで調べた@supportsのブラウザ対応状況
引用:“@supports” | Can I use…

2022年6月でサポート終了したIE以外、ほとんどのモダンブラウザで対応しています!

@supportsの書き方

基本的な使い方は下の通りです。

/* grid非対応ブラウザ用のスタイル */
.container {
  display: flex;
}

/* ブラウザがgridに対応していたら */
@supports (display: grid) {
  .container {
    display: grid;
  }
}

@supportsの後ろに()を書き、その中にプロパティと値を指定し、{ }内に適用させたいプロパティと値を記述します。

上の例では、ブラウザがdisplay: gridに対応していた場合、@supports内に書かれているスタイルが適用されます。

そうでない場合はコードをさかのぼり、サポートしている指定プロパティ・値を適用します。

そのほかにも、@supportsにはさまざまな条件付きの構文があります。

not演算子

/* grid対応ブラウザ用のスタイル */
.container {
  display: grid;
}

/* ブラウザがgridに非対応だったら */
@supports not (display: grid) {
  .container {
    display: flex;
  }
}

not演算子は上記の「基本的な使い方」とは逆の指定方法です。

上の場合、gridに非対応のブラウザだった場合、@supports内に書かれているflexが適用されます。

and演算子

@supports (display: flex) and (gap: 20px) {
  .container {
    display: flex;
    gap: 20px;
  }
}

and演算子は、()で繋いで指定した、2種類以上のスタイルすべてのブラウザ対応可否を判定します。

or演算子

@supports (text-size-adjust: 100%) or (-webkit-text-size-adjust: 100%) {
  .container {
    text-size-adjust: 100%;
    -webkit-text-size-adjust: 100%;
  }
}

or演算子は、()で繋ぎ指定した2種類以上のスタイルのどちらかが、ブラウザに対応している場合に適用されます。

ベンダープレフィックスが必要な場合など、同一プロパティだが複数指定する必要がある場合などに便利です。

selector()

/* .containerの子階層に.itemを含んでいる場合 */
.container:has(.item) {
	background-color: green;
}

/* .containerの子階層に.itemを含んでいないときのスタイル */
@supports not selector(:has(.item)) {
	.container {
		background-color: red;
	}
}

selector()はセレクターの指定ができます。ブラウザーがselector()の中のセレクターに対応している場合、@supports内が適用されます。

:hasは()内の要素を持っているか(階層内に含んでいるか)判定できる擬似クラスです。※現在Safariしか対応していません(参考::has” | Can I use…

上の例では、.itemを含んでいる場合.containerには背景色green、.itemを含んでいない要素には背景色redの指定をしています。

ChromeとSafariの比較
ChromeとSafariの反映結果

selector()内の条件によって色を変えるスタイルを定義しています。

@supportsの具体的な使用例を紹介

@supportsを使った、実際の現場でも使えそうなパターンをいくつかご紹介します。

display: gridとdisplay: flexを条件分岐

/* grid対応ブラウザ用のスタイル */
@supports (display: grid) {
  .container {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 50% 50%;
    gap: 10px;
  }
}

/* grid非対応ブラウザ用のスタイル */
@supports not (display: grid) {
  .container {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    margin-top: -10px;
  }
  .container__item {
    width: calc((100% - 20px) / 3);
    height: 200px;
    margin-top: 10px;
  }
}

上の例では、display: gridでフリッドレイアウトを組んでいますが、gridが非対応のブラウザには@supportsで display: flex が適用するようにしています。

gridレイアウトはなんとなく難しそう…そう考えているコーダーやフロントエンジニアの方もいらっしゃるはず。使い方やポイントはこちらの記事で紹介しているので、あわせて参考にしてみてください!

Flexboxの使い方、毎回調べながら書いてる…という方はこちらの記事で復習しておきましょう!

flexboxでgapプロパティを使う

gapプロパティについてはこちらで詳しく解説しています。

さきほどと同じレイアウトですが、今回はFlexboxをメインに、gapプロパティで余白を調整しています。

/* コンテナスタイルのみ抜粋 */
.container {
  color: #fff;
  font-size: 4em;
  font-weight: bold;
  text-align: center;
  line-height: 3;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

/* gapプロパティ非対応ブラウザ用のスタイル */
@supports not (gap: normal) {
  .container {
    justify-content: space-between;
    margin-top: -10px;
  }
  .container__item {
    margin-top: 10px;
  }
}

.container__item {
  width: calc((100% - 20px) / 3);
  height: 200px;
}

上の例では、display: flex と gapプロパティに対応するかどうかで条件分岐し、非対応ブラウザではmarginなどで余白を変更しています。

gapプロパティはSafariの一部バージョンでは非対応となっているため、活用できるシーンはありそうですね。

※グリッドレイアウトの余白指定にはちょっとしたテクニックが必要。気をつけるポイントはこちらの記事で紹介しています。

aspect-ratioでアスペクト比を保ったレスポンシブコーディング

aspect-ratioの例

次の例はYouTubeやGoogle Map、画像などのアスペクト比を保持させたい場合のコーディングです。

/* aspect-ratio 対応ブラウザ用のスタイル */
.container iframe {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
}

/* aspect-ratio 非対応ブラウザ用のスタイル */
@supports not (aspect-ratio: auto) {
  .container {
    padding-top: 56.25%;
    position: relative;
  }

  .container iframe {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0px;
    left: 0px;
  }
}

上の例では、ブラウザがaspect-ratioプロパティに非対応かどうかで条件分岐しています。

ブラウザがaspect-ratioプロパティに非対応の場合は、従来使われていたpaddingとpositionでのハック的な指定が適用されます。

background-clipのグラデーションテキスト

/* background-clip非対応ブラウザ用スタイル */
.text {
	color: red;
	display: inline-block;
	font-size: 4em;
	font-weight: bold;
}

/* background-clip対応ブラウザ用スタイル */
@supports ((background-clip: text)) or (-webkit-background-clip: text) {
	.text {
		-webkit-background-clip: text;
		background-clip: text;
		background-image: linear-gradient(90deg, rgba(144, 245, 154, 1), rgba(4, 202, 255, 1));
		color: transparent;
	}
}

上の例ではbackground-clip プロパティに対応するブラウザのみグラデーションテキストが表示され、非対応ブラウザの場合にはcolorプロパティで赤色に表示されます。

※background-clip はすべてのモダンブラウザに対応しているため、IEを使用しなくなった今、非対応ブラウザのスタイルがあたることもありませんが…(参考:“background-clip” | Can I use…

まとめ

CSSの新しいプロパティを使うと日々の開発がラクになります。

@supportsを使えば新しいCSSプロパティを使いつつ、簡単に古いブラウザにも対応できます。

効率よくコーディングを進めていくためにもぜひ導入してみてください!

PENGIN BLOGでは無料のデザインカンプを用意しています。今回ご紹介した@supportsを試しに使ってみる練習にお役立ていただければ嬉しいです!

また、モダンなCSSについても解説しているので、@supportsを使って話題のプロパティを試してみるのもオススメです!