できる!中央寄せ 2024年版 前編 絶対配置による中央寄せ

現在ではCSS Flexbox、CSS Gridなどさまざまプロパティが使えます。そこで、「今ならこうできる!中央寄せ」を詳細に解説します。第1回はお馴染み絶対配置による中央寄せです。従来からの手法でもよりシンプルな記述ができます。

発行

著者 國仲 義則 フロントエンド・エンジニア
できる!中央寄せ 2024年版 シリーズの記事一覧

はじめに

CSSの中央寄せにはさまざまな方法があります。CodeGridでも過去に連載されていました。

このシリーズは2015年のもので、現在主流の方法とは差が出てきています。

この記事では、最近の中央寄せはどのようなものが使われているのか、それぞれ見てみましょう。

第1回は、従来からある手法ですが、現在でも現役である「絶対配置による中央寄せ」をテーマにします。絶対配置による中央寄せは、要素の幅がわかっている場合に使えます。この方法は長年使われており、今でも現役ですが、従来とは記述を変更して使うとよいでしょう。

なお、この記事に掲載されているデモは、次のリポジトリにあります。併せて、参考にしてください。

できる! 中央寄せ 2024年版

ショートハンドプロパティinsetが使える

元のHTML

<div class="container">
  <div class="centered">中央寄せ</div>
</div>

絶対配置による中央寄せ

.container {
  position: relative;
  /* 任意の高さと幅を指定 */
}

.centered {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  /* 任意の高さと幅を指定 */
}

以前はこのような指定を行っていました。しかし、現在ではショートハンドプロパティが実装されたことで、より簡潔な記述が可能です。

ショートハンドプロパティによる中央寄せ

.centered {
  position: absolute;
  inset: 0;
  margin: auto;
  /* 任意の高さと幅を指定 */
}

このようにinsetを使って記述することで、top, bottom, left, rightを一括指定できます。

まず、中央寄せしたい要素の先祖にposition: relativeを指定することで、どの要素を基準として中央寄せするかを決定します。

中央寄せしたい要素にposition: absoluteを指定した上で、固定された高さと幅を指定することで、中央寄せ対象の要素の大きさを確定させます。

ショートハンドinset: 0によって要素はposition: relativeが指定された要素の上右下左から0の距離となります。

margin: autoによって、マージンが等しく分配されます。これにより、要素は親要素の中央に配置されます。

マージンのautoキーワードは利用可能な余白を埋めるように動作しますが、今回の場合は上下または左右が対称ですので、均等に分配されます。

実際の例を見てみましょう。

元のHTML

<div class="container">
  <div class="centered">Lorem ipsum dolor sit amet...</div>
</div>

insetプロパティによる中央寄せ

.container {
  position: relative;
  width: 500px;
  height: 300px;
  border: 1px solid silver;
}

.centered {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 250px;
  height: 150px;
  background-color: mistyrose;
}

500px幅と300px高さの親要素に対して、250px幅と150px高さの子要素を絶対配置で中央寄せしています。

視覚的にわかりやすくするために、親要素にはボーダーを、子要素には背景色を指定しています。

グレーのボーダーを持つ要素の中央に、ピンクの背景色を持つ要素が配置されているのがわかります。

幅や高さにmin-contentmax-contentfit-contentが使える

従来の絶対配置による中央寄せとは違う点として、幅や高さを指定する方法が増えたことが挙げられます。

Internet ExplorerとEdgeHTML版Microsoft Edgeのサポートが終了したことにより、min-content max-content fit-contentキーワードが使えるようになりました。

min-contentは、要素の中身が取り得る最小の大きさとなります。高さは行の高さと同じになりますが、幅はちょっと複雑です。

英語のような分かち書きテキストの場合、もっとも長い単語の幅になるでしょう。

日本語の場合は文字単位になりますので、1文字幅になる可能性が高いです。テキストの折り返し処理がどのような状況にあるかによっても変わりますので、かならず1文字幅になるわけではありません。たとえば句読点があれば、2文字幅になるでしょう。

ほか、英語日本語にかかわらず、white-spaceなどの折り返し処理の指定があれば、それに応じた幅になります。

max-contentmin-contentと同様に、要素の中身が取り得る最大の大きさとなります。テキストの場合、折り返されずに1行で表示される場合の幅になります。

fit-contentmax-contentと似ていますが、親要素の大きさを超えないように調整されます。

これらのキーワードについて、デモで確認してみましょう。

それぞれ幅にmin-contentmax-contentfit-contentが指定された要素があります。比較として短いテキスト版と長いテキスト版があります。

先ほどの説明どおり、min-contentはもっとも長い1ワード幅、max-contentは文字列分の幅、fit-contentは親要素の幅を超えない幅になっていることがわかります。

次に日本語でのmin-contentです。

1文字幅になっていますが、最後に句点を追加したものは2文字幅になっています。

このように、これらのキーワードは折り返し指定や禁則処理にも影響を受けることがわかります。

ほかに、比較関数も登場しています。これらを使うことで、より柔軟な指定が可能になりました。

絶対配置とmargin: autoによる中央寄せは以前からある手法ですが、新しい記述を取り入れることで、より簡潔に、より柔軟な指定が可能になっています。

fit-contentの例を見てみましょう。

fit-contentの使用

.container { /* 同じ */ }

.centered {
  position: absolute;
  inset: 0;
  margin: auto;
  width: fit-content;
  max-width: 80%;
  height: min-content;
  background-color: mistyrose;
}

中央寄せ対象の要素の幅にfit-contentを指定しています。また、最大幅を80%に制限することで、基準となる要素の幅より小さな幅になるようにしました。

高さにはmin-contentを指定し、中身の行の高さに合わせています。

この方法は固定配置の要素を中央寄せするのに向いています。

position: fixedである要素をビューポートに対して中央寄せしたい場合は、先ほどのコードのposition: absoluteposition: fixedに変更して活用できるでしょう。

元のHTML

<body>
  <div class="centered">Lorem ipsum dolor sit amet...</div>
</body>

固定配置要素の中央寄せ

.centered {
  position: fixed;
  inset: 0;
  margin: auto;
  width: fit-content;
  max-width: 80%;
  height: min-content;
  background-color: mistyrose;
}

先ほどのコードのposition: absoluteposition: fixedに変更されています。position: relativeが指定されていた要素は削除しています。

position: fixedの場合、ビューポートに対して中央寄せされます。

この手法はモーダルダイアログのように、ビューポートの中央に配置したい要素に向いています。

絶対配置+transformによる中央寄せ

絶対配置の中央寄せには、transformを使った方法もあります。

元のHTML

<div class="container">
  <div class="centered">中央寄せ</div>
</div>

transformを用いた中央寄せ

.container {
  position: relative;
  /* 任意の高さと幅を指定 */
}

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

基準となる要素にposition: relativeが指定されているのは変わりません。

中央寄せ対象の要素にposition: absoluteを指定し、top: 50% left: 50%で、基準要素の中央に対象要素の左上が合うように配置します。

さらにtransform: translate(-50%, -50%)で、対象要素の幅50%分を左方向に、高さ50%分を上方向に移動させます。

これにより、基準要素の中央に対象要素が配置されます。

こちらはあまり見かけなくなりました。要素の高さと幅がわかっている場合は前述の方法で十分ですし、そうでなくても新しいキーワードや関数を使うことで対応できる場面も多いでしょう。

この方法が必要な場面では、次回解説するFlexboxやCSS Gridのほうが向いていることが多いでしょう。現在、選択肢がある中で、あえてこの方法を採用するメリットはありません。

もしこの方法を使う場合にも、transformプロパティではなくtranslateプロパティを使うことで、より簡潔になります。

translateを用いた中央配置

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  translate: -50% -50%;
}

基本的には先ほどと同じコードですが、transformプロパティの代わりにtranslateプロパティを使っています。 これにより、コードが少しシンプルになりました。

translateプロパティについては過去にCodeGridで紹介されています。

絶対配置のまとめ

絶対配置による中央寄せのメリットは、昔から存在する方法であるため、古いブラウザでも対応しているという点です。従来の記述方法なら、かなり古い環境でも対応できます。

現在の環境がターゲットの場合、ショートハンドプロパティinsetを使ってシンプルな記述が可能となりました。

デメリットとしては中央寄せしたい要素の幅と高さを指定する必要がある部分ですが、新しいキーワードを用いることで、固定値を指定する以外の選択肢が生まれました。

この方法は中央寄せしたい要素自体に配置の指定を行うため、どの要素を基準にするのかを把握する必要があります。

position: absoluteならば、position: relative/absolute/fixedが指定された先祖要素が基準となるため、それらを知っていなくてはなりません。

position: fixedならば、ビューポートが基準となります。これは大きな特徴です。

ビューポートを基準にした中央寄せUIを作りたい場合には、この方法が向いています。

向いていない場面は、中央寄せしたい対象が複数ある場合です。複数の要素を中央寄せする場合には、FlexboxやCSS Gridのほうが向いています。

次回は、Flexbox、CSS Gridによる、まさに「現代らしい」中央寄せの手法を解説します。