【CSS】地味に厄介な「背景色付きテキスト(横幅追従・paddingあり)」のコーディング方法
当サイトのリンクには広告が含まれています。
このアイキャッチ画像のように「テキスト量に追従して背景が付く」デザインってありますよね。画像に乗っかるテキストの可読性を上げる手法です。
しかしこのデザイン。例えば「先方が入力するテキストに自動で反映して」と言われたら、どうCSSを組みますか?
決め打ちのテキストでは無く、文字数も行数も折り返す場所も不確定。背景は幅いっぱいでは無くテキスト量に追従。さらにpadding
の指定。行間同士もくっつけないで離す。そして勿論先方がソースコードを書くなんてナッシング。行ごとにspan
等、個別のタグで囲む事も出来ず。。
……と、まあ一見単純なデザインの割にコーディングで再現するには色々と条件が重なり地味に厄介。…というかモダンCSSを使わないと実は困難です。
結論から言うとbox-decoration-break
プロパティを使って解決します。
ここにテキストが入ります
ここにテキストが入りますここにテキストが入りますここにテキストが入ります。
<h2>
ここにテキストが入ります<br>
ここにテキストが入りますここにテキストが入りますここにテキストが入ります。
</h2>
h2{
display: inline;
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
/* 以降の設定はデザインに合わせて調整 */
font-size: 24px;
font-weight: 700;
padding: .4em 1em;
line-height: 2.8;
background: rgba(255, 255, 255, .8);
}
単純にインライン要素では何故ダメなのか
まず求められている仕様を確認します。
- テキストの背景に色をつける。背景は横100%の長さではなく、テキスト量に追従する
- テキストの上下左右に余白(padding)をつける
- 行ごとにも余白(margin or line-height)をつける。さらに1行ずつ
span
等タグで囲むことはせず、ただ流し込まれたテキストに自動で反映させる - テキストの文字数及び行数。そして改行(折返し)されるタイミングは不確定とする
背景色は横100%ではなく、テキスト量に追従する。つまりテキストはブロック要素ではなくインライン要素である必要があります。では単純にインライン要素で囲って色を付けてみましょう。
NG例 その1
ここにテキストが入ります
ここにテキストが入りますここにテキストが入りますここにテキストが入ります。
h2{
display: inline;
/* 以降の設定はデザインに合わせて調整 */
font-size: 24px;
font-weight: 700;
padding: .4em 1em;
line-height: 2.8;
background: rgba(255, 255, 255, .8);
}
ぱっと見では上手くいっていますが、テキストの余白部分であるpadding
が期待している結果と異なりますよね。前後のpadding
は要素の始点と終点にしか効かないので折返しの改行地点には適用されていません。
手動で1行ずつインライン要素で囲むと?
ではテキスト部分を1行ずつspan
で囲み、それを装飾すれば……。これならばデザイン自体は再現出来ます。
しかし先述した条件の通り、今回はソースコードの編集を想定せず、先方がCMSにただ流し込んだテキストに自動で反映させなければならないので、この手法もNG。
そもそも仮にこの手法を使ってもテキスト量に合わせて行毎にタグの調整が必要で、コンポーネントとして汎用性が低すぎます。決め打ちの原稿箇所にしか使えず内容が変更されたら都度調整が必要です。面倒くさすぎる。
NG例 その2
ここにテキストが入りますここにテキストが入ります
ここにテキストが入ります。
<h2>
<span>ここにテキストが入ります</span><br>
<span>ここにテキストが入りますここにテキストが入ります</span><br>
<span>ここにテキストが入ります。</span>
</h2>
h2 span{
/* 以下、例1と同様につき省略 */
}
力技で1行ずつ対応したパターン。保守性も悪い上、改行にはbr
を利用。その結果、端末の横幅によって意図しないタイミングで折り返しされてしまう。上記の例もスマホだと中途半端な位置で改行される。
box-decoration-breakを使って解決
ここで冒頭の結論に戻り、box-decoration-break
を活用。
あまりメジャーな印象は無いプロパティですが、要素が改行(断片化)した際の表示形式を指定する事が出来ます。
今回の場合clone
を指定し、同じ描写をコピーさせる事で折り返し地点にも装飾が個別に適用されるようになります。
ここにテキストが入ります
ここにテキストが入りますここにテキストが入りますここにテキストが入ります。
<h2>
ここにテキストが入ります<br>
ここにテキストが入りますここにテキストが入りますここにテキストが入ります。
</h2>
h2{
display: inline;
box-decoration-break: clone;
-webkit-box-decoration-break: clone;
/* 以降の設定はデザインに合わせて調整 */
font-size: 24px;
font-weight: 700;
padding: .4em 1em;
line-height: 2.8;
background: rgba(255, 255, 255, .8);
}
実は意外と昔からあるプロパティですが、2023年現在でも主要ブラウザにはベンダープレフィックスが必要なのでそこだけは注意が必要です。
https://caniuse.com/css-boxdecorationbreak
以上。地味に厄介な「背景色付きテキスト」のコーディング方法でした。
このプロパティを知るまでは、なかなか妙案がありませんでしたが、これでもう恐れる必要はありませんね。