この記事は、http://css-tricks.com/ の Chris Coyier の許可を得て、翻訳しています。一部変更して翻訳している部分もある場合がります。オリジナルの記事はここよりご覧いただけます。

先日、とある方にこのテクニックに関して質問されたのですが、その時の私の反応は「チュートリアルとして記事にするにはあまりに平凡過ぎるのではないか」というものでした。けれどもそれからしばらく考えてみて、なかなか興味深い点も幾つかあることですし、みなさんに興味を持っていただける内容なのではないかと思うようになったのでこちらに取り上げることに致しました。

今回のアイデアは、ただ単にテキストを画像の上にオーバーレイ(重ねて表示させること)させるだけのことなのですが、左寄せのブロックがきちんとテキスト全体を充分な余白で囲んでいることに注目してください。こちらのスクリーンショットのサンプルをご覧ください:

textoverimageexample CSSを使ってイメージキャプションを入れる

スキーマ

scematics CSSを使ってイメージキャプションを入れる

HTML

<div class="image">

      <img src="images/3754004820_91a5c238a0.jpg" alt="" />

      <h2>A Movie in the Park:<br />Kung Fu Panda</h2>

</div>

 
画像を背景画像としてDIVタグの中に記述してしまえば簡単でしょう。けれどもここでは画像はコンテンツとして扱われており、HTMLにも属しています。そしてDIVタグは絶対位置指定用の外枠として使われています。

CSS

.image {
   position: relative;
   width: 100%; /* for IE 6 */
}

h2 {
   position: absolute;
   top: 200px;
   left: 0;
   width: 100%;
}

このように記述すると、テキストをいい感じで画像の上に重ねて表示してくれますが、テキストを取り囲む黒の半透明の部分の表示までは成功していません。h2タグはブロックレベル要素なので、ここではスタイル設定用としては役に立ちません。事前に幅が設定されていないインライン要素が必要になってきます。
なので、h2タグの内側にspanタグを追加しましょう:

<h2><span>A Movie in the Park:<br />Kung Fu Panda</span></h2>

 
spanタグを使っての、テキストと背景スタイル設定方法:

h2 span {
   color: white;
   font: bold 24px/45px Helvetica, Sans-Serif;
   letter-spacing: -1px;
   background: rgb(0, 0, 0); /* fallback color */
   background: rgba(0, 0, 0, 0.7);
   padding: 10px;
}

問題点

textoverimage problem CSSを使ってイメージキャプションを入れる

このままだとテキストを改行すると同時にブロック自体も改行されてしまい、1行目の最後の文字の右側と2行目の最初の文字の左側の余白が確保されません。パディングの意味が無いのです。
これを解決するためには、<br />タグ前後にspanを追加して余白を確保する必要があります。

<h2><span>A Movie in the Park:<span class='spacer'></span><br /><span class='spacer'></span>Kung Fu Panda</span></h2>

追加したspanにもCSSでスタイル設定して、パディングを加えてあげます:

h2 span.spacer {
   padding:0 5px;
}

セマンティック的に見ると・・・

今までのコーディングでデザイン的には完成しましたが、随分と細かい余計なHTML要素が増えてしまいました。ハッキリ言えばspanタグですね。jQueryを使えばこれを簡単に解決することが出来ます。単純にHTML文からspanタグを削除して、下記のjQueryを適用させれば完璧です:

$(function() {

    $("h2")
        .wrapInner("<span>")

    $("h2 br")
        .before("<span class='spacer'>")
        .after("<span class='spacer'>");

});