フッターメニューやページ送りのナビゲーションで、リスト項目を横一列に並べて、しかも全体を真ん中に置きたい。私も何度もぶつかってきた場面です。ところが「margin: 0 auto;」や「text-align: center;」を素直に書いても、リスト全体がきれいに中央へ来てくれないことがあります。
この記事では、その中央揃えを実現する方法を、昔ながらのfloatを使うやり方から、今なら第一候補になるFlexboxやGridまで整理して紹介します。今から新しく書くならFlexboxが一番ラクなので、まずはそこから始めます。
まず結論:今ならFlexboxが一番簡単
リストを横並びにして中央に置くだけなら、ul(リストを囲む親)に display: flex; と justify-content: center; を指定するだけで済みます。floatのように打ち消しの計算をする必要はありません。
HTML
<div id="menu">
<ul>
<li><a href="#">メニュー1</a></li>
<li><a href="#">メニュー2</a></li>
<li><a href="#">メニュー3</a></li>
<li><a href="#">メニュー4</a></li>
<li><a href="#">メニュー5</a></li>
</ul>
</div>
以下ではこのHTMLを共通して使います。
Flexboxで中央揃えする(推奨)
CSSはこれだけです。
#menu ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
justify-content: center;
}
ulを display: flex; にすると、中のli要素は自動的に横並びになります。float: left; を書く必要はありません。そのうえで justify-content: center; を指定すると、並んだ項目のかたまりが親要素の横方向(主軸)の中央に配置されます。MDNでも justify-content: center は「アイテムを主軸の中央に寄せてまとめて配置する」値と説明されています。
項目が多くて1行に収まらないときは、次のように折り返しを許可しておくと安心です。
#menu ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
flex-wrap: wrap; を付けると、幅に入りきらない項目が次の行へ折り返されます。横スクロールバーが出てしまう心配もなくなります。上下方向の位置も揃えたいときは align-items: center; を足せば、縦方向(交差軸)の中央にもそろいます。
Gridで中央揃えする
Gridでも同じことができます。項目の間隔を gap でまとめて指定できるのが気持ちいいところです。
#menu ul {
list-style: none;
padding: 0;
margin: 0;
display: grid;
grid-auto-flow: column;
justify-content: center;
gap: 10px;
}
grid-auto-flow: column; で項目を横方向に並べ、justify-content: center; でグリッド全体を中央へ寄せています。項目の間隔は margin ではなく gap: 10px; で管理できるので、端の余白がずれる心配もありません。横一列のメニュー程度ならFlexboxで十分ですが、行と列を組み合わせたレイアウトに発展させたいときはGridが向いています。
【レガシー】floatで中央揃えする方法
ここからは、FlexboxやGridが普及する前によく使われていた、floatによる中央揃えです。今は第一候補ではありませんが、仕組みとして今も動きますし、古いコードを読むときに知っておくと役立ちます。
floatで横並びにしたリストは、ul全体をそのまま中央に置こうとしてもうまくいきません。そこで、ul要素を右に50%動かし、li要素を左に50%戻すというテクニックを使います。
#menu { position: relative; overflow: hidden; }
#menu ul { position: relative; float: left; left: 50%; }
#menu li { position: relative; float: left; left: -50%; }
それぞれの役割はこうです。
- #menu に
position: relative;を付けて、内側の要素の位置決めの基準にします。overflow: hidden;は、ズレによって横スクロールバーが出るのを防ぐための対策です。 - #menu ul に
float: left;とleft: 50%;を指定し、リスト全体を右へ50%移動させます。 - #menu li に
left: -50%;を指定して、各項目を左へ50%戻します。結果として、ちょうど中央にそろいます。
ulを右に50%、liを左に50%と、逆方向に同じだけ動かすことで打ち消し合い、全体が中央に来るという理屈です。left: -50%; は right: 50%; と書いても同じ意味なので、わかりやすい方を使えば大丈夫です。
どれを選べばいい?
今から新しく書くなら、迷わずFlexboxをおすすめします。コードが短く、意図も読み取りやすく、折り返しや縦の中央揃えにも素直に対応できます。行列のあるレイアウトに広げたいならGrid。そして、既存のfloat中心のコードを触っていて、周りに合わせたいときや、そのまま手を入れたいときはfloatの手法、という使い分けが現実的です。
まとめ
floatで横並びにしたリストを中央揃えする方法を、レガシーな手法と現代的な手法の両方で見てきました。ポイントを整理します。
- 今ならFlexbox:ul に
display: flex;とjustify-content: center;だけ。折り返すならflex-wrap: wrap;を追加。 - 行列に広げたいならGrid:
display: grid;とgapで間隔もまとめて管理。 - floatは ul を right へ50%、li を left へ50%で打ち消して中央に。今も動くが位置づけはレガシー。
手元のコードの事情に合わせて、一番ラクに書ける方法を選んでください。