Menu

CSS ::before と ::after 疑似要素の使い方

::before と ::after は、CSS だけで要素の最初と最後の子として生成コンテンツを挿入します。content プロパティ、空の content が必要な理由、配置のしかた、attr() を使ったツールチップ、カウンター、使えない要素を解説します。

このページのコードはエディタで実行できます - 編集してすぐに結果を確認できます。

::before と ::after の働き

::before は要素の 最初の子 として、::after は 最後の子 としてボックスを挿入します。ボックスの中身は content プロパティで決まります。HTML には何も追加されず、ブラウザが CSS から生成します。

HTML にあるのは 9 と Tests pass だけです。ドル記号、「/ month」のラベル、チェックマークはすべて CSS から来ています。上の例のように上書きしない限り、疑似要素は要素のスタイル (フォント、色) を継承します。

書き方

selector::before {
  content: "text";   /* required */
  /* any other styles */
}

selector::after {
  content: "";       /* empty string: a box with no text */
}
content の値結果
"text"文字列。改行には "\A" (white-space: pre と併用)、Unicode 文字には "\2192" (→) を使います
""空のボックス。図形や装飾に使います
attr(data-label)要素の属性の値
counter(step)CSS カウンターの値
open-quote / close-quote要素の言語に合った引用符
none または normal疑似要素なし (normal が初期値)

content は必須です。これがないと、ほかにいくつプロパティを指定しても ::before と ::after は作られません。

content: "" で装飾の図形を作る

content: "" にすると、疑似要素はサイズや色を指定できる空のボックスになります。初期状態ではインラインで、インラインのボックスは width と height を無視するので、display: block、inline-block、または position: absolute を指定します:

疑似要素を配置する

要素の上や周りに置く装飾には、疑似要素に position: absolute、要素そのものに position: relative を指定します。こうすると位置は要素を基準に測られます:

疑似クラス と組み合わせるときの順番に注意してください。状態が先、疑似要素が後で .link:hover::after と書きます。.link::after:hover ではありません。

attr() で属性を読む: ツールチップ

attr() は属性の値を content に取り込むので、1 つのルールで要素ごとに違うテキストを表示できます:

hover だけのツールチップは、キーボードやタッチで操作する人には見えません。重要な内容はページにテキストで書くか、要素に tabindex="0" を付けて :focus でも表示しましょう。

カウンターで番号を付ける

CSS カウンターと ::before を使えば、数字を書かずに番号を振れます:

ステップを追加したり削除したりすると、番号は自動で更新されます。

::before と ::after が使えない要素

疑似要素は要素の内側、つまりタグの間に挿入されます。そのための内側を持たない要素には表示できません:

  • <img>、<video>、<iframe> (置換要素)
  • <input>、<select>、<textarea> (フォームコントロール) と <br>

チェックボックスや壊れた画像に描画するブラウザもありますが、一貫していません。代わりに囲みの要素に疑似要素を付けます: <span class="field"><input></span> として .field::after をスタイルします。

よくある間違い

  • content がない。 何も表示されない原因として圧倒的に多いものです。content: "" を追加しましょう。
  • インラインの疑似要素にサイズを指定する。 display: block、inline-block、position: absolute を指定するまで、width と height は効きません。
  • 状態との順番を間違える。 a:hover::after は動きますが、a::after:hover は動きません。
  • 位置指定された親なしで absolute にする。 疑似要素がどこか遠くの祖先を基準に配置されます。要素に position: relative を追加しましょう。
  • 本当のコンテンツを CSS に書く。 content のテキストは選択もコピーもできません。情報は HTML に書きましょう。

よくある質問

CSS の ::before は何をしますか?

選択した要素の最初の子になる疑似要素を作り、content プロパティで指定したもので中身を埋めます。::after は同じことを最後の子として行います。どちらも HTML には存在しないので、アイコン、ラベル、装飾に便利です。

::before や ::after が表示されないのはなぜですか?

いちばん多い原因は content プロパティがないことです。これがないと疑似要素は生成されません。装飾用の空のボックスには content: "" を使います。ほかには、インラインのままの疑似要素に幅と高さを指定している (display: block か inline-block を指定する)、<img> や <input> のように疑似要素を持てない要素に付けている、といった原因があります。

:before と ::before の違いは何ですか?

動作に違いはありません。コロン 2 つの ::before は疑似要素を示す現在の書き方で、コロン 1 つの :before は CSS2 の古い書き方です。ブラウザは before、after、first-line、first-letter についてはまだ受け付けます。

img や input に ::before は使えますか?

確実には使えません。疑似要素は要素のコンテンツの内側に挿入されますが、<img> などの置換要素や <input> などのフォームコントロールには、そのためのコンテンツボックスがありません。要素を <span> や <div> で囲み、疑似要素はその囲みに付けましょう。

CSS の ::before の内容はスクリーンリーダーで読み上げられますか?

おおむね読み上げられます。content のテキストはふつうアクセシブルな名前に含まれますが、選択やコピーはできません。本当の情報は HTML に書き、疑似要素は装飾や小さな視覚的な手がかりに使いましょう。

Coddy programming languages illustration

Coddyでコードを学ぼう

始める