CSSの@supportsを使ってCSSのみでスタイルの条件分岐をする方法

Webブラウザーによって表示可能なCSSが異なるのは、よく知られていることです。例えばChromeやSafariでは問題なく表示される filter は、Internet Explorerではうまく表示されず、別のスタイルを用意しなければいけません。今回は @supports を使って対応しているプロパティー別にスタイルを変更してみましょう。

↑私が10年以上利用している会計ソフト!

@supports とは?

指定した (プロパティー:値) の条件に対応しているブラウザーには {} 内に書かれたスタイルを適用するよ、というもの。新しいスタイルの書き方に対応しているブラウザーにはそれを、対応していないブラウザーには従来の書き方で、かつ見栄えの崩れないようにコンテンツを提供できるよう、CSSを記述していけます。「プログレッシブエンハンスメント」というやつですね。

有名なJavaScriptライブラリー「Modernizr」の役割を、CSSでやってのける、というわけです!

@supportsに対応しているブラウザー

caniuse
Can I use…を見ると、IE以外のモダンブラウザーに対応しています。そのため、基本的にIE用にCSSを書き、ブラウザーごとに対応状況の異なるスタイルに @supports を使って対応させるとよいでしょう。

@supportsの記述方法

まずは簡単な例を。以下のコードをCSSファイルに記述すると、Flexboxに対応しているブラウザーにはFlexboxを適用させます。Flexboxって何?という人は、過去記事「これからのCSSレイアウトはFlexboxで決まり!」を読んでみてくださいね!

@supports (display: flex) {
  .flexbox {
    display: flex;
  }
}

not、and、or も使える

not (プロパティー:値) を使うと、それに対応していないブラウザーに向けてスタイルを指定できます。以下の例では、Flexboxに対応していないブラウザーには従来どおり float を使ってコンテンツを横並びにしています。

@supports not (display: flex) {
  .flexbox {
    overflow: hidden;
  }
  .flexbox div {
    float: left;
  }
}

and は「指定した複数のスタイルの、どちらにも対応している場合のみ」を条件に指定できます。

@supports (animation: example 2s infinite) and (transform: rotate(-45deg)) {
  /* ここにCSSが入ります */
}

or は「指定した複数のスタイルの、どちらかに対応している場合」を条件に指定できます。同じスタイルに対して複数のベンダープレフィックスを指定する場合等に使えます。

@supports (display: flex) or (display: -webkit-flex) {
  /* ここにCSSが入ります */
}

注意点1:スペースが必要

notandor を使う場合は、その前後にスペースが必要です。

/* 悪い例 */
@supports (display: flex)or(display: -webkit-flex) {
  /* ここにCSSが入ります */
}

/* 良い例 */
@supports (display: flex) or (display: -webkit-flex) {
  /* ここにCSSが入ります */
}

注意点2:カッコが必要

条件にする プロパティー:値 は必ずカッコ () で囲みます。

/* 悪い例 */
@supports display: flex {
  /* ここにCSSが入ります */
}

/* 良い例 */
@supports (display: flex) {
  /* ここにCSSが入ります */
}

@supportsを使った実例

実際にどんな場面で使えるのか、実例を紹介します。

1. iOS風に下に重なったコンテンツをぼかす

下のレイヤーにある画像やテキストなどのコンテンツをぼかして、上のレイヤーを目立たせるという、iPhoneユーザーにはお馴染みのエフェクト。JavaScript等を使って様々なスニペットが公開されていますが、現在Safariにのみ対応している backdrop-filter が一番簡単です。

ただし、Safari以外のブラウザーだと適用されないので、この例ではSafari以外のブラウザーはぼかしなしで、背景色である白の不透明度を高くしています。

header {
  padding: 5px 0;
  position: fixed;
  top: 0;
  width: 100%;
  background: rgba(255,255,255,.9);
}

@supports (-webkit-backdrop-filter: blur(5px)) {
  header {
    -webkit-backdrop-filter: blur(5px);
    background: rgba(255,255,255,.5);
  }
}

See the Pen backdrop-filter by Mana (@manabox) on CodePen.


サンプルをスクロールしてみてください。Safariで見ると後ろの画像やテキストがぼかされてますね!早くすべてのブラウザーに対応してくれますように!

2. グラデーションのテキスト

テキストの色をグラデーションにするには、テキスト要素の背景をグラデーションカラーにし、テキストでマスクをかける方法を使います。しかし、マスクをかけるにはSafariとChromeで使える background-clip を利用するので、対応していないブラウザーには普通の塗りつぶし色を適用させましょう。

.gradient-text {
  color: #E55D87;
}

@supports
  (-webkit-background-clip: text) or
  (background-clip: text) {
  .gradient-text {
    background: linear-gradient(90deg, #E55D87 10%, #5FC3E4 90%);
    color: transparent;
    -webkit-background-clip: text;
    background-clip: text;
  }
}

See the Pen CSS gradient colour by Mana (@manabox) on CodePen.


同じプロパティーと値を繰り返し記述するのはなんだかスマートではないのですが、JavaScriptに頼らず実装できるのは利点かなーと思います。もちろんサイトによってはこれがベストな書き方とは言えないかもしれません。「こんな書き方もあるよー」ということで、ぜひ試してみてください!

シェアする

ニュースレター

Web制作の最新情報やWebクリエイターボックスからのお知らせ、中の人の近況等を定期的にお送りいたします。 ぜひご登録ください!もちろん無料です! :)