置換要素(img
など)に対する :before
, :after
疑似要素の指定について
CSSのセレクターのひとつ :before
, :after
疑似要素では、content
プロパティを組み合わせて要素の内容の前後にコンテントを挿入することができます。
たとえばこんな記述をすることによって、新着であることを分かりやすく表現できます。
.new:before {
content: "New!";
color: #e00;
background: #fff;
}
- IE7以前は
:before
,:after
疑似要素に対応していません。
しかし、img
要素やobject
要素などの置換要素(Replaced element)[1]に指定する場合の動作については、仕様が何度か変わったこともあり、ブラウザによって挙動が異なります。たとえばimg
要素にtitle
属性を設定してその値を画面表示したい場合、
img:after {
content: attr(title);
}
と書けば実現できそうですが、ほとんどのブラウザでは表示されず、また仕様的にもその挙動は正しいものとなります。
まず、CSSの仕様を再確認してみます。
CSS2(1998年勧告)の場合
:before
, :after
疑似要素は1998年に勧告されたCSS2で追加されたものですが、当初の仕様書にはimg
要素に指定する例が載っていました。
The next rule inserts the text of the HTML "alt" attribute before the image. If the image is not displayed, the reader will still see the "alt" text.
IMG:before { content: attr(alt) }

例示の記述をした場合、画像が表示されないときはalt
属性値が表示されるようです。
CSS2.1(2011年勧告)の場合
ところが、先のimg
要素の記述例はCSS2.1で削除され、h1
要素の例に置き換えられてしまいました。代わりに、「12.1 The :before and :after pseudo-elements」にこんな注釈が追加されています。
Note. This specification does not fully define the interaction of :before and :after with replaced elements (such as IMG in HTML). This will be defined in more detail in a future specification.

置換要素については、CSS2.1ではその作用を定義しないという扱いのようです(将来的に定義されるかもしれないという含みを残しつつ)。
CSS3の場合
CSS3はモジュール化が行われていますが、content
プロパティはCSS3 Generated and Replaced Content Moduleで定義されており、現在の最新バージョンである2003年5月14日版は Working Draft(草案)の状態にあります。
置換要素に関する記述は「12. Replaced content」に記述されています。
If the computed value of the part of the 'content' property that ends up being used is a single URI, then the element or pseudo-element is a replaced element. The box model defines different rules for the layout of replaced elements than normal elements. Replaced elements do not have '::before' and '::after' pseudo-elements; the 'content' property in the case of replaced content replaces the entire contents of the element's box.
To insert text around replaced content, '::outside::before' and '::outside::after' may be used.

置換要素の場合は::outside
疑似要素を使えと言うことですね。ただ、主要ブラウザの最新版(Firefox13, Google Chrome19, IE9, Opera12, Safari5.1)はいずれも未対応なので、現段階ではHTML構造を変えるか、JavaScriptで制御するしかなさそうです。
ブラウザの挙動を見る
では、実際のブラウザはどんな挙動をするのか、次のコードでテストしてみました。
<!DOCTYPE html>
<html lang="ja">
<head>
<title>img:afterでcontentを生成してみる</title>
<style>
img:after {
content: attr(title);
color: #e00;
background: #fff;
}
</style>
</head>
<body>
<p><img src="img01.png" alt="画像1" title="画像1のタイトル" /></p>
<p><img src="img02.png" alt="画像2" title="画像2のタイトル" /></p>
</body>
</html>
img
要素に対して、:after
疑似要素でtitle
属性値を表示するよう指定しています(区別できるよう色も変えています)。またimg
要素は2つありますが、 img02.png は意図的に用意しておらず 404 となります。
結果は次の3パターンでした。
:after
疑似要素で生成した内容は表示されない。(Google Chrome19, IE8〜9, Opera11.6以降, Safari5.1)- 画像が存在しない場合(img02.png)のみ、
:after
疑似要素で生成した内容が表示される。(Firefox13) :after
疑似要素で生成した内容は表示される。(Opera11.5以前)
Operaは少し前まで、画像の表示可否に関わらず :before
, :after
疑似要素の生成内容を表示するというおかしな動作でしたが、2011年12月にリリースされた 11.6 で修正されています。
FirefoxはCSS2の記述 If the image is not displayed, the reader will still see the "alt" text.
に従ったものですね。CSS3的にはこの動作は正しくないので[2]、いずれ他のブラウザに合わせられるのではないかと思います。
脚注
-
1.
置換要素(Replaced element)の定義は、CSS2.1仕様書の3.1 Definitions
に書かれています。 ↩ 戻る
-
2.
現段階では草案なので、仕様が変わる可能性もありますが。 ↩ 戻る