見出しの文字をグラデーションにしたい。ロゴのような装飾文字を作りたい。こうしたとき、画像として書き出してしまうと、文字が検索されなくなり、あとから修正するのも面倒です。
CSS の background-clip: text を使えば、テキストのまま実現できます。背景に敷いたグラデーションや画像を、文字の形に切り抜いて表示するという仕組みです。
この記事では、background-clip の4つの値と、文字をグラデーションで塗る基本の書き方、画像やアニメーションを使った応用、そして文字が消えてしまうときの対処までを解説します。
目次
background-clip は背景を描く範囲を決めるプロパティ
要素の背景は、既定では枠線(border)の外側まで広がって描かれています。background-clip は、この「どこまで背景を描くか」を指定するプロパティです。
| 値 | 背景が描かれる範囲 |
|---|---|
border-box | 枠線の外側まで(既定値) |
padding-box | 枠線の内側まで。点線や半透明の枠線のとき違いが出る |
content-box | パディングを除いた、内容の領域だけ |
text | 文字の形に切り抜く |
上3つは地味ですが、点線の枠線を使ったときに背景色が線の隙間から見えてしまう、といった場面で padding-box が役に立ちます。そして4つめの text が、今回の主役です。
文字をグラデーションで塗る
やることは3つだけです。背景にグラデーションを敷き、background-clip: text で文字の形に切り抜き、文字自体を透明にして背景を見えるようにします。
<h2 class="gradient-text">グラデーションの見出し</h2>
<p class="note">文字の形で背景を切り抜いています。選択やコピーも普通にできます。</p>
.gradient-text {
/* 1. 背景にグラデーションを敷く */
background-image: linear-gradient(90deg, #007bff, #e83e8c 50%, #fd7e14);
/* 2. 背景の描画範囲を文字の形にする */
-webkit-background-clip: text;
background-clip: text;
/* 3. 文字自体を透明にして、背景を見せる */
color: transparent;
font-size: 40px;
font-weight: bold;
margin: 0 0 12px;
}
.note {
color: #555;
font-size: 14px;
margin: 0;
}
3つめの color: transparent が欠かせません。これを書かないと、文字そのものの色が上に乗ったままになり、切り抜いた背景が隠れてしまいます。
画像として書き出した場合と違い、中身はテキストのままです。選択してコピーできますし、検索にも引っかかり、スクリーンリーダーも読み上げます。文字サイズを変えても崩れません。
-webkit- を付ける理由
この機能はもともと WebKit の独自拡張として広まった経緯があり、長いあいだ -webkit-background-clip: text という書き方が必要でした。現在は接頭辞なしの background-clip: text も広くサポートされていますが、古い Safari のことを考えると、両方書いておくのが安全です。
.gradient-text {
background-image: linear-gradient(90deg, #007bff, #e83e8c);
/* 接頭辞付きを先に、標準の書き方をあとに書く */
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
順番は「接頭辞付きが先、標準があと」です。CSS は後に書いたほうが優先されるため、標準の書き方に対応しているブラウザーではそちらが使われます。
文字を透明にする指定は color: transparent のほかに -webkit-text-fill-color: transparent もあります。どちらでも動きますが、color のほうが標準のプロパティなので、まずはこちらで書いておけば十分です。
画像やアニメーションで塗る
切り抜かれるのは「背景」なので、グラデーションに限らず画像も使えます。background-size: cover と組み合わせると、文字の中に写真が入ったような表現になります。
.photo-text {
background-image: url("/images/sky.jpg");
background-size: cover;
background-position: center;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
font-size: 64px;
font-weight: 900;
}
細い書体だと写真の情報が読み取れず、ただの汚れた文字に見えてしまいます。この表現を使うときは、太めのフォントと大きな文字サイズを選んでください。
背景の位置を動かせば、グラデーションが流れるアニメーションも作れます。背景を横長にしておき、background-position をずらし続けるという作り方です。
.flowing-text {
background-image: linear-gradient(
90deg,
#007bff, #e83e8c, #fd7e14, #007bff
);
/* 要素の3倍の幅を持たせて、その中を移動させる */
background-size: 300% 100%;
-webkit-background-clip: text;
background-clip: text;
color: transparent;
animation: flow 6s linear infinite;
}
@keyframes flow {
to {
background-position: -200% 0;
}
}
/* 動きを減らす設定をしている人には止めて見せる */
@media (prefers-reduced-motion: reduce) {
.flowing-text {
animation: none;
}
}
グラデーションの最初と最後に同じ色を置いておくと、ループしたときに色が飛ばず、なめらかにつながります。
枠線と背景の関係を整える
text 以外の値も見ておきます。点線の枠線を引いた要素に背景色を付けると、既定では点と点のすき間から背景色がのぞきます。これを避けたいときに padding-box を使います。
.ticket {
border: 3px dashed #007bff;
background-color: #e7f1ff;
/* 背景を枠線の内側までにとどめる */
background-clip: padding-box;
padding: 16px;
}
もう1つの使いどころが、background-clip: content-box と background-color の組み合わせです。パディングの部分だけ背景を抜けるので、内側に余白のある枠のような表現ができます。
文字が見えなくなるときの対処
対応していない環境で真っ白になる
最も注意すべき失敗がこれです。background-clip: text が効かない環境では、color: transparent だけが適用され、文字が完全に見えなくなります。背景色が白いページなら、そこに何も無いように見えてしまいます。
これを防ぐには、@supports で対応を確認してから透明にします。
/* 通常の文字色を先に指定しておく */
.gradient-text {
color: #007bff;
}
/* 対応している環境だけ、グラデーションに差し替える */
@supports (background-clip: text) or (-webkit-background-clip: text) {
.gradient-text {
background-image: linear-gradient(90deg, #007bff, #e83e8c);
-webkit-background-clip: text;
background-clip: text;
color: transparent;
}
}
こう書いておけば、対応していない環境では単色の文字として表示されます。装飾が1段階落ちるだけで、読めなくなることはありません。
背景が付いているのに文字が単色のまま
color: transparent の書き忘れか、他のルールに上書きされています。開発者ツールで color の値を確認してください。テーマやフレームワークが h2 { color: #333; } のような指定を持っていると、詳細度によってはそちらが勝ちます。
文字の一部しか色が付かない
背景は要素の大きさに合わせて描かれるため、display: inline の要素に指定すると、行ごとに背景が分割されて意図しない見た目になります。display: inline-block にするか、ブロック要素に指定してください。
逆に、見出し全体が画面幅いっぱいに広がっていると、グラデーションも画面幅に対して引き伸ばされます。文字の部分だけで色を変化させたいときは、display: inline-block にして要素の幅を文字に合わせるのが手軽です。
影や縁取りが効かない
text-shadow は文字の色に対して落ちる影なので、文字が透明だと影も見えません。影を付けたい場合は、親要素に filter: drop-shadow() を指定すると、切り抜かれた形に対して影が落ちます。
まとめ
background-clip は背景を描く範囲を指定するプロパティで、text を指定すると背景が文字の形に切り抜かれます。グラデーションの見出しを作るなら、背景を敷く・background-clip: text を指定する・color: transparent にする、の3行で完成です。
気をつけたいのは、対応していない環境で文字が消えてしまう点です。@supports で囲って通常の文字色をフォールバックとして用意しておけば、この事故は防げます。Safari のことを考えて -webkit-background-clip も併記しておくと確実です。
画像として書き出す方法と違い、テキストのまま扱えるのが最大の利点です。文言の修正もコピーも検索も普通にできるので、見出しの装飾にはこちらを選びたいところです。