CSSのcontentプロパティは、疑似要素(::before/::after)を使ってHTMLを汚さずにテキストや画像、アイコンを挿入できる、装飾デザインの要となるプロパティです。
本記事では、基本的な文字や改行の入れ方、attr()を使ったデータ属性の取得、Font Awesomeなどのアイコン表示における文字化けの解決策まで実務で必須となるcontentを解説します。
また、CSSに関するカテゴリーページから学びたい内容を決めたい人は、以下のCSSページをご確認ください。
疑似要素contentの基本と文字の挿入
Webサイトのデザインで、リンクの横に矢印アイコンをつけたり、見出しの先頭に装飾を入れたりする際に使われるのが、CSSの「疑似要素(::beforeや::after)」です。
疑似要素である::beforeと::afterの使い方を詳しく知りたい人は「【CSS】::before・::after擬似要素の使い方:画像・アイコン・ホバーエフェクト」を一読ください。
この疑似要素を画面上に表示させるために欠かせないプロパティがcontentです。
contentの使い方は、HTMLに直接書かれていない要素をCSS側から擬似的に生成して挿入することにあります。
ここでは、contentの基礎から様々な値の指定方法、疑似要素を使った実践的な装飾テクニックを解説します。
- テキストや空白・改行の入れ方
- カスタムデータ属性や連番の取得
- HTMLタグは入れられない&文字化けの解決策
テキストや空白・改行の入れ方
contentプロパティの基本的な使い方は、任意のテキストを挿入することです。
値として" "(ダブルクォーテーション)または' '(シングルクォーテーション)で囲んだ文字列を指定します。
また、文字と文字の間に「空白」を入れたい場合は、単にクォーテーションの中にスペースを空けるか、特殊文字である\00a0を指定します。
疑似要素内で改行(\A)を有効にするには、改行させたい疑似要素に対してwhite-space: pre;またはwhite-space: pre-wrap;をセットで指定することです。
これを忘れると、\Aを書いてもブラウザ上で改行されません。
⭕️ 疑似要素で改行するなら \A と white-space のコンボ!
❌ 改行されない
(white-space指定忘れ)
⭕️ 正しく改行
(\A が効いている)
.no-break::after {
content: ” \A World!”; /* 💡 画面上では「 Hello World!」と1行になる */
}
/* ⭕️ \A を効かせるには white-space プロパティが必須! */
.break::after {
content: ” \A World!”; /* 💡 ここで改行コードを入れる */
white-space: pre; /* 💡 これを指定して初めて改行が有効になる! */
}
HTMLコード表示
<div class="content-layout-wrapper">
<p class="content-caption">⭕️ 疑似要素で改行するなら \A と white-space のコンボ!</p>
<div class="content-demo-area">
<!-- ❌ 失敗:ただ \A を書いただけ(改行されない) -->
<div class="content-box-wrapper">
<p class="content-label">❌ 改行されない<br><small>(white-space指定忘れ)</small></p>
<div class="content-text-box is-no-break">
Hello
</div>
</div>
<!-- ⭕️ 成功:\A と white-space の組み合わせで改行される -->
<div class="content-box-wrapper">
<p class="content-label" style="color:#0d6efd;">⭕️ 正しく改行<br><small>(\A が効いている)</small></p>
<div class="content-text-box is-break">
Hello
</div>
</div>
</div>
<div class="content-code-area">
/* ❌ \A を書いただけで満足してしまう */<br>
<span class="hl-blue">.no-break::after</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">" \A World!";</span> /* 💡 画面上では「 Hello World!」と1行になる */<br>
}<br><br>
/* ⭕️ \A を効かせるには white-space プロパティが必須! */<br>
<span class="hl-blue">.break::after</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">" \A World!";</span> /* 💡 ここで改行コードを入れる */<br>
<span class="hl-green">white-space:</span> <span class="hl-red">pre;</span> /* 💡 これを指定して初めて改行が有効になる! */<br>
}
</div>
</div>CSSコード表示
.content-layout-wrapper {
background-color: #f8f9fa;
padding: 30px;
border-radius: 8px;
border: 1px solid #dee2e6;
}
.content-caption {
font-size: 14px;
font-weight: bold;
margin-bottom: 30px;
color: #198754;
text-align: center;
}
.content-demo-area {
display: flex;
justify-content: center;
gap: 40px;
background-color: #e9ecef;
padding: 40px;
border-radius: 8px;
border: 1px dashed #adb5bd;
margin-bottom: 20px;
}
.content-box-wrapper {
display: flex;
flex-direction: column;
align-items: center;
}
.content-label {
font-size: 13px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
text-align: center;
line-height: 1.5;
}
/* 共通のテキストボックス */
.content-text-box {
background-color: #fff;
border: 1px solid #ced4da;
border-radius: 6px;
padding: 15px;
font-size: 18px;
font-weight: bold;
color: #495057;
text-align: center;
min-width: 120px;
}
/* =❌ 実践コード:改行されない疑似要素= */
.is-no-break::after {
content: " \A World!"; /* \A を入れているが改行されない */
color: #dc3545; /* 赤色で表示 */
}
/* =⭕️ 実践コード:正しく改行される疑似要素= */
.is-break::after {
content: " \A World!"; /* \A を入れる */
white-space: pre; /* 💡 この指定が改行のスイッチ! */
color: #0d6efd; /* 青色で表示 */
}
.content-code-area {
background-color: #282c34;
color: #abb2bf;
padding: 20px;
border-radius: 6px;
font-family: monospace;
font-size: 13px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }white-spaceの使い方を詳しく知りたい人は「【html&css】white-spaceの使い方とnowrap・pre・pre-wrapの使い分け」を一読ください。
カスタムデータ属性や連番の取得
固定のテキストを入れるだけでなく、HTML側に書かれた動的なデータを取得してCSSで表示できるのがcontentプロパティの機能です。
よく使われるのが、HTMLタグに設定したカスタムデータ属性(data-*)の値を引っ張ってくる関数attr()です。
画像のキャプションや、ツールチップの実装などで活躍します。
また、リストや見出しに自動で連番を振るcounter()関数も、手順書やランキングの作成に必須の機能です。
ツールチップ(ホバー時に文字が出るUI)などをattr()で実装する際、「カスタムデータ属性が空(設定されていない)場合のレイアウト崩れ」に注意を払います。
data-tooltipのような属性が付与されている要素に対してのみ疑似要素を生成するよう、属性セレクタ([data-tooltip]::after)を用いてスタイリングを行います。
⭕️ HTMLの属性値(attr)や自動連番(counter)も疑似要素で操れる!
💡 attr(data-tooltip) の活用
(ホバーするとHTMLのdata属性の文字が出現)
💡 counter() の活用
(HTMLには数字を書いていないのに連番になる)
.tooltip::after {
content: attr(data-tooltip); /* 💡 HTMLの data-tooltip=”〇〇” を取得 */
}
/* ⭕️ 親要素でカウンターをリセットし、子で増やす */
.ranking-list {
counter-reset: my-rank; /* 💡 カウンター(変数名my-rank)を0に初期化 */
}
.rank-item::before {
counter-increment: my-rank; /* 💡 項目ごとに+1ずつ増やす */
content: “第” counter(my-rank) “位:”; /* 💡 文字列と counter() を連結! */
}
HTMLコード表示
<div class="content-layout-wrapper">
<p class="content-caption">⭕️ HTMLの属性値(attr)や自動連番(counter)も疑似要素で操れる!</p>
<div class="content-demo-area" style="flex-direction: column; align-items: center; gap: 40px;">
<!-- 💡 attr() のデモ:カスタムデータ属性からテキストを取得するツールチップ -->
<div class="content-attr-demo">
<p class="content-label" style="color:#0d6efd;">💡 attr(data-tooltip) の活用<br><small>(ホバーするとHTMLのdata属性の文字が出現)</small></p>
<button class="content-btn is-tooltip" data-tooltip="これが attr() で取得した文字です!">
マウスを乗せてみて!
</button>
</div>
<!-- 💡 counter() のデモ:CSSだけで自動で連番を振る -->
<div class="content-counter-demo" style="width: 100%; max-width: 300px;">
<p class="content-label" style="color:#198754;">💡 counter() の活用<br><small>(HTMLには数字を書いていないのに連番になる)</small></p>
<div class="content-ranking-list">
<div class="content-rank-item">りんご</div>
<div class="content-rank-item">みかん</div>
<div class="content-rank-item">ぶどう</div>
</div>
</div>
</div>
<div class="content-code-area">
/* ⭕️ attr() の中はクォーテーションで囲まない! */<br>
<span class="hl-blue">.tooltip::after</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">attr(data-tooltip);</span> /* 💡 HTMLの data-tooltip="〇〇" を取得 */<br>
}<br><br>
/* ⭕️ 親要素でカウンターをリセットし、子で増やす */<br>
<span class="hl-blue">.ranking-list</span> {<br>
<span class="hl-green">counter-reset:</span> <span class="hl-red">my-rank;</span> /* 💡 カウンター(変数名my-rank)を0に初期化 */<br>
}<br>
<span class="hl-blue">.rank-item::before</span> {<br>
<span class="hl-green">counter-increment:</span> <span class="hl-red">my-rank;</span> /* 💡 項目ごとに+1ずつ増やす */<br>
<span class="hl-green">content:</span> <span class="hl-red">"第" counter(my-rank) "位:";</span> /* 💡 文字列と counter() を連結! */<br>
}
</div>
</div>CSSコード表示
.content-btn {
padding: 10px 20px;
font-size: 14px;
font-weight: bold;
background-color: #0d6efd;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.is-tooltip {
position: relative; /* ツールチップの基準点 */
}
/* ホバー時に出現する疑似要素 */
.is-tooltip:hover::after {
content: attr(data-tooltip); /* 💡 ここでHTMLの属性値を引き抜く! */
position: absolute;
bottom: 120%; /* ボタンの上に出す */
left: 50%;
transform: translateX(-50%);
background-color: #333;
color: #fff;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
white-space: nowrap; /* 折り返さない */
pointer-events: none;
}
/* =💡 実践コード:counter() を使った自動連番= */
.content-ranking-list {
counter-reset: demo-rank; /* 💡 1. カウンターをリセットして準備 */
display: flex;
flex-direction: column;
gap: 10px;
}
.content-rank-item {
background-color: #fff;
border: 1px solid #ced4da;
padding: 10px 15px;
border-radius: 6px;
font-weight: bold;
}
.content-rank-item::before {
counter-increment: demo-rank; /* 💡 2. 要素が現れるたびに+1する */
content: "No." counter(demo-rank) " - "; /* 💡 3. counter() で数値を表示 */
color: #198754;
}HTMLタグは入れられない&文字化けの解決策
contentプロパティを使う上で、知っておかなければならない制限事項があります。
それは、「contentプロパティの中にHTMLタグを書いてもタグとしては認識されず、文字列として出力される」ということです。
例えば、content: "<span>テキスト</span>";と記述しても、赤い文字のテキストにはならず、画面には<span>テキスト</span>という文字がそのまま表示されてしまいます。
疑似要素でアイコンなどの特殊文字(Unicode)を扱う方法は以下の通りです。
- CSSファイルの1行目に
@charset "UTF-8";を記述し、文字化けを防ぐ。 - Unicodeを指定する際は、先頭にバックスラッシュ(
\)を付ける。 - もし疑似要素内で「HTMLタグを使いたい」といった装飾が必要になった場合は、CSSの疑似要素(
content)の限界と見切りをつけ、HTML側に<span>タグを追加すること。
⭕️ contentにはHTMLタグは効かない!特殊文字(Unicode)は設定に注意
❌ HTMLタグの記述
(ただの文字列として出力される)
⭕️ Unicodeの記述
(バックスラッシュを付けて正しく表示)
.html-fail::after {
content: “<span style=’color:red;’>NG</span>”; /* 💡 タグがそのまま文字として出てしまう! */
}
/* ⭕️ 記号やアイコンはHTMLタグではなく、Unicode(\ + 英数字)を使う */
.unicode-success::after {
content: “\2714 OK”; /* 💡 \2714 はチェックマーク(✔)のコード */
color: #198754; /* 💡 色を変えるなら疑似要素全体に対して指定する */
}
HTMLコード表示
<div class="content-layout-wrapper">
<p class="content-caption">⭕️ contentにはHTMLタグは効かない!特殊文字(Unicode)は設定に注意</p>
<div class="content-demo-area">
<!-- ❌ 失敗:HTMLタグを書こうとしてそのまま表示される -->
<div class="content-box-wrapper">
<p class="content-label">❌ HTMLタグの記述<br><small>(ただの文字列として出力される)</small></p>
<div class="content-tag-box is-html-fail">
Result:
</div>
</div>
<!-- ⭕️ 成功:Unicodeを使った正しいアイコン表現 -->
<div class="content-box-wrapper">
<p class="content-label" style="color:#0d6efd;">⭕️ Unicodeの記述<br><small>(バックスラッシュを付けて正しく表示)</small></p>
<div class="content-tag-box is-unicode-success">
Result:
</div>
</div>
</div>
<div class="content-code-area">
/* ❌ 疑似要素でHTMLタグを使って色を変えようとする */<br>
<span class="hl-blue">.html-fail::after</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">"<span style='color:red;'>NG</span>";</span> /* 💡 タグがそのまま文字として出てしまう! */<br>
}<br><br>
/* ⭕️ 記号やアイコンはHTMLタグではなく、Unicode(\ + 英数字)を使う */<br>
<span class="hl-blue">.unicode-success::after</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">"\2714 OK";</span> /* 💡 \2714 はチェックマーク(✔)のコード */<br>
<span class="hl-green">color:</span> <span class="hl-red">#198754;</span> /* 💡 色を変えるなら疑似要素全体に対して指定する */<br>
}
</div>
</div>CSSコード表示
.content-tag-box {
background-color: #fff;
border: 1px solid #ced4da;
padding: 15px;
border-radius: 6px;
font-weight: bold;
font-size: 14px;
}
/* =❌ 実践コード:HTMLタグが無効になる= */
.is-html-fail::after {
content: "<span style='color:red;'>NG</span>"; /* 💡 文字列としてそのまま出力される */
}
/* =⭕️ 実践コード:Unicodeで正しくアイコンを表示= */
.is-unicode-success::after {
content: "\2714 OK"; /* 💡 先頭に \ を付けたUnicodeでチェックマークを表示 */
color: #198754; /* 疑似要素自体に色をつける */
}spanタグの使い方を詳しく知りたい人は「【HTML】spanタグの使い方:divとの違いやCSS装飾・幅が効かない時の対策」を一読ください。
画像・アイコンの挿入とサイズ調整
contentプロパティは、テキストだけでなく、画像やアイコンを画面に呼び出すツールでもあります。
見出しの横に置く小さなロゴやボタンに添えるアイコンなど、HTMLを汚さずにCSSだけでビジュアルをリッチにできるため、モダンなWeb制作には欠かせません。
しかし、画像を挿入した途端に「位置がズレる」「サイズが変えられない」「アイコンが文字化けする」といったトラブルに直面するのも多いです。
ここでは、URLを使った画像挿入の基本、サイズ変更におけるトラブルの解決策、Font Awesomeなどのアイコンフォントを表示させるルールを解説します。
- url()を使った画像・SVGの挿入と位置調整
- 画像のサイズが変えられない問題の解決策
- Font Awesomeなどのアイコンフォントと特殊文字
url()を使った画像・SVGの挿入と位置調整
疑似要素に画像を挿入する場合、contentプロパティの値としてurl("画像のパス")を使用します。
JPGやPNGだけでなく、ベクター画像であるSVGや画像を文字列化したBase64データを直接書き込むことも可能です。
例えば疑似要素で挿入した画像の位置調整を行い、テキストと縦の中央寄せにする場合は、親要素をdisplay: flex;にしてalign-items: center;で揃えるか、あるいは疑似要素をposition: absolute;にしてtop: 50%;とtransform: translateY(-50%);で中央に固定することです。
実務では、記述がシンプルなFlexboxを使うのが主流です。
⭕️ 疑似要素の画像とテキストを揃えるなら、親にFlexboxを指定せよ!
❌ 位置調整なし
⭕️ Flexboxで中央寄せ
.btn-fail::before {
content: url(“icon.svg”);
}
/* ⭕️ 親要素をFlexboxにして中央をビシッと揃える */
.btn-success {
display: flex;
align-items: center; /* 💡 縦の中央寄せ */
gap: 8px; /* 💡 画像とテキストの隙間 */
}
.btn-success::before {
content: url(“icon.svg”); /* 💡 画像を挿入 */
}
HTMLコード表示
<div class="icon-layout-wrapper">
<p class="icon-caption">⭕️ 疑似要素の画像とテキストを揃えるなら、親にFlexboxを指定せよ!</p>
<div class="icon-demo-area">
<!-- ❌ 失敗:ただ挿入しただけで位置がズレている -->
<div class="icon-box-wrapper">
<p class="icon-label">❌ 位置調整なし</p>
<div class="icon-btn-fail">
<span class="icon-text">Warning</span>
</div>
</div>
<!-- ⭕️ 成功:Flexboxで完璧な中央寄せ -->
<div class="icon-box-wrapper">
<p class="icon-label">⭕️ Flexboxで中央寄せ</p>
<div class="icon-btn-success">
<span class="icon-text">Warning</span>
</div>
</div>
</div>
<div class="icon-code-area">
/* ❌ 画像を挿入しただけで放置すると、テキストとズレる */<br>
<span class="hl-blue">.btn-fail::before</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">url("icon.svg");</span><br>
}<br><br>
/* ⭕️ 親要素をFlexboxにして中央をビシッと揃える */<br>
<span class="hl-blue">.btn-success</span> {<br>
<span class="hl-green">display:</span> <span class="hl-red">flex;</span><br>
<span class="hl-green">align-items:</span> <span class="hl-red">center;</span> /* 💡 縦の中央寄せ */<br>
<span class="hl-green">gap:</span> <span class="hl-red">8px;</span> /* 💡 画像とテキストの隙間 */<br>
}<br>
<span class="hl-blue">.btn-success::before</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">url("icon.svg");</span> /* 💡 画像を挿入 */<br>
}
</div>
</div>CSSコード表示
.icon-layout-wrapper {
background-color: #f8f9fa;
padding: 30px;
border-radius: 8px;
border: 1px solid #dee2e6;
}
.icon-caption {
font-size: 14px;
font-weight: bold;
margin-bottom: 30px;
color: #198754;
text-align: center;
}
.icon-demo-area {
display: flex;
justify-content: center;
gap: 40px;
background-color: #e9ecef;
padding: 40px;
border-radius: 8px;
border: 1px dashed #adb5bd;
margin-bottom: 20px;
}
.icon-box-wrapper {
display: flex;
flex-direction: column;
align-items: center;
}
.icon-label {
font-size: 13px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
text-align: center;
}
.icon-text {
font-weight: bold;
font-size: 16px;
}
/* ボタンの共通装飾 */
.icon-btn-fail, .icon-btn-success {
background-color: #fff;
border: 1px solid #ced4da;
padding: 10px 20px;
border-radius: 6px;
color: #dc3545;
}
/* =❌ 実践コード:ただ挿入しただけ= */
/* ※SVGをDataURI(Base64)で直接記述しています */
.icon-btn-fail::before {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="%23dc3545" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>');
margin-right: 8px;
}
/* =⭕️ 実践コード:Flexboxで位置調整= */
.icon-btn-success {
display: flex;
align-items: center;
gap: 8px;
}
.icon-btn-success::before {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="%23dc3545" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>');
/* display: blockなどを指定して高さを持たせる */
display: block;
height: 24px;
}
.icon-code-area {
background-color: #282c34;
color: #abb2bf;
padding: 20px;
border-radius: 6px;
font-family: monospace;
font-size: 13px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }Flexboxで利用するflexの使い方を詳しく知りたい人は「【CSS】flexの使い方:justify-content・align-items・gap」を一読ください。
画像のサイズが変えられない問題の解決策
「画像が大きすぎるからCSSでwidthやheightを指定したのに、画像のサイズが全く変わらない」という問題です。
疑似要素で画像のサイズをコントロールするには、content: url();は捨ててcontent: "";とした上でbackground-imageを使うことです。
疑似要素を空のブロック(display: inline-block;やblock;)にし、背景画像として画像を敷きbackground-size: contain;を指定します。
これにより、指定したwidthやheightに合わせて画像が伸縮するようになります。
⭕️ サイズを変えたいなら、content: url() ではなく背景画像(background)を使え!
❌ content: url() 使用
(width/heightが効かず巨大化)
⭕️ background-image 使用
(指定した24pxに縮小される)
.fail::before {
content: url(“huge-icon.png”);
width: 24px; /* 💡 効かない! */
height: 24px; /* 💡 効かない! */
}
/* ⭕️ contentを空にして、背景画像として表示・縮小させる */
.success::before {
content: “”; /* 💡 contentは空文字にする */
display: inline-block; /* 💡 幅と高さを持たせるために必須 */
width: 24px;
height: 24px;
background-image: url(“huge-icon.png”); /* 💡 背景として呼び出す */
background-size: contain; /* 💡 これで箱のサイズにピタッと収まる! */
}
HTMLコード表示
<div class="icon-layout-wrapper">
<p class="icon-caption">⭕️ サイズを変えたいなら、content: url() ではなく背景画像(background)を使え!</p>
<div class="icon-demo-area">
<!-- ❌ 失敗:content: url() でサイズを変えようとして失敗 -->
<div class="icon-box-wrapper">
<p class="icon-label">❌ content: url() 使用<br><small>(width/heightが効かず巨大化)</small></p>
<div class="icon-resize-fail">Error</div>
</div>
<!-- ⭕️ 成功:background-image と size: contain で自由にリサイズ -->
<div class="icon-box-wrapper">
<p class="icon-label" style="color:#0d6efd;">⭕️ background-image 使用<br><small>(指定した24pxに縮小される)</small></p>
<div class="icon-resize-success">Success</div>
</div>
</div>
<div class="icon-code-area">
/* ❌ url() で挿入した画像は、width/height では縮まない */<br>
<span class="hl-blue">.fail::before</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">url("huge-icon.png");</span><br>
<span class="hl-green">width:</span> <span class="hl-red">24px;</span> /* 💡 効かない! */<br>
<span class="hl-green">height:</span> <span class="hl-red">24px;</span> /* 💡 効かない! */<br>
}<br><br>
/* ⭕️ contentを空にして、背景画像として表示・縮小させる */<br>
<span class="hl-blue">.success::before</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">"";</span> /* 💡 contentは空文字にする */<br>
<span class="hl-green">display:</span> <span class="hl-red">inline-block;</span> /* 💡 幅と高さを持たせるために必須 */<br>
<span class="hl-green">width:</span> <span class="hl-red">24px;</span><br>
<span class="hl-green">height:</span> <span class="hl-red">24px;</span><br>
<span class="hl-green">background-image:</span> <span class="hl-red">url("huge-icon.png");</span> /* 💡 背景として呼び出す */<br>
<span class="hl-green">background-size:</span> <span class="hl-red">contain;</span> /* 💡 これで箱のサイズにピタッと収まる! */<br>
}
</div>
</div>CSSコード表示
.icon-resize-fail, .icon-resize-success {
display: flex;
align-items: center;
gap: 10px;
font-weight: bold;
background-color: #fff;
padding: 10px 20px;
border: 1px solid #ced4da;
border-radius: 6px;
}
/* =❌ 実践コード:リサイズ失敗(巨大なSVGを想定)= */
.icon-resize-fail::before {
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="%23dc3545"><path d="M12 2L2 22h20L12 2z"/></svg>');
width: 24px; /* 効かない */
height: 24px; /* 効かない */
}
/* =⭕️ 実践コード:背景画像でリサイズ成功= */
.icon-resize-success::before {
content: ""; /* 空にする */
display: inline-block;
width: 24px; /* ここでサイズ指定 */
height: 24px; /* ここでサイズ指定 */
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 24 24" fill="%230d6efd"><path d="M12 2L2 22h20L12 2z"/></svg>');
background-size: contain; /* サイズを箱に合わせる */
background-repeat: no-repeat;
background-position: center;
}background-imageの使い方を詳しく知りたい人は「【CSS】background-imageの使い方:サイズ・透過・レスポンシブ」を一読ください。
Font Awesomeなどのアイコンフォントと特殊文字
画像ファイルを用意しなくても、Font Awesomeなどのアイコンフォントや、特殊文字・エンティティを使えば、CSSだけで多彩なアイコンを表現できます。
これらのアイコンを呼び出すには、\f007のようなUnicodeをcontentの値として指定します。
Font Awesomeを疑似要素で表示させるには、「content(Unicode)、font-family(フォント名)、font-weight(太さ)の3点セットを記述すること」です。
無料版(Free)のSolidアイコンを使いたい場合は、font-weight: 900;を指定してください。ここが400(標準)などになっていると、アイコンは表示されません。
HTMLコード表示
<!-- 💡 必須:Font Awesomeの読み込み(実際のサイトではhead内に記述) -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<div class="icon-layout-wrapper">
<p class="icon-caption">⭕️ アイコンの文字化けを防ぐには、family と weight の「3点セット」が必須!</p>
<div class="icon-demo-area">
<!-- ❌ 失敗:font-weight の指定を忘れて文字化け(□) -->
<div class="icon-box-wrapper">
<p class="icon-label">❌ weight 指定忘れ<br><small>(四角い□が表示される)</small></p>
<div class="icon-fa-fail">User</div>
</div>
<!-- ⭕️ 成功:3点セットが揃い、正しく表示 -->
<div class="icon-box-wrapper">
<p class="icon-label" style="color:#0d6efd;">⭕️ 3点セット完備<br><small>(美しいアイコンが表示)</small></p>
<div class="icon-fa-success">User</div>
</div>
</div>
<div class="icon-code-area">
/* ❌ Unicodeとfont-familyを書いただけでは表示されない! */<br>
<span class="hl-blue">.fa-fail::before</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">"\f007";</span> /* 💡 ユーザーアイコンのUnicode */<br>
<span class="hl-green">font-family:</span> <span class="hl-red">"Font Awesome 6 Free";</span><br>
<span class="hl-comment">/* 🚨 font-weight が指定されていないため、化ける */</span><br>
}<br><br>
/* ⭕️ Solidアイコンを表示するには font-weight: 900; が絶対条件 */<br>
<span class="hl-blue">.fa-success::before</span> {<br>
<span class="hl-green">content:</span> <span class="hl-red">"\f007";</span><br>
<span class="hl-green">font-family:</span> <span class="hl-red">"Font Awesome 6 Free";</span><br>
<span class="hl-green">font-weight:</span> <span class="hl-red">900;</span> /* 💡 これが命!Solidスタイルの太さを指定する */<br>
}
</div>
</div>CSSコード表示
.icon-fa-fail, .icon-fa-success {
background-color: #fff;
border: 1px solid #ced4da;
padding: 10px 30px;
border-radius: 30px;
font-weight: bold;
color: #333;
display: flex;
align-items: center;
gap: 10px;
}
/* =❌ 実践コード:文字化けの再現= */
.icon-fa-fail::before {
content: "\f007";
font-family: "Font Awesome 6 Free";
/* font-weight をあえて指定しないことで文字化け(□)を引き起こす */
font-weight: 400;
color: #dc3545;
}
/* =⭕️ 実践コード:正しい表示= */
.icon-fa-success::before {
content: "\f007";
font-family: "Font Awesome 6 Free";
font-weight: 900; /* 💡 これが必須! */
color: #0d6efd;
}幅や高さを中身に合わせる:fit-content ・max-content
Webデザインにおいて、「ボタンの幅を中のテキストの長さに合わせたい」「表の列幅を中身に合わせて最適化したい」といった要望は発生します。
これまでコンテンツの幅に合わせるにはdisplay: inline-blockを使うなどの工夫が必要でしたが、モダンCSSでは要素のサイズを中身に合わせて自動調整するキーワードが用意されています。
ここでは、fit-contentによるコンテンツベースのサイズ指定方法と「なぜか効かない」原因と解決策を解説します。
fit-contentとmin/max-contentの違いwidthやheightでfit-contentが効かない原因
fit-contentとmin/max-contentの違い
要素の幅を中身のテキストなどに合わせて自動決定する値には、主に以下の3種類があります。
max-content
中身のテキストが長くても、改行せずに1行で表示し、最大の長さに要素の幅を合わせます。min-content
単語の切れ目など、改行できる箇所で可能な限り改行し、一番長い単語の幅に合わせます。fit-content
基本的にはmax-contentと同じようにテキストの幅に合わせて伸びますが、親要素の幅に到達すると、上限として改行されます。
また、div要素だけでなく、テーブルのセルの幅を調整したり、最近では入力フォームのサイズを文字数に合わせるfield-sizing: content;といった新しいプロパティも登場しています。
ボタンやラベルなど、「基本はテキストの長さに幅を合わせたい、ただし画面幅が狭い時は親の枠からはみ出さずに改行してほしい」という実務で多いケースでは、常にwidth: fit-content;を選択するのがよいです。
⭕️ widthに対する3つのキーワードの挙動の違い
min-content
(限界まで改行)
max-content
(1行を貫く)
fit-content
(基本は1行、親枠で改行)
.box-min {
width: min-content;
}
/* 💡 親の幅を無視して、絶対に改行せずにテキストを1行で表示し続ける幅になる */
.box-max {
width: max-content;
}
/* ⭕️ 基本はテキスト幅に合わせるが、親の幅を超えそうな時は改行する最も安全な指定 */
.box-fit {
width: fit-content;
}
HTMLコード表示
<div class="content-sizing-wrapper">
<p class="content-caption">⭕️ widthに対する3つのキーワードの挙動の違い</p>
<div class="content-demo-area">
<!-- 💡 min-content(最小幅:可能な限り改行する) -->
<div class="sizing-box-wrapper">
<p class="sizing-label">min-content<br><small>(限界まで改行)</small></p>
<div class="sizing-box is-min-content">
VeryLongWord And Short Words.
</div>
</div>
<!-- 💡 max-content(最大幅:絶対に改行しない) -->
<div class="sizing-box-wrapper">
<p class="sizing-label">max-content<br><small>(1行を貫く)</small></p>
<div class="sizing-box is-max-content">
VeryLongWord And Short Words.
</div>
</div>
<!-- 💡 fit-content(丁度いい幅:親の幅まで伸びて改行) -->
<div class="sizing-box-wrapper">
<p class="sizing-label" style="color:#0d6efd;">fit-content<br><small>(基本は1行、親枠で改行)</small></p>
<!-- デモのため親要素の幅を制限 -->
<div class="fit-parent-limit">
<div class="sizing-box is-fit-content">
VeryLongWord And Short Words.
</div>
</div>
</div>
</div>
<div class="content-code-area">
/* 💡 一番長い単語(VeryLongWord)の幅に合わせ、他は全て改行される */<br>
<span class="hl-blue">.box-min</span> {<br>
<span class="hl-green">width:</span> <span class="hl-red">min-content;</span><br>
}<br><br>
/* 💡 親の幅を無視して、絶対に改行せずにテキストを1行で表示し続ける幅になる */<br>
<span class="hl-blue">.box-max</span> {<br>
<span class="hl-green">width:</span> <span class="hl-red">max-content;</span><br>
}<br><br>
/* ⭕️ 基本はテキスト幅に合わせるが、親の幅を超えそうな時は改行する最も安全な指定 */<br>
<span class="hl-blue">.box-fit</span> {<br>
<span class="hl-green">width:</span> <span class="hl-red">fit-content;</span><br>
}
</div>
</div>CSSコード表示
.content-sizing-wrapper {
background-color: #f8f9fa;
padding: 30px;
border-radius: 8px;
border: 1px solid #dee2e6;
}
.content-caption {
font-size: 14px;
font-weight: bold;
margin-bottom: 30px;
color: #198754;
text-align: center;
}
.content-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
background-color: #e9ecef;
padding: 40px;
border-radius: 8px;
border: 1px dashed #adb5bd;
margin-bottom: 20px;
}
.sizing-box-wrapper {
display: flex;
flex-direction: column;
}
.sizing-label {
font-size: 13px;
font-weight: bold;
color: #333;
margin-bottom: 5px;
}
/* 共通のボックス形状 */
.sizing-box {
background-color: #0d6efd;
color: white;
padding: 10px;
border-radius: 4px;
font-weight: bold;
font-size: 14px;
/* はみ出しをわかりやすくする */
border: 2px solid #0a58ca;
}
/* =💡 実践コード:min-content= */
.is-min-content {
width: min-content;
background-color: #6c757d;
border-color: #495057;
}
/* =💡 実践コード:max-content= */
.is-max-content {
width: max-content;
background-color: #dc3545;
border-color: #b02a37;
}
/* =⭕️ 実践コード:fit-content= */
.fit-parent-limit {
width: 150px; /* 親要素の幅をあえて狭くする */
border: 1px dashed #6c757d;
padding: 5px;
}
.is-fit-content {
width: fit-content;
}
.content-code-area {
background-color: #282c34;
color: #abb2bf;
padding: 20px;
border-radius: 6px;
font-family: monospace;
font-size: 13px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }幅や高さの使い方を詳しく知りたい人は「【html&css】width(横幅)とheight(高さ)の指定とボックスモデル」を一読ください。
widthやheightでfit-contentが効かない原因
「ボタンの幅を文字に合わせようとwidth: fit-content;を指定したのに効かない!」「高さを中身に合わせようとしたら崩れた!」と悩むのは、多くの人が通る道です。
これには、親要素のレイアウトモデル(FlexboxやGrid)やプロパティ自体の初期値の仕様が深く関わっています。
Flexbox(display: flex;)の中でアイテムの幅に対してwidth: fit-content;が効かないと感じる場合、「親要素のalign-items(デフォルトはstretch)によって強制的に引き伸ばされていないか?」を真っ先に疑います。
また、絶対配置(position: absolute;)の要素を中央寄せしつつ幅を中身に合わせたい場合はwidth: fit-content;と併用してmargin: auto;を活用するのがレイアウト手法です。
⭕️ Flexboxの中で幅が広がってしまう場合は「align-items」を見直す!
❌ flex-direction: column の罠
(fit-contentを指定しても親の幅いっぱいになる)
⭕️ align-items: flex-start を追加
(文字の幅にピタッと収まる)
/* ❌ 親の align-items: stretch(初期値)に負ける */
.fail-btn {
width: fit-content; /* 💡 Flexboxの強制力で横いっぱいに伸びてしまう */
}
/* ⭕️ 親要素の align-items を修正し、強制引き伸ばしを解除する */
.success-parent {
display: flex;
flex-direction: column;
align-items: flex-start; /* 💡 ここが超重要!stretchを解除する */
}
.success-btn {
width: fit-content; /* 💡 これで無事に文字幅に収まる! */
}
HTMLコード表示
<div class="content-sizing-wrapper">
<p class="content-caption">⭕️ Flexboxの中で幅が広がってしまう場合は「align-items」を見直す!</p>
<div class="content-demo-area">
<!-- ❌ 失敗:Flexboxの特性で縦方向がstretch(伸びる)してしまう例の横幅版 -->
<div class="sizing-box-wrapper">
<p class="sizing-label">❌ flex-direction: column の罠<br><small>(fit-contentを指定しても親の幅いっぱいになる)</small></p>
<div class="fail-flex-container">
<!-- 💡 width: fit-content; を指定しているのに広がる -->
<div class="sizing-box is-fail-fit">
Button
</div>
</div>
</div>
<!-- ⭕️ 成功:align-items を指定して解決 -->
<div class="sizing-box-wrapper">
<p class="sizing-label" style="color:#0d6efd;">⭕️ align-items: flex-start を追加<br><small>(文字の幅にピタッと収まる)</small></p>
<div class="success-flex-container">
<!-- 💡 意図通りにコンテンツ幅に収まる -->
<div class="sizing-box is-success-fit">
Button
</div>
</div>
</div>
</div>
<div class="content-code-area">
/* 💡 前提:親が display: flex; で、縦並び(column)になっているとする */<br><br>
/* ❌ 親の align-items: stretch(初期値)に負ける */<br>
<span class="hl-blue">.fail-btn</span> {<br>
<span class="hl-green">width:</span> <span class="hl-red">fit-content;</span> /* 💡 Flexboxの強制力で横いっぱいに伸びてしまう */<br>
}<br><br>
/* ⭕️ 親要素の align-items を修正し、強制引き伸ばしを解除する */<br>
<span class="hl-blue">.success-parent</span> {<br>
<span class="hl-green">display:</span> <span class="hl-red">flex;</span><br>
<span class="hl-green">flex-direction:</span> <span class="hl-red">column;</span><br>
<span class="hl-green">align-items:</span> <span class="hl-red">flex-start;</span> /* 💡 ここが超重要!stretchを解除する */<br>
}<br>
<span class="hl-blue">.success-btn</span> {<br>
<span class="hl-green">width:</span> <span class="hl-red">fit-content;</span> /* 💡 これで無事に文字幅に収まる! */<br>
}
</div>
</div>CSSコード表示
/* =❌ 実践コード:fit-contentが効かないFlexbox親= */
.fail-flex-container {
display: flex;
flex-direction: column;
/* align-items のデフォルトは stretch なので、子要素の横幅が親いっぱいになる */
background-color: #fff;
border: 1px dashed #adb5bd;
padding: 10px;
border-radius: 4px;
}
.is-fail-fit {
width: fit-content;
/* 上記を指定しても、IE11など古い環境や特定のFlexboxバグで効かない場合と同等の見た目 */
/* デモとして、stretchが優先されている状態を再現するため幅を100%に上書き */
width: 100%;
background-color: #dc3545;
border-color: #b02a37;
text-align: center;
}
/* =⭕️ 実践コード:正しいFlexbox親= */
.success-flex-container {
display: flex;
flex-direction: column;
align-items: flex-start; /* 💡 stretch を解除して左寄せにする */
background-color: #fff;
border: 1px dashed #adb5bd;
padding: 10px;
border-radius: 4px;
}
.is-success-fit {
width: fit-content; /* 💡 無事にコンテンツ幅になる */
}レイアウトの配置と特殊な仕様
CSSで「コンテンツ」という言葉が使われるのは、文字や画像の挿入、幅の自動計算だけではありません。
FlexboxやGridを用いたレイアウトにおける配置プロパティ(justify-content)やボックスモデルの計算規則(content-box)、要素の存在そのものを操作する特殊なプロパティまで、多岐にわたります。
ここでは、要素を並べる配置テクニックとよくある「はみ出し」の解決策、contentがつく特殊なCSS仕様について解説します。
- Flexbox/Gridのコンテンツ配置と中央寄せ・はみ出し対策
display: contentsとcontent-box/visibility
Flexbox/Gridのコンテンツ配置と中央寄せ・はみ出し対策
justify-contentを一言で言えば、FlexboxやGridにおいて、アイテムを「主軸方向」にどう並べるかを決めるプロパティです。
要素を親枠の中央に配置するjustify-content: center;や要素間の余白を均等に散らして両端に揃えるjustify-content: space-between;、右寄せにするjustify-content: flex-end;など、レイアウト構築においてjustify-contentは頻繁に使用されます。
Flexboxで複数要素を並べる際は、「親要素にflex-wrap: wrap;(折り返し許可)を指定し、アイテム同士の隙間はgapプロパティで管理すること」です。
これにより、画面が狭くなった際にも要素が潰れたり枠からはみ出したりすることなく、自動的に複数行のレイアウト(折り返し)へと変化します。
⭕️ Flexboxの配置と、絶対にはみ出させない「折り返し(wrap)」の鉄則
1. 中央寄せ (center)
2. 両端揃え (space-between)
❌ wrap指定なし
(要素が多いと親枠を突き破る)
⭕️ flex-wrap: wrap 指定
(安全に改行される)
.center-layout {
display: flex;
justify-content: center;
}
/* ❌ 要素が多いと枠を突き破ってレイアウト崩壊 */
.no-wrap-layout {
display: flex;
/* flex-wrapのデフォルトは nowrap(折り返さない) */
}
/* ⭕️ flex-wrap と gap をセットで使う */
.wrap-layout {
display: flex;
flex-wrap: wrap; /* 💡 溢れたら自動で改行させる安全装置 */
gap: 10px; /* 💡 隙間は margin ではなく gap で一括管理 */
}
HTMLコード表示
<div class="jc-layout-wrapper">
<p class="jc-caption">⭕️ Flexboxの配置と、絶対にはみ出させない「折り返し(wrap)」の鉄則</p>
<div class="jc-demo-area">
<!-- 💡 代表的な配置のデモ -->
<div class="jc-demo-section">
<p class="jc-label">1. 中央寄せ (center)</p>
<div class="jc-flex-container is-center">
<div class="jc-box">A</div>
<div class="jc-box">B</div>
</div>
</div>
<div class="jc-demo-section">
<p class="jc-label">2. 両端揃え (space-between)</p>
<div class="jc-flex-container is-space-between">
<div class="jc-box">A</div>
<div class="jc-box">B</div>
<div class="jc-box">C</div>
</div>
</div>
<!-- ❌ 失敗:折り返しを忘れてはみ出す -->
<div class="jc-demo-section">
<p class="jc-label">❌ wrap指定なし<br><small>(要素が多いと親枠を突き破る)</small></p>
<div class="jc-flex-container is-no-wrap">
<div class="jc-box">Item 1</div>
<div class="jc-box">Item 2</div>
<div class="jc-box">Item 3</div>
<div class="jc-box">Item 4</div>
<div class="jc-box">Item 5</div>
</div>
</div>
<!-- ⭕️ 成功:flex-wrapで美しく折り返す -->
<div class="jc-demo-section">
<p class="jc-label" style="color:#0d6efd;">⭕️ flex-wrap: wrap 指定<br><small>(安全に改行される)</small></p>
<div class="jc-flex-container is-wrap">
<div class="jc-box">Item 1</div>
<div class="jc-box">Item 2</div>
<div class="jc-box">Item 3</div>
<div class="jc-box">Item 4</div>
<div class="jc-box">Item 5</div>
</div>
</div>
</div>
<div class="jc-code-area">
/* 💡 中央寄せ */<br>
<span class="hl-blue">.center-layout</span> {<br>
<span class="hl-green">display:</span> <span class="hl-red">flex;</span><br>
<span class="hl-green">justify-content:</span> <span class="hl-red">center;</span><br>
}<br><br>
/* ❌ 要素が多いと枠を突き破ってレイアウト崩壊 */<br>
<span class="hl-blue">.no-wrap-layout</span> {<br>
<span class="hl-green">display:</span> <span class="hl-red">flex;</span><br>
<span class="hl-comment">/* flex-wrapのデフォルトは nowrap(折り返さない) */</span><br>
}<br><br>
/* ⭕️ flex-wrap と gap をセットで使う */<br>
<span class="hl-blue">.wrap-layout</span> {<br>
<span class="hl-green">display:</span> <span class="hl-red">flex;</span><br>
<span class="hl-green">flex-wrap:</span> <span class="hl-red">wrap;</span> /* 💡 溢れたら自動で改行させる安全装置 */<br>
<span class="hl-green">gap:</span> <span class="hl-red">10px;</span> /* 💡 隙間は margin ではなく gap で一括管理 */<br>
}
</div>
</div>CSSコード表示
.jc-layout-wrapper {
background-color: #f8f9fa;
padding: 30px;
border-radius: 8px;
border: 1px solid #dee2e6;
}
.jc-caption {
font-size: 14px;
font-weight: bold;
margin-bottom: 30px;
color: #198754;
text-align: center;
}
.jc-demo-area {
display: flex;
flex-direction: column;
gap: 30px;
background-color: #e9ecef;
padding: 40px;
border-radius: 8px;
border: 1px dashed #adb5bd;
margin-bottom: 20px;
}
.jc-demo-section {
display: flex;
flex-direction: column;
}
.jc-label {
font-size: 13px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
/* Flexboxコンテナのベース */
.jc-flex-container {
background-color: #dee2e6;
border: 2px solid #adb5bd;
border-radius: 4px;
padding: 10px;
width: 100%;
max-width: 250px; /* はみ出しを再現するためあえて狭くする */
margin: 0 auto;
}
/* 共通のボックス形状 */
.jc-box {
background-color: #0d6efd;
color: white;
padding: 8px 15px;
border-radius: 4px;
font-weight: bold;
font-size: 14px;
flex-shrink: 0; /* 箱自体が縮むのを防ぐ(はみ出し再現のため) */
}
/* =💡 実践コード:center= */
.is-center {
display: flex;
justify-content: center;
gap: 10px;
}
/* =💡 実践コード:space-between= */
.is-space-between {
display: flex;
justify-content: space-between;
}
/* =❌ 実践コード:wrapなし(はみ出す)= */
.is-no-wrap {
display: flex;
/* flex-wrap: nowrap; がデフォルト */
gap: 10px;
}
/* =⭕️ 実践コード:wrapあり(折り返す)= */
.is-wrap {
display: flex;
flex-wrap: wrap; /* 💡 はみ出さずに下段へ折り返す */
gap: 10px;
}
/* =コード解説エリア= */
.jc-code-area {
background-color: #282c34;
color: #abb2bf;
padding: 20px;
border-radius: 6px;
font-family: monospace;
font-size: 13px;
line-height: 1.6;
border-left: 4px solid #0d6efd;
}
.hl-blue { color: #61afef; font-weight: bold; }
.hl-red { color: #e06c75; font-weight: bold; }
.hl-green { color: #98c379; font-weight: bold; }
.hl-comment { color: #6c757d; font-style: italic; }display: contentsとcontent-box/visibility
中〜上級者へのステップアップとして、contentの名を冠する特殊なCSSプロパティ群を紹介します。
display: contents
自身の要素の存在をレイアウト上から消し去り、「中の子要素」だけを親要素のレイアウトに直接参加させるプロパティです。
HTMLの構造を変えずにレイアウトを調整したい時に役立ちます。box-sizing: content-box
要素の幅(width)の計算方法の基準です。
デフォルトであるcontent-boxは中身の幅だけを指すため、paddingやborderを足すと全体のサイズが膨張してレイアウトが崩れます。content-visibility
最新のパフォーマンス最適化プロパティです。
値にautoを指定すると、画面外にある要素のレンダリングをスキップし、ページの読み込み速度を向上させます。
レイアウト崩れを防ぐには、「CSSの先頭(リセットCSS)で、全ての要素に対してbox-sizing: border-box;を指定すること」です。
これにより、paddingやborderを含めたサイズが指定したwidthとなるため、計算が狂わなくなります。
また、display: contents;は便利ですが、過去にスクリーンリーダーで要素が無視されるバグがあったため、主要な構造(<nav>やリストなど)には多用せず、限定的な装飾コンテナに対してのみ使用するのがよいです。
⭕️ widthがはみ出す原因!全要素に border-box を適用するのが現代の常識
❌ content-box(初期値)
(paddingの分だけ親枠を突き破って膨張する)
⭕️ border-box 指定
(paddingを含めて100%に収まる)
.box-bad {
width: 100%;
padding: 20px;
box-sizing: content-box; /* 💡 実際の幅は 100% + 40px になってはみ出す! */
}
/* ⭕️ CSSの先頭で全要素を border-box に設定する */
*, *::before, *::after {
box-sizing: border-box;
}
.box-good {
width: 100%; /* 💡 paddingを含めて親の幅にピタッと収まる! */
padding: 20px;
}
HTMLコード表示
<div class="jc-layout-wrapper">
<p class="jc-caption">⭕️ widthがはみ出す原因!全要素に border-box を適用するのが現代の常識</p>
<div class="jc-demo-area">
<!-- ❌ 失敗:デフォルトの content-box -->
<div class="jc-demo-section" style="width: 100%;">
<p class="jc-label">❌ content-box(初期値)<br><small>(paddingの分だけ親枠を突き破って膨張する)</small></p>
<div class="misc-parent-box">
<div class="misc-child-box is-content-box">
width: 100% + padding: 20px
</div>
</div>
</div>
<!-- ⭕️ 成功:border-box -->
<div class="jc-demo-section" style="width: 100%;">
<p class="jc-label" style="color:#0d6efd;">⭕️ border-box 指定<br><small>(paddingを含めて100%に収まる)</small></p>
<div class="misc-parent-box">
<div class="misc-child-box is-border-box">
width: 100% + padding: 20px
</div>
</div>
</div>
</div>
<div class="jc-code-area">
/* ❌ デフォルト設定のまま余白をつけると幅が狂う */<br>
<span class="hl-blue">.box-bad</span> {<br>
<span class="hl-green">width:</span> <span class="hl-red">100%;</span><br>
<span class="hl-green">padding:</span> <span class="hl-red">20px;</span><br>
<span class="hl-green">box-sizing:</span> <span class="hl-red">content-box;</span> /* 💡 実際の幅は 100% + 40px になってはみ出す! */<br>
}<br><br>
/* ⭕️ CSSの先頭で全要素を border-box に設定する */<br>
<span class="hl-blue">*, *::before, *::after</span> {<br>
<span class="hl-green">box-sizing:</span> <span class="hl-red">border-box;</span><br>
}<br>
<span class="hl-blue">.box-good</span> {<br>
<span class="hl-green">width:</span> <span class="hl-red">100%;</span> /* 💡 paddingを含めて親の幅にピタッと収まる! */<br>
<span class="hl-green">padding:</span> <span class="hl-red">20px;</span><br>
}
</div>
</div>CSSコード表示
.misc-parent-box {
background-color: #dee2e6;
border: 2px dashed #6c757d;
width: 100%;
max-width: 300px;
margin: 0 auto;
/* 親自身は崩れないようにしておく */
box-sizing: border-box;
}
/* 子要素のベース */
.misc-child-box {
background-color: #0d6efd;
color: white;
font-weight: bold;
text-align: center;
font-size: 12px;
}
/* =❌ 実践コード:content-box(膨張する)= */
.is-content-box {
width: 100%;
padding: 20px;
box-sizing: content-box; /* 初期値 */
background-color: #dc3545;
/* padding分が100%に加算されて右にはみ出す */
}
/* =⭕️ 実践コード:border-box(内側に収まる)= */
.is-border-box {
width: 100%;
padding: 20px;
box-sizing: border-box; /* 💡 必須設定! */
}まとめ
分かりやすいようにまとめを記載します。
contentプロパティは、疑似要素(::before/::after)にテキストや画像を表示させる必須のプロパティである。- テキストを挿入する場合は
" "または' 'で囲み、空白を入れたい場合は\00a0を用いる。 - 疑似要素内で改行するには、
content: "\A";とし、同時にwhite-space: pre;(またはpre-wrap)を指定する。 attr(属性名)を使うと、HTMLのカスタムデータ属性(data-*)等の値を取得して表示できる(クォーテーションは不要)。counter()と組み合わせることで、リストや見出しに自動で連番を振ることができる。contentの値にHTMLタグ(<span>など)を記述してもタグとして認識されず、そのまま文字列として出力される。url("画像のパス")で画像やSVGを挿入できるが、この方法で挿入した画像はCSSのwidthやheightでリサイズできない。- 画像のサイズを自由に調整したい場合は、
content: "";とし、背景画像(background-imageとbackground-size)として実装する。 - Font AwesomeなどのアイコンをUnicode(例:
\f007)で表示する際、文字化けを防ぐにはfont-familyと適切なfont-weight(Solidなら900)の指定が必須である。
よくある質問(FAQ)
::beforeや::afterを書いたのに画面に何も表示されないのはなぜですか?
ほぼ100%の原因が、contentプロパティの記述忘れです。
疑似要素を画面に存在させるには、たとえ文字を入れない(図形や背景だけを作る)場合であっても、content: "";(空の文字列)を指定する必要があります。
また、インライン要素(テキストなど)と同じ扱いになるため、幅や高さを持たせたい場合は合わせてdisplay: block;やinline-block;などを指定してください。
contentの中にHTMLタグ(<span>や<br>)を入れて色を変えたり改行したりできますか?
いいえ、できません。
contentプロパティの中にHTMLタグを記述しても、タグとしては認識されず「<br>」という単なる文字列として画面に出力されます。
一部だけ色を変えたい場合はHTML側に実際のタグを追加し、改行したい場合は改行コード(\A)を使用してください。
contentで入れたテキストの途中で改行するにはどうすればいいですか?
改行したい位置に\A(改行コード)を挿入し、疑似要素に対してwhite-space: pre;(またはpre-wrap)をセットで指定してください。
white-spaceの指定がないと、\Aを書いてもブラウザ上では半角スペースとして扱われてしまい改行されません。
content: url(…)で挿入した画像のサイズ(width/height)が変えられません。
仕様上、content: url()で直接呼び出した画像本体をCSSでリサイズすることはできません。
画像のサイズをコントロールしたい場合は、contentは""(空)にした上で、background-imageとして画像を読み込み、background-size: contain;などを使ってリサイズするのがWeb制作のルールです。
Font Awesomeのアイコンをcontentで入れたら、四角(□)に文字化けします。なぜですか?
Unicode(例: \f007)を指定しただけでは、ブラウザがどのフォントで描画すればいいか分からないため文字化けします。
Font Awesomeを疑似要素で正しく表示させるには、contentに加えてfont-family(フォント名)とfont-weight(太さ)の3点セットが必須です。
特に無料版(Free)のSolidアイコンを使う場合、font-weight: 900;の指定が漏れているだけで表示されなくなるため注意が必要です。

