快い図のキャプション

キャプション付きの犬の画像。

画像に続けてfigcaptionをそのまま普通に表示するといまいちなことが多いです。それでも英語ならイタリック体にするとかでなんとなくその文字列がfigure要素に係っているものだということが表現できるような気がしますが、日本語の斜体はいろいろアレなので使いたくないです(よね!)。そこで画像にキャプションを綺麗に重ねる方法を模索してみました。

Demo: Smooth Caption

まずは画像のHTMLです。

<figure>
  <a href="http://example.com/">
    <img src="http://example.com/images/logo.png">
  </a>
  <figcaption>Example.com's Logo</figcaption>
</figure>

このHTMLに対してどんなサイズの画像にも対応できるようにCSSを書いていきます。a要素には依存しませんが、入っていてもいなくても大丈夫なようにもします。

figure {
  display: inline-block;
  position: relative;
  line-height: 1;
  overflow: hidden;
}

まずはfigure要素をinline-blockにします。こうすることによって内包される画像に合わせてfigure要素のサイズが変化します。そしてpositionoverflowプロパティーで効率的にfigcaptionをレイアウトできるようにしておきます。line-heightプロパティーはなくてもうまくいくことがありますが、なるべく1にしておいたほうが良いでしょう。

figure img {
  vertical-align: text-bottom;
}

次に画像の行ボックスに対する位置決めを行います。デフォルト値であるbaselineだとfigure要素の下端に数ピクセルの隙間ができてしまいますが、text-bottomにすることによってその隙間を消すことができます。

最後にfigcaptionのデザインです。

figure figcaption {
  padding: 0 1em;
  position: absolute;
  right: 0;
  bottom: 0;
  width: 100%;
  line-height: 3;
  color: white;
  background-color: black;
  text-align: right;
  opacity: 0.75;
}

幅はwidthプロパティーで100%を指定するとfigure要素の幅一杯になります。つまり画像の幅と揃うことになりますね。paddingプロパティーで左右に余白を確保しているので、実際には飛び出してしまいますが、figure要素でoverflow: hiddenとなっているので問題ありません。高さはline-heightプロパティーでやると、高さと同時に縦方向のセンタリングも行えるのでお手軽でしょう。

テキストを右寄せにしているので、全体の位置はrightbottomプロパティーで右下に合わせます。overflowで隠しているのでわかりませんが、実際には左に少し飛び出しています。左寄せにする場合はleftを代わりに使いましょう。

色は普通に指定してopacityプロパティーで半透明にしていますが、このあたりは好みで良いでしょう。勿論背景画像を使っても大丈夫です。

これで最初にあげたスクリーンショットのような派手すぎないけど少しだけ凝ったキャプションになります。周囲のコンテンツとのマージンを工夫したりフォントや前景色を変更したりして、図のキャプションかそうでないかを判断できるようにするのが王道だと思いますが、フォントの自由さが足りない日本語のページではこういう方法もまぁ悪くないんじゃないかと思います。

やり過ぎると図が読み手に与えるイメージが揺らいでしまうので、キャプションが図よりも目立つような形にはするべきではないでしょう。図が主でキャプションが従になるように気をつけてデザインすると良いと思います。

おまけ

オンマウスでスルッとキャプションを隠す場合は位置をいじるよりもline-heightプロパティーをいじった方がアニメーションさせやすいと思います。

.test figcaption {
  overflow: hidden;
  transition-duration: 0.5s;
}

.test:hover figcaption {
  line-height: 0;
  transition-duration: 0.5s;
}

bottomいじる場合はキャプションの高さを知らなくちゃいけないのでちょっと面倒なので。まぁ吹っ飛ぶくらいの量を適当に指定するとかで逃げるという手もありますけどね。