CSSで画像の上に表示するテキストをより読みやすく、より美しくするテクニック・実装方法のまとめ
Post on:2021年4月8日
画像の上にテキストを配置する際に、より読みやすく、より美しくするCSSのテクニックを紹介します。
CSSで画像上にテキストを表示する際に起こる問題に対するさまざまなアプローチと解決するための実装方法を解説。また、最近見かけた素晴らしいテクニック、便利なツールなども紹介します。
Handling Text Over Images in CSS
by Ahmad Shadeed
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
- はじめに
- テキストを読みやすくするためのさまざまなテクニック
- グラデーションのオーバーレイを使ったテクニック
- イージングのグラデーションを使ったテクニック
- 水平方向のグラデーションを使ったテクニック
- ソリッドカラーとグラデーションの混合
- グラデーションのオーバーレイとtext-shadow
- グラデーションのオーバーレイ、text-shadow、そして不透明度
- 放射状グラデーションを使ったテクニック
- オーバーレイに使用するアクセシブルなカラーの選択
- グラデーションが適切か検証する方法
- 終わりに
はじめに
画像の上にテキストが表示されているUIコンポーネントを見たことがあると思います。使用されている画像によっては、テキストが読みにくくなる場合があります。そのような場合の解決方法としては、グラデーションのオーバーレイを加えたり、背景画像に色を与えたり、text-shadowを使用するなどがあります。このツイートで、私はこの記事を書くように勧められました。
この記事では、CSSで画像上にテキストを表示する際に起こる問題に対するさまざまなアプローチと解決方法を解説します。デザインのモックアップ通りに実装されているかどうかを確認するために、フロントエンドの開発者とUIをどのようにコミュニケーションするかを考えたいと思います(CSSでは一部のディテールが簡単に見落とされる可能性があります)。
ここで解説するテクニックは、問題を解決することを前提としています。そのためには、まず問題点を探ります。画像の上にテキストを表示するコンポーネントをデザインする際は、そのテキストを読みやすくすることに気をつけなければなりません。
左: オーバーレイなし、右: オーバーレイあり
左の方は、テキストが読みにくいことに注目してください。これはユーザーにとってよくないことです。これを解決するには、テキストの下にレイヤーを追加して、読みやすくする必要があります。しかし、このレイヤーを追加するのは難しい場合があり、アクセシビリティを考慮せずに実装しているのを多く見かけます。
テキストを読みやすくするためのさまざまなテクニック
テキストを読みやすくするためのさまざまなテクニックがあります。それらを一通りチェックしてみましょう。
テキストを読みやすくするためのテクニック
ご覧の通り、さまざまな解決方法があります。特に注意が必要なのは、グラデーションを使用したテクニックです。なぜだと思いますか? グラデーションのレイヤーを追加するのはとても簡単ですが、テキストにアクセスできなくなるからです。
グラデーションのオーバーレイを使ったテクニック
一般的にグラデーションのオーバーレイは、画像上のテキストをより明確にするための最も一般的な解決方法です。それを踏まえて、もう少しフォーカスを当てます。
グラデーションのオーバーレイを実装する際には、2つのオプションがあります。
- グラデーションに分離された要素を使用する(疑似要素または空の<div>)。
- グラデーションを背景画像として適用する。
それぞれに長所と短所があります。実際の例で見てみましょう。
コンテンツは絶対配置されており、グラデーションは背景画像として使用しています。これは、グラデーションのサイズが要素の高さに等しいことを意味します。
1 2 3 4 5 |
.card__content { position: absolute; /* other styles (left, top, right, and padding) */ background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent); } |
コンテンツは絶対配置、グラデーションは背景で実装
一見すると、グラデーションがうまく機能しているように見えるかもしれません。しかし、これは正しくありません。同じグラデーションを他の画像で試してみた結果は、下記のとおりです。
同じグラデーションを他の画像で試してみた結果
白抜きのテキストと画像のコントラストが常に明確であるとは限らないことに注目してください。一部の画像では読みやすいかもしれませんが、アクセシブルではないため、このようなグラデーションを使用することは大きな間違いです。
その理由は、グラデーションは垂直方向により多くスペースをカバーする必要があるため、高さを大きくする必要があるからです。グラデーションのサイズをコンテンツのサイズと同じにすることは、すべての場合に機能するとは限りません。これを解決するには、min-heightを次のように使用します。
- .card__content要素にmin-heightを与える。
- Flexboxで、コンテンツを一番下にプッシュする。
1 2 3 4 5 6 7 8 |
.card__content { position: absolute; /* other styles (left, top, right, and padding) */ display: flex; flex-direction: column; justify-content: flex-end; background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent); } |
別の解決策としては、単純に大きなpadding-topを使用することです。min-heightやFlexboxは必要ありません。
1 2 3 4 5 |
.card__content { position: absolute; padding-top: 60px; background: linear-gradient(to top, rgba(0, 0, 0, 0.85), transparent); } |
左のカードと右のカードの違いに注目してください。グラデーションの高さが大きくなっています。
左: ビフォー、右: アフター、グラデーションの高さが大きくなっている
これでうまく機能します!
イージングのグラデーションを使ったテクニック
グラデーションをよく見ると、終わりがはっきりとしていて、ハードエッジと呼ばれるものがあります。
グラデーションのハードエッジ(hard edge)
これを改善するには、イージングの概念をグラデーションに適用します。そうすると、グラデーションがより自然に見え、グラデーションの終わりにハードエッジが表示されることはありません。
左: ハードエッジがあるグラデーション、右: イージングのグラデーション
CSSでこのイージングを実現するためには、複数のグラデーションストップを用意する必要がありますが、この記事を書いている現時点ではネイティブな方法はありません。幸いなことに、CSSグラデーションにイージングを実装する可能性についてCSSのワーキンググループで議論されているところですが、実現がいつになるかは明らかではありません。
ありがたいことに、Andreas Larsen氏は、通常のグラデーションをイージングのグラデーションに変換するPostCSSとSketchの便利なプラグイン「Easing Gradients」を作成しました。
イージングのグラデーションを実装するCSSは、下記のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
.card__content { background-image: linear-gradient( 0deg, hsla(0, 0%, 35.29%, 0) 0%, hsla(0, 0%, 34.53%, 0.034375) 16.36%, hsla(0, 0%, 32.42%, 0.125) 33.34%, hsla(0, 0%, 29.18%, 0.253125) 50.1%, hsla(0, 0%, 24.96%, 0.4) 65.75%, hsla(0, 0%, 19.85%, 0.546875) 79.43%, hsla(0, 0%, 13.95%, 0.675) 90.28%, hsla(0, 0%, 7.32%, 0.765625) 97.43%, hsla(0, 0%, 0%, 0.8) 100% ); } |
あとは、このグラデーションを適用するだけです。
左: イージングあり、右: イージングなし
イージングありの方が読みやすいですね。ハードエッジもありません。
水平方向のグラデーションを使ったテクニック
画像上のテキストを扱うのは、垂直方向だけでなく、水平方向のグラデーションとしても使用できます。例えば、ヒーローセクションを例に見てみましょう。
ヒーローセクションで、水平方向のグラデーションんを使った例
上記のヒーローセクションのCSSグラデーションは下記のとおりです。前述のツール「Easing Gradients」を使用して、イージングのグラデーションを生成しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
background: linear-gradient( to right, hsl(0, 0%, 0%) 0%, hsla(0, 0%, 0%, 0.964) 7.4%, hsla(0, 0%, 0%, 0.918) 15.3%, hsla(0, 0%, 0%, 0.862) 23.4%, hsla(0, 0%, 0%, 0.799) 31.6%, hsla(0, 0%, 0%, 0.73) 39.9%, hsla(0, 0%, 0%, 0.655) 48.2%, hsla(0, 0%, 0%, 0.577) 56.2%, hsla(0, 0%, 0%, 0.497) 64%, hsla(0, 0%, 0%, 0.417) 71.3%, hsla(0, 0%, 0%, 0.337) 78.1%, hsla(0, 0%, 0%, 0.259) 84.2%, hsla(0, 0%, 0%, 0.186) 89.6%, hsla(0, 0%, 0%, 0.117) 94.1%, hsla(0, 0%, 0%, 0.054) 97.6%, hsla(0, 0%, 0%, 0) 100% ); |
ソリッドカラーとグラデーションの混合
ソリッドカラーとグラデーションの混合を知ったのは、Netflixのサイトからです。ログインしていないユーザー向けのトップページには、大きな背景画像付きのヘッドラインがあります。
Netflixのトップページ
グラデーションが多くの画像を隠しますが、私は非常にかっこいいと思います。このデザインは、画像が装飾的なもの(エンドユーザーに実際の利益をもたらさない)である場合にのみ使用してください。
1 2 3 4 5 6 7 |
<div class="hero"> <img src="cover.jpg" alt="" /> <div class="hero__content"> <h2>Unlimited movies, TV shows, and more.</h2> <p>Watch anywhere. Cancel anytime.</p> </div> </div> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
.hero:after { content: ""; position: absolute; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.4); background-image: linear-gradient( to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0) 60%, rgba(0, 0, 0, 0.8) 100% ); } |
このパターンがどのように機能するかを視覚的にまとめました。
実装の仕組み
グラデーションのオーバーレイとtext-shadow
画像上のテキストをより美しくすることができるちょっとした工夫があります。それは、テキストに繊細なtext-shadowを加えることです。これに気づくのは簡単ではないかもしれませんが、画像の読み込みに失敗したときなどにも役立ちます。
1 2 3 |
.whatever-text { text-shadow: 0 2px 3px rgba(0, 0, 0, 0.3); } |
テキストにほんの少しシャドウを加えることで、美しくなります。
ほんの少しだけtext-shadowを加える
グラデーションのオーバーレイ、text-shadow、そして不透明度
これは、Facebookの動画プレーヤーで気付いたパターンです。テキスト(およびその他のUI要素)を明確にするために、複数のテクニックを使っているのがいいですね。動画プレーヤーを扱う際には、その上の要素が目立つようにすることがとても重要です。
Facebookの動画プレーヤー
1 2 3 4 5 6 7 8 |
.player__icon { opacity: 0.9; } .player__time { color: #fff; text-shadow: 0 0 5px #fff; } |
ここでの注目は、アイコンに定義されたopacity: 0.9;です。これにより、その下にある背景との調和に効果があります。コントローラーとアイコンが一体化されているように感じられます。
また、白い文字には白いテキストシャドウを使うと、テキストをより鮮明に見せることができて効果的です。背景が真っ白な画像であっても、上記のような効果があることを証明したいと思いませんか? ほら、この通りです。
背景が真っ白でも、テキストは鮮明に見える
YouTubeも同様のことをしています。
YouTubeの動画プレーヤー
Youtubeのアプローチで、私が気に入った点は次のとおりです。
- アイコンの枠を黒くして、より目立つようにしている。
- 時間表記に白ではなく黒のシャドウを使用している。
放射状グラデーションを使ったテクニック
Netflixから学んだ興味深い解決策は、放射状のグラデーションを使うことです。その方法を紹介します。
- ヒーローにベースバックの背景色を設定する。
- 画像を75%の幅で右上に配置する。
- オーバーレイは、画像のサイズと位置に等しくなる。
Netflixで使用されているグラデーション
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
.hero { background-color: #000; min-height: 300px; } .hero__image { position: absolute; right: 0; top: 0; width: 75%; height: 100%; object-fit: cover; } .hero:after { content: ""; position: absolute; right: 0; top: 0; width: 75%; height: 100%; background: radial-gradient( ellipse 100% 100% at right center, transparent 80%, #000 ); } |
Netflixでは、オーバーレイに.png画像が使用されています。その理由についてはよく分かりません。放射状グラデーションを使ったテクニックを十分にテストしなかったため、クロスブラウザの問題が何かあるのかもしれません。
オーバーレイに使用するアクセシブルなカラーの選択
Optimal Overlay Finderは、画像に応じて適切なオーバーレイの不透明度を選択するのに役立つ素晴らしいツールです。特に興味深い点は、グラデーションのアクセシビリティを処理することです。
一般的には、グラデーションのオーバーレイがテキストを正しく塗りつぶし、色のコントラストが適切であれば問題ありません。
グラデーションが適切か検証する方法
実際に検証してみないと、良い解決方法とは言えませんよね。私がグラデーションのオーバーレイをテストする際に使用している方法は、グラデーションの下に白い背景を追加することです。これでテキストが読めれば、どんな画像を使用してもグラデーションは機能します。読めない場合は、調整する必要があります。
白い背景を使用して検証
タイトル下のベタ塗りを選んだところ、コントラスト比が4.74となり、アクセシビリティは良好と考えられます。
デベロッパーツールで検証する方法
Firefoxのデベロッパーツールでグラデーションのコントラストを検証できることを知らせてくれたGijsVeyfeykenに感謝します。素晴らしい機能です。
デベロッパーツールで、グラデーションのコントラストを検証
終わりに
CSSのデバッグに関する電子書籍を書いていることをお知らせします。
興味がある場合は、debuggingcss.comにアクセスして、本に関する最新情報を購読してください。
コメントや提案があれば、@shadeed9までお願いします。
sponsors