【簡単解説】floatで横並びにしたリストをCSSで中央揃えする方法

コードが書かれたモニター

フッターメニューやページ送りのナビゲーションで、リスト項目を横一列に並べて、しかも全体を真ん中に置きたい。私も何度もぶつかってきた場面です。ところが「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%で打ち消して中央に。今も動くが位置づけはレガシー。

手元のコードの事情に合わせて、一番ラクに書ける方法を選んでください。