スタイルを使いこなせ!要素の特徴やブラウザのサポート制限をくぐり抜けて使い分けるグラデーションについて考える

こんにちは、ユアサです。
前回からJSとCanvasでレーダーチャートを作成する記事を作成しましたが、弊社で取り扱った案件でグラデーションを使うことがあり自分の備忘録という意味でもまとめておきたいと思ったので、今回は少し逸れてCSSでグラデーションを使う際のポイントなどをまとめていこうと思います。

(1)背景グラデーションの見える範囲

ブロック要素とインライン要素どちらにもbackgroundのlinear-gradient等でグラデーションを指定することはできますが、それぞれの要素の特徴ゆえにデフォルトの状態ではグラデーションの表示される範囲が違ってきます。

See the Pen gradetion-text-back by felly (@felly00505) on CodePen.

例としてspanタグとpタグの見え方を比べていきます。
上記コードでは上から

  • インライン要素のspanタグ
  • ブロック要素のpタグ
  • ブロック要素のpタグ(widthが固定値500px)

と並んでいて、spanタグは要素の中身の分だけグラデーションが0%→100%と広がり満遍なく背景にグラデーションがかかっています。上から二番目のpタグでは要素の中身が表示されている範囲を一つのブロックとしてその背景全体にグラデーションがかかっており、一番下のwidth: 500pxのpタグは親要素より大きいので途中で途切れていてグラデーションがどこまで伸びているのか判定しづらいですが、途切れている分にもしっかり伸びていて全体にかかっている状態でした。
このように、(当たり前の話ではあるんですが)ブロック要素とインライン要素とでは背景の伸び方がそれぞれの要素の性質に依存しているので、この特徴を把握して要素を使い分けていけるといいですね。
(background-clip: textを使用してテキストそのものにグラデーションをかける場合でも同様です)

(2)borderにグラデーションをかける

borderそのものにもグラデーションをかけることができ、指定された要素の周りに画像を描画するborder-imageとその画像の使用範囲を指定するborder-image-sliceを併用して作成することができます。
ほとんどのブラウザでは問題なく扱えますが、(ごく少数ではありますが)一部ブラウザではサポートしていない場合があるようです。

赤色の部分がいわゆるNot Supportの箇所になるんですが、border-imageは許容範囲内としてborder-image-sliceの方がちょっと怪しい感じがしますね・・・。
全ブラウザ対応させたい場合にはちょっと力ずくな小技になりますが、グラデーションのかかったborderをつけたい要素の擬似要素や子要素などでグラデーション背景を指定し(親要素のborder: noneも忘れずに)、親要素のサイズより少し大きめにしてposition: absoluteやz-indexなどを使って適宜表示位置を調整すると、border-imageを使わずうまい具合にグラデーションのborderがかかったような表示にすることもできます。

See the Pen gradation-border by felly (@felly00505) on CodePen.

今回はブラウザのサポート範囲内に焦点を当てましたが、グラデーションの範囲にアニメーションで変化を与えたい場合などでも後者のやり方は使えそうな気がします。

(3)background-clip: textで注意したいこと

以前に紹介したbackgroundの要素についてまとめた記事でも書きましたが、background-clip: textで背景グラデーションを透かしたようにテキストの色として反映させることができます。
僕自身、弊社の案件でこれを使用していたんですが、予想だにしなかった落とし穴がありました・・・・・。

See the Pen gradation-text by felly (@felly00505) on CodePen.

上記コードには二種類テキストが用意されていて、通常のpタグだけのものとpタグ内にspanタグがありflexをかけているものがあります。ほとんどのブラウザでならこの二種類は問題なく表示されますが、これをおそらくiOS14以前のちょっと古いバージョンのiphoneのSafariで閲覧しようとすると後者のテキストが表示されなくなっているかと思います(もしCodePenの仕様などで表示できていた場合はすいません)。
これは現象通り古いバージョンのiphoneのSafariでのみ発生するバグで、background-clipが使用されている要素内でdisplay: flexを併用するとテキストが非表示の状態になってしまいます。iOS15以降ではこの現象は解消されているので将来的には心配ありませんが、現状まだ警戒しておいた方がいいかもしれません。

まとめ

今回は要素の特徴やブラウザのサポートなどを考慮してグラデーションをどう使っていくかの紹介をしました。
最後のバグの解決法は探すのに少し手間取りましたね・・・・かなりピンポイントなバグだったので最初発見した時は絶望しました・・・。(苦笑)
今回も最後まで読んでいただきありがとうございました(^人^)