margin: auto;とposition: absoluteを組み合わせて特殊な中央揃えをする

HTML/CSS

こんにちは。今回はmargin: auto;をさらに深めていこうと思います。

margin: auto;での中央揃えが何故動くのか、基本的なことはこちらをご覧ください。

position: abusolute;との併用による中央揃え

margin: auto;を用いると要素を中央揃えにできることは知られていますが、position: absolute;と併用することでより特殊な中央揃えを行うことができます。この方法は、モーダルウィンドウなどを作るときに使える方法です。

モーダルウィンドウの作り方はこちらをご覧ください。

画面、もしくは親要素のY方向に対して中央揃え

position: absolute;を用いますので、画面もしくは親要素に対しての中央という話になります。

まずは適当な要素を作って配置しましょう。ここでポイントなのは、width/heightをauto以外の値にすることです。

<div class="Box"></div>
.Box {
  width: 300px;
  height: 200px;
  background-color: skyblue;
}

さて、横方向ではmargin-left/rightをauto;にすればよかったのですが、縦方向はどうでしょうか。

ここでposition: absolute;とmargin-top/bottomを同時に用います。

.Box {
  position: absolute; /*追加*/
  top: 0; /*追加*/
  bottom: 0; /*追加*/
  margin-top: auto; /*追加*/
  margin-bottom: auto; /*追加*/
  width: 300px;
  height: 200px;
  background-color: skyblue;
}

このように、top/bottomを0にした上でmargin-top/bottomをautoにすることで縦方向の中央に揃えることができました。これをさらに横方向に対しても中央に置いてみましょう。

画面、もしくは親要素のX、Y方向に対して中央揃え

先程のスタイルに、さらに横方向についての情報を追加します。

.Box {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0; /*追加*/
  right: 0; /*追加*/
  margin-top: auto;
  margin-bottom: auto;
  margin-left: auto; /*追加*/
  margin-right: auto; /*追加*/
  width: 300px;
  height: 200px;
  background-color: skyblue;
}

このように、縦方向の時と同様でleft/rightを0にしmargin-left/rightをautoにすることで中央に配置されます。

なぜ中央に揃うのか

position: absoluteと併用することで、margin: autoだけでは実現できなかった「縦方向の中央揃え」「縦横どちらに対しても中央揃え」が実現できました。なぜこのような挙動をするのでしょうか。

そのように定義されているから

はい、身も蓋もない言い方になってしまいますがこれが回答です。

具体的には、position: absoluteが指定されている要素に対して以下のようなルールになっています。(参考:https://www.w3.org/TR/CSS21/visudet.html

  • left, width, rightがどれもautoでない場合、margin-leftとmargin-rightの両方がautoならば2つのmarginが等しい値になる。
  • top, height, bottomがどれもautoでない場合、margin-topとmargin-bottomの両方がautoならば2つのmarginが等しい値になる。

なんとなくこの条件をコードっぽく書いてみましょう。


if (
  left !== "auto" &&
  width !== "auto" &&
  right !== "auto" &&
  marginLeft === "auto" &&
  marginRight === "auto"
) {
  equalizeMarginLeftAndRight()
}

if (
  top !== "auto" &&
  height !== "auto" &&
  bottom !== "auto" &&
  marginTop === "auto" &&
  marginBottom === "auto"
) {
  equalizeMarginTopAndBottom()
}

このような条件になっています。left, width, right、そしてtop, height, bottomはそれぞれ初期値がautoです。

そのため、Y方向に中央揃えする場合はtop, height, bottomをauto以外の値に、X方向に中央揃えする場合はleft, width, rightをauto以外の値にする必要がありました。

まとめ

ということで、margin: auto;とposition: absolute;が併用された場合の挙動について解説しました。

margin: autoに限らず中央揃えに関してはさまざまな方法があるので、機会があれば「いろんな中央揃え」という切り口で解説しようと思います。

コメント

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