開発ブログ

WWWクリエイターズが送る、Git、CSS、HTML、コマンドライン、Macの便利機能など、開発に関する役立ち情報発信します。気まぐれに更新。

CSSで、上下(縦)に中央寄せする方法、徹底解説。

最終更新:2017-10-19 by Joe

HTMLとCSSで、テキストや画像を縦方向(上下方向)に中央寄せ(=センタリング)したい事があります。この課題は簡単そうに見えて、意外と厄介です。c

実際のところ、実現方法にはいくつか選択肢がありますが、いずれも、HTML、CSSの初学者にとってはちょっとだけトリッキーです。と、まあ嘆いてもしょうがないので、さっそく見ていきます。(ちなみに、IE10以降、ということでお願いしますね。さすがにもういいでしょう。)

1行のテキストを縦に中央寄せ

これはあまり細かい説明は不要かもしれませんが、CSSで、line-heightプロパティは、1行あたりの高さを定めます。下記の例は、text-aling:center; で、縦だけでなく、横方向にも中央寄せしています。

<!-- HTML -->
<div class="container">
  縦にセンタリングしてほしいの。
</div>

<!-- CSS -->
<style>
.container{
  line-height:200px;
  text-align:middle;
  background-color:#efd
}
</style>

CSSのline-heightプロパティは、その値にpx, %, 少数(割合を指定)などを取ります。割合を指定すれば、フォントサイズに対する割合として解釈されます。通常のウェブサイトでは、line-height は1.2〜2程度の値が読みやすい範囲ですので、そのくらいの値に設定されている事が多いと思います。ブラウザ(Chrome)のデフォルトは normal (1.2程度) です。上記のように、line-heightの値を極端に大きくすることで、自動的にテキストが縦方向の中央寄せに配置されます。

2行以上のテキストを縦に中央寄せ

これにはいくつか選択肢があります。いずれも、必ずしも直感的な方法ではないですので、CSSの仕様を少し理解しておく必要があります。

[方法1] インラインブロック大作戦

1行だろうと2行だろうと中央に配置できる、一番おすすめの方法です。displayプロパティの「inline-block」を利用します。

CSSの、inline-blockプロパティは、2017年現在では、ほとんどのブラウザで完璧にサポートされていますので、恐れる必要はありません。

<!-- HTML -->
<div class="container">
  <span class="target">縦にセンタリングしてほしいの。<br> 何行だって構わないわ。</span>
</div>

<!-- CSS -->
<style>
.container{
  line-height:200px;
  background-color:#fec;
  text-align:center;
}
.container .target{
  display:inline-block;
  vertical-align: middle;
  line-height:normal;
}
</style>

親要素で、line-height:300px と高さを固定することで、対象(と、そのプロパティを継承する子要素)内のテキストは自動的に行内で、中央に配置されます。(正確には「中央」というと語弊があるのは、こちらも同じです。)

ポイントは、その子要素(.target)に指定したスタイルで、line-heightの値を元に戻している点です。上記はnormalでブラウザのデフォルト値を取るように指定していますが、任意の値で構いません。このプロパティ「vertical-align」が有効な要素には、display:inline, display:inline-block, display:table-cellなどがあります。

逆に、display:blockである要素は、このvartical-alignプロパティを受け付けませんので、このことを知らないと「あれ〜、middleってやってるのに、なんでセンタリングされないんだろ〜?」と時間を浪費してしまいがちです。知っておくことって、大事ですね。

このinline-blockを使った中央寄せの方法には、上記の他にも、「親要素の高さをどのようにして決めるか?」において、いくつかの亜種がありますが、代表的なものをご紹介。

[方法2] テーブルセル作戦

これも一般的な方法で、CSSの「display:table」を使います。同時に、内包する要素に「display:table-cell」とするのを忘れないようにして下さい。特に親要素のtableは、width: autoの振る舞いがblockのときと違いますので、width値を宜しく設定下さい。

見た目は全然テーブル、すなわち、表ではないのですが、テーブル化するという、若干の気持ち悪さが残りらなくも無いですが、スタイル(=表現)の問題だけですので、問題ないでしょう。

<!-- HTML -->
<div class="container">
  <span class="target">「最近、テキストを縦にセンタリングする事ばかり考えちゃうの。」<br>2行目の女は言う。</span>
</div>

<!-- CSS -->
<style>
.container{
  display:table;
  width:100%;
  height:200px;
  background-color:#edf;
}
.container .target{
  display:table-cell;
  vertical-align:middle;
}
</style>

上述のように、table-cell も「vertical-align:middle」を受け付けます。「display:table-cell」は、tableの中のみで有効ですから、親要素をdisplay:tableしてやる。というわけです。

CSS「vertical-align」プロパティについて

テキストにおいて、厳密に「中央とは?」の定義を話をすると、かなり話が細かくなりますので、ここでは追求しないでいおきまが、「vertical-align: middle」によるレイアウトの定義は、「その要素の縦方向の中央線を、テキストのベースラインに「親要素の高さの半分」を足し合わせる」です。つまり、これは「親要素の中央」ではなく、ベースラインの分だけ上にずれます。Mozzila Develper Networkのページで、CSSプロパティ「vertical-align」の詳細な定義に言及しています:

画像を縦に中央寄せ

IMG要素の場合

imgタグは、デフォルトではdisplay:inlineのインライン要素です。つまり、上述のline-height作戦でも、ある程度中央寄せが可能です。但し、上述のように、line-heighとvertical-align:middleは厳密には「中央寄せ」ではありません。特に、画像は明確な四角形ですので、この事が問題になりやすいでしょう。

<!-- HTML -->
<div class="container">
  <img class="target" src="http://www-creators.com/wp-content/uploads/2017/05/1.png">
</div>

<!-- CSS -->
<style>
.container {
  width: 100%;
  line-height: 200px;
  background-color: #fac;
  text-align: center;
  position: relative;
}
.container .target {
  vertical-align:middle;
  height:120px
}
</style>

正確な中央寄せを実現するために、imgタグをblock化し、あとは、ブロック要素を中央寄せするための一般的な方法を適応すればOKです。

IMG要素は、インライン?

Google Chrome ではimg要素にデフォルトで「inline」が割当られていますが、width, heightなどのプロパティの値を受け取り、拡縮します。おかしいですね、インライン要素は、高さや横幅を持たないはずです・・・。

実は、img要素は「Replaced inline element」と呼ばれ、CSSの仕様の制約を必ずしも従わず、独自のレンダリングが施される要素です。実際には「inline-block」のような振る舞いをします。これには、HTMLの歴史的な背景が関係しているようです。

参考:Stackoverflow

ブロック要素の中央寄せに関しては、下記に続きます。

背景画像(background-image)の場合

画像を配置する時は(特別な強い理由がない限りは)IMGタグよりも、CSSの、backgroundプロパティを利用するのがおすすめです。

.container{ 
  display:block;
  width:300px;
  height:300px;

  background-image:url(img/my-photo.jpg);
  background-position:center center;
  background-size:cover
  background-repeat:no-repeat;
}

特に便利なのは、background-sizeでしょう。cover, containのいずれかで、画像の自動サイズ調整を行うことができます。

  • cover: 要素に空白ができないように拡大します。はみ出した部分を切り落とします。
  • contain: 縦、横のいずれかで、要素の長さを満たすように拡大します。(要素をはみ出しません)

これとbackground-position:centerを組み合わせれば、画像の自動配置で必要となる配置方法のほとんどは実現できるでしょう。

背景画像の中央寄せ

一方で、このbackgroundを使うと、img タグのaltのような値を設定できないため、SEO観点で不利だと考える説があります。ですが、もしそのページが十分にテキストを配置できる限りは、画像の近くに十分なテキストを配置することでカバーできるはずです。

alt 値は、そのページの価値の全てを左右するような魔法のキーワードではないからです。

ブロック要素の縦方向の中央寄せ

最も直感的なのは、position:absoluteを使った方法です。

margin:autoで、自動的に、上下、もしくは左右がそれぞれのバランスを取るようにマージンが計算されます。position:absoluteが座標の基準値を見つけられるよう、これの親要素を「position:relative」とします。(もしくは、absolute, fixed など、initial以外の値であれば、かまいません。)

.container{ 
  display:block;
  width:300px;
  height:100px;
  background-color:#ccc;
}

.target{
  position:absolute;
  display:block;
  left:0;
  right:0;
  top:0;
  bottom:0;
  margin:auto;
  height:90px
}

こちらは、IMGタグをブロック化した例ですが、ブロック化した要素であれば、a, div, p,  いかなる要素であろうとも適応できます。

<!-- HTML -->
<div class="container">
  <img class="target" src="http://www-creators.com/wp-content/uploads/2017/05/1.png">
</div>

<!-- CSS -->
<style>
.container {
  width: 100%;
  height: 200px;
  background-color: #cef;
  text-align: center;
  position: relative;
}
.container .target {
  display: block;
  height: 80px;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
</style>

参考

中央寄せについては、こちらにも網羅的に記載しています。ぜひご一読下さい。

CSSプロパティ「vertical-align」の詳細です。

閉じる