::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 に書き、疑似要素は装飾や小さな視覚的な手がかりに使いましょう。