この記事は、Frontrend Conferenceのセッション「Inline layout」でお話させていただいた内容を基に、連載記事(全4回)として書き起こしたものです。今回は第2回目です。
なぜ画像の下部にスペースができてしまうのか?
今回の記事では、vertical-align
について解説していきます。前回は、行のレイアウトが、font-size
とline-height
によりどう変わるのかを見てきました。この行の中で、要素を縦位置のどこに配置するかを決定するのがvertical-align
です。これを理解すると、前回の疑問、「なぜ画像の下部にスペースができてしまうのか」が分かります。
行の中にdisplay
がinline
であるimg要素が登場したときのことを考えていきましょう。このときのimg要素は、そのvertical-align
の値により、配置される場所が異なります。順に見ていきます。
top, bottom
まずはtop
、bottom
の場合です。
top
の場合は、行の上端であるbefore-edgeに画像の上端が合わせられるように配置されます(A)。bottom
の場合は逆で、行の下端であるafter-edgeに画像の下端が合わせられるように配置されます(B)。つまり、top
であれば上端にくっつくよう、bottom
であれば下端にくっつくように配置されるのです。そして、行の高さはその内容にあわせて高くなります。
以下がtop
の場合です。
行の上端に画像の上端が合わせられ、下部に行が拡張されます。
以下がbottom
の場合です。
top
の時とは逆で、行の下端に画像の下端が合わせられ、上部に行が拡張されます。
では、前回はじめに上げた例、<div><img></div>
のimg要素のvertical-align
を変更してみます。ここでは、わかりやすさのために、<div><img> xAhy 鈴</div>
と、テキストを後ろに足しています。まずはtop
の場合です。
行の上端に画像の上端が揃えられ、下部に行が拡張されています。
次はbottom
の場合です。
今度は逆で、行の下端に画像の下端が揃えられ、上部に行が拡張されています。
text-top, text-bottom
次はtext-top
、text-bottom
の場合です。
text-top
の場合は、text-before-edgeに画像の上端が合わせられるように配置されます(C)。text-bottom
の場合は逆で、text-after-edgeに画像の下端が合わせられるように配置されます(D)。font-size
により確保される領域の上端がtext-before-edge、下端がtext-after-edgeでした。この位置というのは、line-height
がいくら高くても関係ありません。簡単にいえば、文字のちょっと上にくっつくのがtext-top
、文字のちょっと下にくっつくのがtext-bottom
です。
そして、先程と同様、行の高さはその内容により高くなります。
以下がtext-top
の場合です。
font-size
により確保される領域の上端、text-before-edgeに画像の上端が合わせられ、下部に行が拡張されます。
以下がtext-bottom
の場合です。
text-top
の時とは逆で、text-before-edgeに画像の下端が合わせられ、上部に行が拡張されます。
この2つのパターンの時、図の青矢印で示した部分、つまり、before-edgeとtext-before-edgeの間、text-after-edgeとafter-edgeの間には、画像が侵入しないことに注目してください。この部分はどのようになっているか、先の例と同様、色を付けたサンプルで見てみましょう。まずはtext-top
の場合です。
そして次は、text-bottom
の場合です。
先の図で、青矢印で示した箇所がスペースとして確保されているのが分かります。
baseline, middle
次はbaseline
、middle
の場合です。
baseline
の場合は、baseline(alphabetical baseline)に画像の下端が合わせられるように配置されます(E)。middle
の場合は、img要素の高さの中央が、baselineからx-heightの高さの半分上の位置に揃うように配置されます(F)。
これまでと同様、行の高さはその内容により高くなりますので、その様子を見てみます。
以下がbaseline
の場合です。
baselineに画像の下端が揃えられるため、行は上に拡張されます。ということは、baselineよりも下に画像が侵入することはありません。
以下がmiddle
の場合です。
middle
の場合は、画像の中央のラインで揃えられるため、画像の高さが高くなった場合、上下に行が拡張されます。
では、先程と同様、色を付けたサンプルで見てみましょう。
以下がbaseline
の場合です。
ベースラインよりも下に画像が侵入することはありませんが、ベースラインより下も行の一部です。よって、このように画像下部にスペースが確保された状態になります。先の図で青矢印で示した箇所です。
そして次はmiddle
の場合です。
画像の高さが高くなれば、行は上下にどんどん広がります。この時に余計なスペースは発生していません。
<length>
最後はlength
の場合です。3px
とか0.3em
等が指定された場合です。
length
が指定された場合は、baselineよりその長さ分だけ上のラインに画像の下端が揃えられるわけですから、それよりも下側の部分が余白となります。
色を付けたサンプルで見てみましょう。
baseline
を指定したときよりも、広いスペースが下に確保されているのが分かります。
画像下部のスペースの謎
今回は、img要素のvertical-align
に様々な値を指定してみた場合を詳しく見てきました。もう既にお気づきかと思いますが、画像下部のスペースというのは、行として確保される領域の一部です。img要素の初期vertical-align
値はbaseline
です。よって、その場合に発生する画像下部のスペースというのは、baselineからafter-edgeまでの領域のこととなります。
これが、画像下部に発生する余分なスペースの謎でした。ただimg要素を置いただけだと、インライン要素が配置されただけなので、それは、行ボックスの中に配置されることになります。そうなると、行各部の領域が確保されてしまうこととなりますので、意図しない余白に悩まされてしまうかもしれません。
こんな時はどうすればいいかといいますと、行ボックスを作らなければよいのです。早い話、img要素にdisplay: block
を指定してやるのが一番でしょう。ブロックとして表示させたい要素にはちゃんとdisplay: block
を指定する……と、考えて見れば当たり前の話ではありますが。
次回は、今回までの連載内容を活かし、リストのビュレットをうまく配置する方法を解説します。
CodeGridについて
この連載の内容は、弊社、株式会社PixelGridが運営するフロントエンドの技術情報を配信するサービス、CodeGridにて連載された内容を元にしています。フロントエンド関する様々な情報を毎週配信しています。ご興味があれば、こちらもチェックしていただけると幸いです。
イベント動画
イベントの模様はYoutubeで公開されています。よろしければ、ご覧ください。