web-dev-qa-db-ja.com

なぜ「margin:auto」は要素を垂直方向に中央揃えしないのですか?

以下のデモでわかるように、margin: auto;青いdivを水平方向に中央揃えしますが、垂直方向には中央揃えしません。何故なの?

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto;
}
<div class="box">
  <div class="center"></div>
</div>

私の質問は回避策を求めていません。

46
Stickers

前述のように、この動作はCSS2.1の セクション10.6.2 で指定されており、 CSS2 から変更されていません。

通常のフローでは、ブロックボックスは上から下に垂直に積み重ねられます。さらに、 垂直マージンは折りたたむ可能性があります 、特定の状況下でのみそうします(デモでは、親要素の境界線により、子要素のマージンがそれ自体で折りたたまれることを防ぎます)。そのようなブロックボックスが1つしかなく、包含ブロックの高さがautoの場合、その上部および下部の余白はとにかくゼロになります。ただし、同じフロー内に複数のブロックボックスがある場合、またはインフローボックスのレイアウトに影響するアウトフローボックスさえある場合(たとえば clearance の場合)、どのようになりますかこれらのインフローボックスの自動マージンの解決を期待していますか?

これが、インライン要素(アトミックインラインを含む)およびフロート(水平マージンは決して崩壊しない)の自動左マージンと右マージンが同様にゼロにされる理由です。インラインレベルのボックスは ラインボックスに沿って配置 であり、フロートも従います 一意のレイアウトルール

絶対的に配置されたボックスは別の話です:同じ配置コンテキスト内の他のボックスを認識することはないため、 auto top and bottom marginscan含まれるブロックに関して計算されます 他のボックスが干渉する心配はありません。

フレックスボックスもまた別の話です。フレックスレイアウトをブロックレイアウトと区別するのは、フレックスアイテムが、定義上、同じフレックスフォーマットコンテキスト内の他のフレックスアイテムを常に認識していることです。特に、 フロートはフレックスコンテナに侵入することも、フレックスアイテムをフロートさせてこれを破壊することもできません (ただし、 絶対配置 を使用すると、フレックスレイアウトから子要素を完全に削除できます=)。これに一部起因して、フレックスアイテムではマージンの動作が大きく異なります。セクション 4.29.5 および 9.6 を参照してください。

36
BoltClock

なぜ... W3C spec がそう言うからです。

「margin-top」または「margin-bottom」が「auto」の場合、使用される値は0です。

実際の「理由」については...クエリは実際に対処する必要があります。

30
Paulie_D

通常のフローではブロックレベルの要素であるため、要素を垂直方向に中央揃えしません。したがって、 次の規則が適用されます

margin-top、またはmargin-bottomautoの場合、それらの使用値は0です。

また、上記の規則は次の要素にも適用されることにも注意してください(詳細と条件については、ポイント 10.6.2 および 10.6. を参照してください)。

  • インライン置換された要素
  • 通常フローのブロックレベルの置換された要素
  • inline-blockは通常のフローの要素を置き換えました
  • 置換された要素をフローティング
  • overflowvisibleを計算する場合の通常フローのブロックレベルの非置換要素

そうは言っても、topheightbottom、およびautoの値を持たない絶対位置の非置換要素は例外です。このルール。以下は point 10.6.4 から適用されます:

3つのtopheight、およびbottomのいずれもautoでなく、margin-topmargin-bottomの両方がauto2つのマージンが等しい値になるという追加の制約の下で方程式を解きます

margin: autoを使用して、絶対に配置された要素を垂直方向に中央揃えする方法を示す以下の例を参照してください。 3つのプロパティtopheight、およびbottomのいずれにもautoの値がないため、機能します。

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
  position: relative;
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto;
  position: absolute;
  top: 0; right: 0;
  bottom: 0; left: 0;
}
<div class="box">
  <div class="center"></div>
</div>

さらに、おそらく ルールに従う も指摘する価値があります。

margin-topまたはmargin-bottomのいずれかがautoである場合、その値の方程式を解きます。値が過剰に制約されている場合、bottomの値を無視して、その値を解きます。

これは、絶対に配置された要素のmargin-top値がautoおよびmargin-bottom値が0(つまり、margin: auto auto 0)である場合、その要素は下の例のように、親に対して絶対に一番下に配置する必要があります。

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
  position: relative;
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto auto 0;
  position: absolute;
  top: 0; right: 0;
  bottom: 0; left: 0;
}
<div class="box">
  <div class="center"></div>
</div>
16
Josh Crozier

なぜmargin:autoは垂直に機能しないのですか?

実際には、すべてのdisplay値に対してではありません。

displayflexの場合、margin: autoは垂直と水平の両方に中央揃えされます。

同じことがdisplay: inline-flexdisplay: grid、およびdisplay: inline-gridにも当てはまります。

.box {
  border: 1px solid red;
  width: 100px;
  height: 100px;
  display: flex; /* new */
}
.center {
  background: blue;
  width: 50px;
  height: 50px;
  margin: auto;
}
<div class="box">
  <div class="center"></div>
</div>
14
Michael_B

これは、垂直方向の中心に配置する要素の実際の高さを実際に知ることができるためです。それを理解するには、まず、自動水平方向の中心調整の仕組みについて考えます。幅(固定またはパーセンテージ)を指定したdivがあります。幅はある程度計算できます。固定幅の場合、素晴らしい。少なくとも柔軟であるか応答性がある場合(パーセンテージ)、次のブレークポイントに達する前に幅がカバーする範囲があります。その幅から、内側の幅を差し引いて、残りを両側で分割します。

さて、その情報を使用して、ブラウザはどのようにしてdivが垂直方向に成長する無限のバリエーションを計算できますか?要素のサイズ、テキストの折り返し、パディング、および応答性も幅を変更し、テキストをさらに折り返すように強制します。

それは不可能な仕事ですか?実際、CSSはこれをカバーするのに時間と労力を費やしましたか?彼らの時間の価値はないと思う。

そして、それは基本的に私が生徒に伝える答えです。

しかし....フレットではありません! Bootstrap v4 alphaが判明 垂直方向のセンタリング

[〜#〜] edit [〜#〜]

これを遅く編集して申し訳ありませんが、このソリューションを垂直方向に中央に配置することを検討する必要があると思ったので、calc関数を使用すると非常に簡単です

<div class="foo"></div>

.foo {
  background-color: red;
  height: 6em;
  left: calc(50% - 3em);
  position: absolute;
  top: calc(50% - 3em);
  width: 6em;
}

ご覧ください [〜#〜] here [〜#〜]

3
LOTUSMS