WithCodeMedia-1-pc
previous arrowprevious arrow
next arrownext arrow

WithCodeMedia-1-sp
previous arrowprevious arrow
next arrownext arrow

【2026年版】CSS疑似要素 ::before/::afterの使い方|contentで装飾をコピペ実装

CSSの ::before::after は、HTMLを一切変えずに要素の前後に装飾を差し込める疑似要素です。見出しのデコレーション、下線エフェクト、吹き出しの三角、アイコン風の記号など、デザインの幅を大きく広げる機能として、現場のCSSで毎日使われています。

「contentプロパティが必要なのはわかるけど、どこに何を書けばいいの?」「positionを使う場面がいつもよくわからない」「思い通りに表示されない原因が掴めない」という声をよく聞きます。この記事では基本の書き方から実務で使えるコピペサンプルまで、順を追って丁寧に解説します。

完全なHTML+CSSのサンプルを複数掲載しているので、ブラウザで確認しながら読み進めてください。読み終わる頃には、疑似要素を自在に使いこなせるようになります。

先に、この記事の結論をまとめます。

  • ::before / ::aftercontent プロパティが必須。これがないと何も表示されない
  • 装飾を「浮かせて」配置したいときは position: absolute と親要素に position: relative をセットで使う
  • content: ""(空文字)にすれば純粋な装飾ボックスとして使える
  • 単一コロン(:before)と二重コロン(::before)の動作は同じだが、CSS3以降は二重コロンが正式表記
目次

::before と ::after の基本構文

疑似要素は「セレクター::疑似要素名 { プロパティ: 値; }」の形で書きます。::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 プロパティに指定できる値

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 属性値を表示する

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 を使って装飾を自在に配置する

疑似要素を「浮かせて」任意の位置に置きたい場合は、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>

吹き出しの三角(::after で三角形を作る)

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>

リストアイテムのアイコン代替(::before でチェック)

.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>

引用符デザイン(blockquote装飾)

.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>

単一コロン(:before)と二重コロン(::before)の違い

結論から言うと、動作は同じです。ただし書き方の意味が違います。

CSS2の時代は疑似クラス(:hover など)と疑似要素(:before など)を同じ単一コロンで書いていました。CSS3から疑似要素は二重コロン(::before)に変更され、疑似クラスと区別できるようになりました。

書き方CSS バージョン動作推奨
:beforeCSS2動く非推奨(後方互換のみ)
::beforeCSS3動く推奨

現代のブラウザは両方対応していますが、新規で書くコードは必ず ::before / ::after の二重コロン表記を使いましょう。過去のコードを読むときに :before が出てきても怖がらなくて大丈夫です。

よくある失敗(表示されない原因と解決策)

疑似要素が意図通りに表示されないとき、原因はほぼ決まっています。チェックリストとして使ってください。

原因1: content プロパティがない

最も多い原因です。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;
}

原因2: 親要素に position: relative がない

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;
}

原因3: display が inline のままでサイズが効かない

疑似要素のデフォルトは 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;
}

原因4: replaced element(img・input)に使おうとしている

imginputbrhr などの置換要素(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;
}

早見表:::before と ::after の主なプロパティ

プロパティよく使う値用途
content"" / "文字列" / attr(data-*)疑似要素の生成(必須)
displayblock / inline-block / flexボックスモデルを有効化
positionabsolute / relative任意の位置へ配置
top / right / bottom / leftpx / % / em絶対配置の座標指定
width / heightpx / % / vw疑似要素のサイズ指定
background色 / グラデーション装飾の色や背景
bordersolid transparent三角形の生成
transformtranslateX(-50%)センタリングや回転
transitionall 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>

よくある質問(FAQ)

Q1. ::before と ::after のどちらを使えばいいの?

視覚的な装飾を「要素の前(左・上)」に置きたいなら ::before、「要素の後(右・下)」に置きたいなら ::after を使います。ただし position: absolute で配置する場合はどちらを使っても top/left/right/bottom で任意の位置に置けるので、その場合はどちらでも構いません。慣習として、装飾1つ目を ::before、2つ目を ::after に割り当てることが多いです。

Q2. 疑似要素は何個まで使えますか?

1つのセレクターに対して ::before::after の合計2つまでです。3つ以上の装飾が必要な場合は、子要素を使うか、親・子・孫それぞれに疑似要素を割り当てて対応します。

Q3. 疑似要素のスタイルは JavaScript で変更できますか?

JavaScriptから直接は変更できません。疑似要素はDOMに存在しないためです。対応方法は2つあります。1つ目は親要素にクラスを付け替え、そのクラスに対応した疑似要素スタイルをCSSで定義する方法。2つ目は CSS カスタムプロパティ(変数)を JavaScript で変更し、疑似要素の content や色で参照する方法です。

Q4. content に改行を入れることはできますか?

content プロパティ内では \A が改行コードに対応しています。ただし white-space: pre を合わせて指定しないと改行が反映されません。また視覚的な改行より display: block で分割するほうがシンプルに管理できます。

Q5. スクリーンリーダーは疑似要素のテキストを読み上げますか?

ブラウザ・スクリーンリーダーの組み合わせによって異なりますが、多くの環境で content に指定した文字列は読み上げられます。装飾目的の記号(「※」「→」など)が読み上げられると意味が変わる場合があるので、装飾専用の疑似要素には content: ""(空文字)を使うか、aria-hidden="true" を親要素に付ける方法を検討してください。

関連記事

CSS・Webデザイン実装の総まとめ

CSSの実装テクニックを「レイアウト・装飾・アニメーション・基礎・トラブル解決」の目的別に探せる総まとめページを用意しています。実装で迷ったときの索引としてどうぞ。

WithCodeを体験できる初級コース公開中!

WithCodeを体験できる初級コース公開中!

初級コース(¥49,800)が完全無料に!

  • 期間:1週間
  • 学習内容:
    ロードマップ/基礎知識/環境構築/HTML/CSS/LP・ポートフォリオ作成
    正しい学習方法で「確かな成長」を実感できるカリキュラム。

副業・フリーランスが主流になっている今こそ、自らのスキルで稼げる人材を目指してみませんか?

未経験でも心配することはありません。初級コースを受講される方の大多数はプログラミング未経験です。まずは無料カウンセリングで、悩みや不安をお聞かせください!

この記事を書いた人

WithCodeでWeb制作を習得後、フリーランスエンジニアとして活動。HTML/CSS・JavaScript・WordPress案件を中心に年間20件以上の制作実績を持つ。「難しい技術をわかりやすく」をモットーに、初心者〜中級者向けの技術記事を執筆。副業・フリーランス独立を目指す方に向けた情報発信に注力している。

– service –WithGroupの運営サービス

  • WithCode
    - ウィズコード -

    スクール

    「未経験」から
    現場で通用する
    スキルを身に付けよう!

    詳細はこちら
  • WithFree
    - ウィズフリ -

    実案件サポート

    制作会社のサポート下で
    実務経験を積んでいこう!

    詳細はこちら

公式サイト より
今すぐ
無料カウンセリング
予約!

目次