align-items: center;
縦の中央揃えで簡単なのは、グリッドレイアウト(またはフレックスボックス)とalign-items: center;を適用させる方法です。
グリッドレイアウトやフレックスボックス(display: grid; / display: flex;)では、align-itemsというCSSプロパティを使うことができます。
これを適用させるだけで、グリッドレイアウトやフレックスボックス(以下『グリッドレイアウト等』)のアイテムが縦方向に中央に配置されます。
※ちなみにですが、グリッドレイアウト等のアイテムの横方向の中央配置はjustify-content: center;でできます。
それでは冒頭で例に出したCSSコードを確認していきましょう。
<div class="parent">
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent {
width: 80%;
height: 150px;
background-color: lightblue;
display: grid;
align-items: center;
}
注意点は、当然と言えば当然なのですがhightの具体的な値の指定が必要であるという点です。
横方向は、デバイス画面の横幅(ブラウザの横幅)いっぱいが1つのブロックレベル要素分の幅という基準が存在するので、その基準で中央値を求めることができます。
なので、横方向(width)に関しては初期値のautoでも中央配置にすることが可能です。
しかし縦方向に関しては1ブロックレベル要素あたり、何pxとか何%とか決まっていません。
なので、heightで縦方向の幅を決める必要があるというわけです。
*ブロックレベル/インラインレベルの記事についてはこちら
また、アイテムが1つだけの場合はグリッドレイアウトでもフレックスボックスでもalign-items: center;で良いのですが、フレックスボックスで複数のアイテムを横並びにせずに縦方向に中央配置にしたい場合は、justify-content: center;を使う必要が出てきます。
というのも、フレックスボックスだとデフォルトの設定ではアイテムが横並びになってしまうため、複数の要素を縦並びのまま縦方向に中央配置にしたい場合、まずflex-direction: column;にして要素を縦並びにしなければなりません。
しかし、flex-direction: column;で横並びを縦並びにしたものは、横と縦が入れ替わっている状態なので、align-itemsとjustify-contentを入れ替える必要がるというわけです。
(▼参考)フレックスボックスを使って、複数のアイテムを横並びにせずに縦方向に中央配置にする場合
<div class="parent2">
<p>このテキスト文章を縦方向に中央配置したい。</p>
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent2 {
width: 80%;
height: 200px;
background-color: lightblue;
display: flex;
flex-direction: column;
justify-content: center;
}
このテキスト文章を縦方向に中央配置したい。
このテキスト文章を縦方向に中央配置したい。
一方で複数のアイテムを縦の中央に配置したい場合、グリッドレイアウトならば便利なのかというと、残念ながらそうでもありません。
グリッドレイアウトだと、アイテムがボックスの中央にギュッと寄せられるのではなく、グリッドボックスの中で中央に配置されるからです。
どういうことなのか、これは言葉よりコードと表示結果を見た方が早いと思います。
<div class="parent3">
<p>このテキスト文章を縦方向に中央配置したい。</p>
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent3 {
width: 80%;
height: 200px;
background-color: lightblue;
display: grid;
align-items: center;
}
このテキスト文章を縦方向に中央配置したい。
このテキスト文章を縦方向に中央配置したい。
…とこのように、『思ったような縦方向の中央配置ではない』という感じになってしまいます。
結局はHTMLコードを書き換えて、複数要素はグリッドレイアウトの孫要素にして、子要素(グリッドアイテム)は1つになるようにするのが最も簡単な方法だと思います。
▼HTMLを書き換えてグリッドアイテムを1つにした例
<div class="parent4">
<div>
<p>このテキスト文章を縦方向に中央配置したい。</p>
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
</div>
.parent4 {
width: 80%;
height: 200px;
background-color: lightblue;
display: grid;
align-items: center;
}
このテキスト文章を縦方向に中央配置したい。
このテキスト文章を縦方向に中央配置したい。
グリッドレイアウト等のアイテム(子要素)数に気をつける必要はありますが、その点さえクリアできれば、最も簡単かつ色々な要素に対して縦方向の中央配置ができる方法です。
*フレックスボックスの記事はこちら
*グリッドレイアウトの記事はこちら
をそれぞれご参照ください。
POINT!
- ・グリッドレイアウト等にalign-items: center;と指定することで、縦方向への中央配置ができる!
- ・ただし、アイテム(子要素)の数が複数の場合は思ったような配置にならない場合があるので注意!
- ・対応策としては、HTMLコードを編集してアイテム数が1つになるようにすると良い!
padding-top/bottomの数値を同じに
前章では高さ(height)の数値を明確に指定することで縦方向への中央配置ができましたが、height値を明確に定義したくない(初期値のautoのままにしておきたい)という場合もあるかと思います。
そんな時には、padding-top/bottomを同じ値に揃えるとうまくいきます。
理屈も簡単で、内側の余白であるpaddingの上下(top/bottom)の数値を同じにすれば、必然的に中の要素は縦方向に中央に配置されるという仕組みです。
<div class="parent5">
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent5 {
width: 80%;
background-color: lightblue;
padding: 50px 0;
}
この方法であれば、子要素(サンプルコードで言うとpタグ)が増えても、CSSやHTMLコードを書き換えたりする必要はありません。
<div class="parent6">
<p>このテキスト文章を縦方向に中央配置したい。</p>
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent6 {
width: 80%;
background-color: lightblue;
padding: 50px 0;
}
このテキスト文章を縦方向に中央配置したい。
このテキスト文章を縦方向に中央配置したい。
ただし、この方法だと当然ですが縦方向に中央に揃えた上で、さらにpaddingを指定することができません。
余白をコンテンツごとに統一させたい場合などは注意が必要です。
また、この方法はheightの値を定めなくても良いのがメリットですが、それは同時にデメリットでもあります。
というのもheightを定めなくても良いというよりはむしろ、heightを定めたらうまくいかない(=height値を指定できなくなる)方法だからです。
(▼参考)heightを指定してしまうと縦の中央配置が崩れてしまう。
<div class="parent7">
<p>このテキスト文章を縦方向に中央配置したい。</p>
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent7 {
width: 80%;
height: 200px;
background-color: lightblue;
padding: 50px 0;
}
このテキスト文章を縦方向に中央配置したい。
このテキスト文章を縦方向に中央配置したい。
paddingやmarginといった余白はそれぞれの要素に必ずと言って良いほど指定するCSSプロパティなので、管理が複雑になりがちです。
padding-top/bottomの値を揃えることで簡単に縦の中央配置ができるのですが、paddingで調整しようとするとどこかでズレたりしてしまう可能性が高く、あまりおすすめできる方法ではありません。
POINT!
- ・padding-top/bottomの値を揃えることで、子要素が縦方向に中央配置される!
- ・heightの値を指定しない(初期値のautoのまま)で良いが、むしろ具体的な値は指定できない!
- ・余白は多くの要素に指定されるものなので、paddingにおける縦の中央配置には注意が必要!
vertical-align: middle;
次に紹介するのは冒頭でもチラッと言及した、vertical-align: middle;というCSSを適用させる方法です。
そして前述の通り、このCSSはインラインレベルの要素にしか効かないという特徴があります。
ただし、純粋なインラインレベルだけでなくtable-cellやinline-blockにも効くので、displayプロパティでこれらの要素レベルに変更して使うのが基本になります。
とはいえ、上記の3種類の要素レベルならどれでも同じ表示結果になるかと言うとそうではなくて、inline/inline-blockに対するvertical-alignと、table-cellに対するvertical-alignの効き方が違います。
こういった仕様もあり、vertical-alignによる縦の中央揃えはなおさらおススメできないところがあります。
サンプルでは期待する表示結果になるtable-cellに要素レベルを変更しています。
それでは、CSSコードと表示結果を確認していきましょう。
<div class="parent8">
<p>このテキスト文章を縦方向に中央配置したい。</p>
<p>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent8 {
width: 80%;
background-color: lightblue;
}
.parent8 p {
height: 200px;
display: table-cell;
vertical-align: middle;
}
このテキスト文章を縦方向に中央配置したい。
このテキスト文章を縦方向に中央配置したい。
というわけで縦方向の中央配置は一応できたわけですが、今回は子要素のpタグにheightを指定しているところがポイントです。
これを親要素に指定してしまうとうまくいかないのでご注意下さい。
そしてもう一点ご注意ですが、ご覧の通りpタグをtable-cellレベルにしたため、要素が横並びになってしまっています。
これを解消するには、上のサンプルのようにpタグを2つ挿入するのではなく、brタグで改行を挟むと良いです。
(▼参考)改行を挟むことで、複数行を中央配置する
<div class="parent8">
<p>このテキスト文章を縦方向に中央配置したい。<br>このテキスト文章を縦方向に中央配置したい。</p>
</div>
.parent8 {
width: 80%;
background-color: lightblue;
}
.parent8 p {
height: 200px;
display: table-cell;
vertical-align: middle;
}
このテキスト文章を縦方向に中央配置したい。
このテキスト文章を縦方向に中央配置したい。
このようにブロックレベル要素をvertical-alignプロパティを使って縦に中央配置するには、要素をtable-cellレベルに変更しなければならず、要素レベルが変わることで別の問題が発生することもしばしばあります。
グリッドレイアウト等が登場してブラウザに対応した今となっては、あえてこちらの方法で調整するメリットはほとんどありません。
掲載時期が古いブログ記事には、table-cellとvertical-aligの組み合わせによる縦の中央配置の方法がおすすめされていることもありますが、当時はグリッドレイアウト等がまだ一般的になる前だったからです。
ただ、この方法が使われている古いWebサイトを修正・改修する際には知っておいた方が良い知識と言えるため、本記事でも取り上げてみました。
今(2021年)となってはあまりメリットは大きくないですが、古いブラウザの代表であるInternet Explorer(IE)にも対応しているという利点も一応あります。
POINT!
- ・display: table-cell;&vertical-align: middle;で縦方向の中央配置が可能!…だが…
- ・要素のレベルを変更することになるので、思わぬ表示になってしまうリスクも!
- ・古いWebサイトに使われていたりするので、念のための知識として知っておくと良い(かも)!
positionで調整
これまで紹介した方法は、自動的に中央に揃えてくれるCSS調整でしたが、計算して中央の位置を求めることで、縦の中央に配置する方法もあります。
それがpositionプロパティを使った方法です。
*positionプロパティの記事についてはこちら
まず、親要素の位置をpotision: relative;で基準位置に指定し、縦方向に中央配置したい子要素の位置をabsoluteで絶対位置に指定します。
そして子要素に対し、top: 50%;とすると、子要素が親要素のトップの高さから50%位置移動するので、この時点でおおよそ中央の位置にくることになります。
ただし、『おおよそ』という表現の通り、これだけでは厳密に中央配置にはなりません。
というのも、top: 50;という指定では、子要素の上端の位置がちょうど中央の位置に来るので、全体としては下寄りになるためです。
論より証拠ということで、まずはtop: 50%;のみを指定したコードと表示結果を見ていきましょう。
縦の中央の位置が分かりやすいように、ちょうど中央の高さで背景色が切り替わるようにしています。
<div class="parent9">
<p>position中央配置</p>
</div>
.parent9 {
width: 80%;
background-image: linear-gradient( lightblue 50%, lightyellow 50%);
height: 200px;
position: relative;
}
.parent9 p {
font-size: 16px;
position: absolute;
top: 50%;
}
このように背景色が切り替わる中央ではなく、色が切り替わった後の中央より下の位置にテキストが移動しています。
ではどうすれば良いかというと、calc( )関数を使って微調整するとうまくいきます。
用語解説:calc関数とは?
子要素の上端が50%(縦の中央)に来てしまうのですから、その位置から子要素の高さ(height)の半分の数値を引けば良いと言うことになります。
16pxのフォントサイズの文字の高さはline-heightの値によっても変わってくるので一概には言えませんが、このブログでは27pxになってます。(高さはブラウザの検証で測定可能です)
なので13.5px引けば良いということになりますね。
では、calc( )関数を使ったコードと表示結果を見ていきましょう!
<div class="parent10">
<p>position中央配置</p>
</div>
.parent10 {
width: 80%;
background-image: linear-gradient( lightblue 50%, lightyellow 50%);
height: 200px;
position: relative;
}
.parent10 p {
font-size: 16px;
position: absolute;
top: calc( 50% - 13.5px );
}
ちょうど背景色が切り替わるタイミングの位置(=縦の中央)に配置されましたね。
注意点としては、テキスト要素の場合、PCでは1行で済むがスマホでは2行に折り返されてしまうということがよくありますよね。
その場合、上記の方法だとテキストの1行目が中央に位置し、2行目以降は中央より下にずれることになります。
また、画像など改行されない要素であってもPCとスマホで表示サイズを変えている場合は、calc( )関数の指定値も変更しないと位置がズレるので注意が必要です。
POINT!
- ・position、topプロパティで縦方向の中央に要素を位置移動させることもできる!
- ・top: 50%;だけだと要素の上端が中央に来るため、全体的には中央より下寄りになってしまう!
- ・calc( )関数を使って、要素の高さの半分を引けばちょうど中央に位置を調整できる!