



WithCodeMedia-1-pc
WithCodeMedia-2-pc
WithCodeMedia-3-pc
WithCodeMedia-4-pc




WithCodeMedia-1-sp
WithCodeMedia-2-sp
WithCodeMedia-3-sp
WithCodeMedia-4-sp









CSSの ::before と ::after は、HTMLを一切変えずに要素の前後に装飾を差し込める疑似要素です。見出しのデコレーション、下線エフェクト、吹き出しの三角、アイコン風の記号など、デザインの幅を大きく広げる機能として、現場のCSSで毎日使われています。
「contentプロパティが必要なのはわかるけど、どこに何を書けばいいの?」「positionを使う場面がいつもよくわからない」「思い通りに表示されない原因が掴めない」という声をよく聞きます。この記事では基本の書き方から実務で使えるコピペサンプルまで、順を追って丁寧に解説します。
完全なHTML+CSSのサンプルを複数掲載しているので、ブラウザで確認しながら読み進めてください。読み終わる頃には、疑似要素を自在に使いこなせるようになります。
先に、この記事の結論をまとめます。
::before / ::after は content プロパティが必須。これがないと何も表示されないposition: absolute と親要素に position: relative をセットで使うcontent: ""(空文字)にすれば純粋な装飾ボックスとして使える:before)と二重コロン(::before)の動作は同じだが、CSS3以降は二重コロンが正式表記疑似要素は「セレクター::疑似要素名 { プロパティ: 値; }」の形で書きます。::before は選択した要素の内容の直前、::after は直後に仮想的な要素を生成します。実際のDOMには追加されず、CSSだけで制御できるのが大きな特徴です。
最低限必要なプロパティは content だけです。これを書き忘れると疑似要素は生成されません。
/* ::before の基本 */
.element::before {
content: "ここが before";
}
/* ::after の基本 */
.element::after {
content: "ここが after";
}
/* displayのデフォルトはinline */
/* ボックスモデルを使うならdisplay: blockかinline-blockを指定 */
.element::before {
content: "";
display: block;
width: 40px;
height: 4px;
background: #d16176;
}実際のHTMLに当てはめて確認してみましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>疑似要素の基本</title>
<style>
.label::before {
content: "【";
color: #d16176;
font-weight: bold;
}
.label::after {
content: "】";
color: #d16176;
font-weight: bold;
}
</style>
</head>
<body>
<p class="label">重要なお知らせ</p>
</body>
</html>表示結果は「【重要なお知らせ】」になります。HTMLのテキストは「重要なお知らせ」だけですが、CSSが前後に括弧を追加しています。これが疑似要素の基本的な働きです。
content には文字列・空文字・attr()など複数の種類の値を指定できます。それぞれの用途を整理しましょう。
シングルクォートまたはダブルクォートで囲んだ文字列をそのまま表示します。絵文字や特殊記号も使えます。
/* 文字列 */
.note::before {
content: "※ ";
}
/* 記号 */
.arrow::after {
content: " →";
}
/* 絵文字 */
.check::before {
content: "✔ ";
color: #4CAF50;
}
/* Unicodeエスケープ(チェックマーク) */
.check2::before {
content: "¹3 ";
color: #4CAF50;
}content: "" にすると、テキストなしの純粋なボックスを生成できます。下線・オーバーレイ・三角など、形状を作る装飾でよく使います。
/* 下線装飾 */
.underline-deco {
position: relative;
display: inline-block;
}
.underline-deco::after {
content: "";
position: absolute;
bottom: -4px;
left: 0;
width: 100%;
height: 3px;
background: #d16176;
border-radius: 2px;
}attr(属性名) を使うと、HTML要素の属性値をcontent内で使えます。ツールチップの代替や、リンクURLの表示などに活用されます。
/* data属性をツールチップ代わりに表示 */
.tooltip {
position: relative;
cursor: pointer;
}
.tooltip::after {
content: attr(data-tip);
position: absolute;
bottom: 100%;
left: 50%;
transform: translateX(-50%);
background: #333;
color: #fff;
padding: 4px 10px;
border-radius: 4px;
white-space: nowrap;
font-size: 12px;
opacity: 0;
transition: opacity 0.2s;
}
.tooltip:hover::after {
opacity: 1;
}<span class="tooltip" data-tip="これがツールチップです">ホバーしてみて</span>疑似要素を「浮かせて」任意の位置に置きたい場合は、position: absolute を疑似要素に設定し、親要素に position: relative を付けます。これは頻出パターンなので必ず覚えてください。
.heading-bar {
position: relative;
padding-left: 16px;
font-size: 20px;
font-weight: bold;
color: #51322b;
}
.heading-bar::before {
content: "";
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 5px;
background: #d16176;
border-radius: 3px;
}<h2 class="heading-bar">セクションタイトル</h2>CSSの border を使った三角形は ::before / ::after の代表的な活用例です。border 3辺を transparent にし、1辺だけ色を付けると三角形になります。
.balloon {
position: relative;
background: #EFBDB7;
border-radius: 8px;
padding: 12px 16px;
display: inline-block;
max-width: 280px;
color: #51322b;
font-size: 14px;
}
/* 下向き三角 */
.balloon::after {
content: "";
position: absolute;
bottom: -12px;
left: 20px;
border: 6px solid transparent;
border-top-color: #EFBDB7;
}<div class="balloon">こんにちは!疑似要素で吹き出しを作りました。</div>ナビゲーションリンクのホバー時に下線が伸びるエフェクトも、疑似要素と transition を組み合わせると実現できます。
.hover-line {
position: relative;
display: inline-block;
text-decoration: none;
color: #51322b;
font-weight: bold;
padding-bottom: 4px;
}
.hover-line::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 0;
height: 2px;
background: #d16176;
transition: width 0.3s ease;
}
.hover-line:hover::after {
width: 100%;
}<a href="#" class="hover-line">ホバーすると下線が伸びます</a>実務でそのまま使えるデザインパターンをまとめます。すべてコピペで動きます。
.line-title {
display: flex;
align-items: center;
gap: 12px;
font-size: 22px;
font-weight: bold;
color: #51322b;
}
.line-title::before,
.line-title::after {
content: "";
flex: 1;
height: 2px;
background: #d16176;
}
<h2 class="line-title">タイトル</h2>.icon-list {
list-style: none;
padding-left: 0;
}
.icon-list li {
position: relative;
padding-left: 28px;
margin-bottom: 8px;
color: #51322b;
font-size: 15px;
line-height: 1.6;
}
.icon-list li::before {
content: "✔";
position: absolute;
left: 0;
top: 0;
color: #d16176;
font-weight: bold;
}<ul class="icon-list">
<li>HTMLを変えずに装飾できる</li>
<li>CSSだけで三角形が作れる</li>
<li>attr()でデータ属性を表示できる</li>
</ul>.badge-heading {
position: relative;
padding-top: 32px;
font-size: 20px;
font-weight: bold;
color: #51322b;
}
.badge-heading::before {
content: "NEW";
position: absolute;
top: 0;
left: 0;
background: #d16176;
color: #fff;
font-size: 11px;
font-weight: bold;
padding: 2px 8px;
border-radius: 4px;
letter-spacing: 0.05em;
}<h3 class="badge-heading">最新のお知らせ</h3>.quote-block {
position: relative;
background: #fdf5f5;
border-radius: 8px;
padding: 24px 24px 24px 56px;
color: #51322b;
font-size: 15px;
line-height: 1.8;
}
.quote-block::before {
content: "C";
position: absolute;
left: 12px;
top: 8px;
font-size: 64px;
color: #EFBDB7;
line-height: 1;
font-family: Georgia, serif;
}<blockquote class="quote-block">
疑似要素を使いこなすと、HTMLをシンプルに保ちながら豊かな表現が可能になります。
</blockquote>結論から言うと、動作は同じです。ただし書き方の意味が違います。
CSS2の時代は疑似クラス(:hover など)と疑似要素(:before など)を同じ単一コロンで書いていました。CSS3から疑似要素は二重コロン(::before)に変更され、疑似クラスと区別できるようになりました。
| 書き方 | CSS バージョン | 動作 | 推奨 |
|---|---|---|---|
:before | CSS2 | 動く | 非推奨(後方互換のみ) |
::before | CSS3 | 動く | 推奨 |
現代のブラウザは両方対応していますが、新規で書くコードは必ず ::before / ::after の二重コロン表記を使いましょう。過去のコードを読むときに :before が出てきても怖がらなくて大丈夫です。
疑似要素が意図通りに表示されないとき、原因はほぼ決まっています。チェックリストとして使ってください。
最も多い原因です。content を省略すると疑似要素そのものが生成されません。空文字でも必ず書く必要があります。
/* NG: content がない */
.box::before {
display: block;
width: 20px;
height: 20px;
background: red;
}
/* OK: content: "" を必ず入れる */
.box::before {
content: "";
display: block;
width: 20px;
height: 20px;
background: red;
}position: absolute を使った疑似要素は、一番近い position が設定された祖先要素を基準に配置されます。親要素に position: relative を忘れると、意図しない場所に表示されます。
/* NG: 親にpositionがない */
.parent { }
.parent::before {
content: "";
position: absolute;
top: 0; left: 0;
}
/* OK: 親にposition: relativeを追加 */
.parent {
position: relative;
}
.parent::before {
content: "";
position: absolute;
top: 0; left: 0;
}疑似要素のデフォルトは display: inline です。width / height を指定したい場合は display: block または display: inline-block に変更する必要があります。
/* NG: デフォルトのinlineのままサイズを指定 */
.element::before {
content: "";
width: 100px; /* 効かない */
height: 4px; /* 効かない */
}
/* OK: display を変更する */
.element::before {
content: "";
display: block;
width: 100px;
height: 4px;
}img・input・br・hr などの置換要素(replaced element)には疑似要素を使えません。これらはコンテンツが外部リソースで決まるため、CSSで前後に挿入することができません。
/* NG: imgには使えない */
img::before {
content: "アイコン";
}
/* OK: imgをdivで包んでそこに使う */
.img-wrap {
position: relative;
display: inline-block;
}
.img-wrap::before {
content: "NEW";
position: absolute;
top: 8px;
left: 8px;
background: #d16176;
color: #fff;
padding: 2px 6px;
font-size: 11px;
border-radius: 4px;
}| プロパティ | よく使う値 | 用途 |
|---|---|---|
content | "" / "文字列" / attr(data-*) | 疑似要素の生成(必須) |
display | block / inline-block / flex | ボックスモデルを有効化 |
position | absolute / relative | 任意の位置へ配置 |
top / right / bottom / left | px / % / em | 絶対配置の座標指定 |
width / height | px / % / vw | 疑似要素のサイズ指定 |
background | 色 / グラデーション | 装飾の色や背景 |
border | solid transparent | 三角形の生成 |
transform | translateX(-50%) 等 | センタリングや回転 |
transition | all 0.3s ease | アニメーション |
z-index | 整数値 | 重なり順の制御 |
ここまでの技術を組み合わせた実践サンプルです。カードの左上に斜めのリボン装飾を付けます。
.card {
position: relative;
background: #fff;
border: 1px solid #EFBDB7;
border-radius: 12px;
padding: 24px;
max-width: 320px;
overflow: hidden;
box-shadow: 0 4px 12px rgba(81,50,43,0.08);
}
/* 左上コーナーリボン */
.card::before {
content: "PICK UP";
position: absolute;
top: 18px;
left: -28px;
background: #d16176;
color: #fff;
font-size: 10px;
font-weight: bold;
letter-spacing: 0.08em;
padding: 4px 32px;
transform: rotate(-45deg);
}
/* カード下部のアクセントライン */
.card::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 4px;
background: linear-gradient(90deg, #d16176, #EFBDB7);
}<div class="card">
<h3 style="margin-top:0;color:#51322b;">おすすめ記事</h3>
<p style="color:#51322b;font-size:14px;line-height:1.7;">
疑似要素を使えば、HTMLを汚さずにリッチなデザインが実現できます。
</p>
</div>手順を説明する際に使えるステップリストです。counter() と疑似要素を組み合わせて、自動採番の番号バッジを作ります。
.step-list {
list-style: none;
padding: 0;
counter-reset: step-counter;
}
.step-list li {
position: relative;
padding: 12px 12px 12px 56px;
margin-bottom: 12px;
background: #fdf5f5;
border-radius: 8px;
color: #51322b;
font-size: 15px;
line-height: 1.6;
counter-increment: step-counter;
}
.step-list li::before {
content: counter(step-counter);
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 30px;
background: #d16176;
color: #fff;
font-weight: bold;
font-size: 14px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}<ol class="step-list">
<li>CSSファイルに疑似要素セレクターを書く</li>
<li>content プロパティを必ず指定する</li>
<li>position が必要な場合は親要素に relative を付ける</li>
<li>display を block か inline-block に変えてサイズを効かせる</li>
</ol>視覚的な装飾を「要素の前(左・上)」に置きたいなら ::before、「要素の後(右・下)」に置きたいなら ::after を使います。ただし position: absolute で配置する場合はどちらを使っても top/left/right/bottom で任意の位置に置けるので、その場合はどちらでも構いません。慣習として、装飾1つ目を ::before、2つ目を ::after に割り当てることが多いです。
1つのセレクターに対して ::before と ::after の合計2つまでです。3つ以上の装飾が必要な場合は、子要素を使うか、親・子・孫それぞれに疑似要素を割り当てて対応します。
JavaScriptから直接は変更できません。疑似要素はDOMに存在しないためです。対応方法は2つあります。1つ目は親要素にクラスを付け替え、そのクラスに対応した疑似要素スタイルをCSSで定義する方法。2つ目は CSS カスタムプロパティ(変数)を JavaScript で変更し、疑似要素の content や色で参照する方法です。
content プロパティ内では \A が改行コードに対応しています。ただし white-space: pre を合わせて指定しないと改行が反映されません。また視覚的な改行より display: block で分割するほうがシンプルに管理できます。
ブラウザ・スクリーンリーダーの組み合わせによって異なりますが、多くの環境で content に指定した文字列は読み上げられます。装飾目的の記号(「※」「→」など)が読み上げられると意味が変わる場合があるので、装飾専用の疑似要素には content: ""(空文字)を使うか、aria-hidden="true" を親要素に付ける方法を検討してください。
CSSの実装テクニックを「レイアウト・装飾・アニメーション・基礎・トラブル解決」の目的別に探せる総まとめページを用意しています。実装で迷ったときの索引としてどうぞ。

副業・フリーランスが主流になっている今こそ、自らのスキルで稼げる人材を目指してみませんか?
未経験でも心配することはありません。初級コースを受講される方の大多数はプログラミング未経験です。まずは無料カウンセリングで、悩みや不安をお聞かせください!
WithCodeでWeb制作を習得後、フリーランスエンジニアとして活動。HTML/CSS・JavaScript・WordPress案件を中心に年間20件以上の制作実績を持つ。「難しい技術をわかりやすく」をモットーに、初心者〜中級者向けの技術記事を執筆。副業・フリーランス独立を目指す方に向けた情報発信に注力している。
公式サイト より
今すぐ
無料カウンセリング
を予約!