PR

中央揃えにleft: 50%; transform: translateX(-50%);などという馬鹿げた記述をするな

HTML/CSSを学ぶ

こんにちは。今回はよく紹介される中央揃えテクニックについて思うところがあったので、最新の中央揃えを解説します。

よく紹介される、position: absolute;にしてleft: 50%; transform: translateX(-50%);を指定するような馬鹿げた記述は忘れてください

中央揃えはflexでやれ

現代のCSSにおいてはスマートに中央揃えができる方法がいくつかあります。もちろん横方向だけでなく縦方向も自在です。直感的にも分かりやすい方法で言えば、display: flex;とjustify-content、align-itemsを組み合わせて使うのがおすすめです。

まず上下左右の中央に揃える場合を見て見ましょう。見た目は次の通り。

コードは以下になります。

<div class="Container">
  <div class="Box"></div>
</div>
.Container {
  width: 100%;
  height: 300px;
  background-color: skyblue;
  display: flex;
  justify-content: center; /* 横方向 */
  align-items: center; /* 縦方向 */
}

.Box {
  width: 100px;
  height: 100px;
  background-color: pink;
}

親要素にdisplay: flex;を指定し、横方向の位置を指定するjustify-contentと縦方向の位置を指定するalign-itemsをそれぞれcenterにすることで中央に配置しています。

それぞれflex-start、center、flex-endという3つの値が指定でき、以下の表のように配置できます。

flex-startcenterflex-end
justify-content中央
align-items中央

例えばjustify-content: flex-end; 、align-items: flex-start; なら右上に配置されます。

下にデモを作ったので、それぞれの値をセレクトボックスで変えてみてください。値の組み合わせによって9方向の位置に要素を配置することができます。

justify-content:
align-items:

親要素のサイズ、子要素のサイズ、ブロックかインラインかなど余計なことを一切考えずに中央揃えができるので本当におすすめの方法です。ほぼ全ての場合においてこの方法さえ覚えておけば問題ありません。

モーダルウィンドウなど、他の要素と関係なく画面の中央に配置したい場合でも.Containerを画面いっぱいに広げた上でposition: fixed;にして使えば問題ありません。

.Container {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background-color: skyblue;
  display: flex;
  justify-content: center;
  align-items: center;
}

.Box {
  width: 100px;
  height: 100px;
  background-color: pink;
}

もしくはgridでやれ

display: grid; でも同様に中央揃えができます。親要素をdisplay: grid; にした上でjustify-itemsとalign-itemsを指定してください。justify-contentではないので注意してください。

startcenterend
justify-items中央
align-items中央

ちなみにこちらの場合はjustify-itemsとalign-itemsを一括指定できるplace-itemsというプロパティがあり、以下のように書くと上下左右中央に子要素を配置することができます。

.Container {
  display: grid;
  place-items: center;
}

position: absolute; left: 50%; transform: translateX(-50%); がなぜダメなのか

レイアウト崩れの原因になりやすい

まずposition: absolute;などは安易に使うとレイアウト崩れの温床になります。positionプロパティがabsoluteやfixedの場合、要素が通常のフローから外れます。具体的には、

  • 要素が重なる
  • 親要素がその要素の横幅、高さを認識しなくなる

などが起こります。

そういうプロパティなので当然と言えば当然ですが、要素の中央揃え目的で使うと考えると面倒ごとが増えてますね。

また、ただ要素をposition: absolute;にすると親要素ではなくページの左上が基準点になってしまいます。必ず基準にしたい親要素をposition: relative;にして使ってください。これを忘れて数時間を失う初心者を何人も見てきました。

コードの意味が分かりにくい

パッと見でposition: absolute; left: 50%; transform: translateX(-50%); とあった時に、これが中央揃えを意味していることは正直分かりにくいですよね。実際Xの投稿でも「なんでこれで中央に行くか分からない」という声が散見されます。

一応解説すると、leftにおける%指定は親要素の横幅に対する割合を示し、translateの%指定は要素自身の横幅に対する割合を示します。

left: 50%;だけだと、50%地点を始点に要素が配置されてしまうので右に行き過ぎてしまいます。その分をtranslateX(-50%);とし、要素の半分だけ左に戻すことで中央揃えを実現しています(下画像参照)。

縦方向についても考え方は同じです。

広く用いられたコードではあるので知っておくべきだという意見も分からなくはないです。しかしflexのように明確に中央揃えができるプロパティがある中わざわざこんなものを持ち出す方が問題と言えます。

古い方法を使って可読性を下げるより、「center」という分かりやすい単語で指定できるjustify-contentやalign-itemsの方がメンテナンス性も上でしょう。

そもそもハック的なやり方であり時代遅れ

この手法、配置に関するプロパティが十分になかった頃の遺物とも言える代物です。いまだに要素の横並べにfloat: left; を使っているのと同レベルです。

総合的に見て、可読性・メンテナンス性・バグの起きやすさなど、コードの品質的にどれをとってもおすすめしません。

left: 50%; transform: translateX(-50%); はやめよう

というわけで中央揃えの書き方についてでした。ぱっと見で分からない記述はやめて、分かりやすい記述を優先しましょう。

display: flex;についてさらに詳しく書いた記事もあるので合わせてご覧ください。

こういったテクニックをもっと知ってレベルアップしたい方はぜひこちらの本で勉強してみてください。僕がフリーランスで活動する中で培ったコーディングテクニックを厳選したおすすめの本です。

【脱・初心者】教材だけでは分からない、案件でよく要求される細かいコーディングのテクニック30選 + α - セカヤサBooks
フリーランスのフロントエンドエンジニアとして7年間、サイト制作やWebアプリケーション開発の案件に携わってきた中で「これは伝えたい」と思ったコーディングのテクニックをまとめました! 正直言うと、これができているかどうかが「プロかプロでないか...

参考

フレックスボックス - ウェブ開発を学ぶ | MDN
フレックスボックス (Flexbox) は、アイテムを行または列に並べるための 1 次元のレイアウト方法です。アイテムがたわんで(伸びて)追加の空間を埋めたり、縮んで小さい空間に収まったりします。この記事では、すべての基本事項について説明し...
justify-content - CSS: カスケーディングスタイルシート | MDN
CSS の justify-content プロパティは、フレックスコンテナーの主軸およびグリッドコンテナーのインライン軸に沿って、中身のアイテムの間や周囲に間隔を配置する方法を定義します。
align-items - CSS: カスケーディングスタイルシート | MDN
CSS の align-items プロパティは、すべての直接の子要素に集合として align-self の値を設定します。フレックスボックスでは交差軸方向のアイテムの配置を制御します。グリッドレイアウトでは、グリッド領域におけるアイテムの...
place-items - CSS: カスケーディングスタイルシート | MDN
CSS の place-items は一括指定プロパティで、アイテムのブロック軸およびインライン軸に沿ったアイテムの配置 (すなわち align-items および justify-items プロパティ) を、グリッドやフレックスボックス...

コメント

タイトルとURLをコピーしました