まだ中央寄せで
消耗してるの?

〜天下一縦横中央寄せCSS決定戦〜

2015.12.15 @yoshiko_pg

自己紹介

よしこ @yoshiko_pg

Frontend engineer at

背景:プログラミング言語チェックシートメーカー

HTML5/CSS3 モダンコーディング という本を出しました

HTML5/CSS3 モダンコーディング

好評発売中!電子版もあるよ!

質問です

CSSで縦横中央寄せする方法を
検索したことがある人?

結構色々でてくるんですよね

  • margin: auto; ?
  • display: table-cell; ?
  • flexbox ?

なぜそうなるのかわからずに
コピペしてる場合もあるかも・・・?

ここらでそろそろ決着をつけようぜ

今日話すこと

それぞれのメリット・デメリットを知ることで
あなた好みのベストプラクティスを心のなかに

HTML

<div class="outer">
  <div class="inner">
    ほげほげほげほげ
    <br>
    ふがふが
  </div>
</div>

outerの中でinnerを縦横中央寄せしたい!

エントリーナンバー 1番

absolute + negative margin

absolute + negative margin

.outer {
  position: relative; /* or absolute, fixed */
}
.inner {
  width: 200px;
  height: 200px;
  position: absolute;
  left: 50%;
  top: 50%;
  margin-left: -100px; /* width / 2 */
  margin-top: -100px; /* height / 2 */
}

position: absolute; top: 50%; left: 50%;

ほげほげほげほげ
ふがふが

margin-left: -100px;

ほげほげほげほげ
ふがふが

margin-top: -100px;

ほげほげほげほげ
ふがふが

メリット

デメリット

エントリーナンバー 2番

absolute + transform

absolute + transform

.outer {
  position: relative; /* or absolute, fixed */
}
.inner {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

position: absolute; top: 50%; left: 50%;

ほげほげほげほげ
ふがふが

transform: translate(-50%, -50%);

ほげほげほげほげ
ふがふが

メリット

デメリット

追記

これ認識してませんでした、めっちゃ役立ちました!

エントリーナンバー 3番

absolute + offsets + margin auto

a.k.a "TRBL" method

absolute + offsets + margin auto

.outer {
  position: relative; /* or absolute, fixed */
}
.inner {
  width: 200px;
  height: 200px;
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  margin: auto;
}

なんでこうなるの?

W3C Visual formatting model details
10.3.7 Absolutely positioned, non-replaced elements
 
日本語訳:視覚整形モデル詳細
10.3.7 絶対配置される非置換要素の場合

'left' + 'margin-left' + 'border-left-width' + 'padding-left'
+ 'width' + 'padding-right' + 'border-right-width'
+ 'margin-right' + 'right' = width of containing block

'left'、'width'、'right'の3つすべてが'auto'である場合:(省略)

この3つが'auto'でない場合:'margin-left'および'margin-right'の両方が'auto'である場合、2つのマージンが等しい値を得る追加条件の下で式を解く。

left、width、rightがすべてauto以外で、margin-leftとmargin-rightの両方がautoの場合は両側のmarginが同じ幅になる!→コンテンツが中央に配置される!
縦方向についても同様です。

top, right, bottom, leftに0を指定していた理由:
値を初期値のauto以外の何かにする必要があった!
(なので対になる値が等しければ0以外でもOK)

メリット

デメリット

エントリーナンバー 4番

table-cell + text-align + vertical-align

<div class="outer">
  <div class="cell">
    <div class="inner">ほげほげほげほげ<br>ふがふが</div>
  </div>
</div>

table-cell + text-align + vertical-align

.outer {
  display: table;
}
.cell {
  display: table-cell;
  vertical-align: middle;
  text-align: center;
}
.inner {
  display: inline-block; /* or width & margin: auto; */
}

メリット

デメリット

エントリーナンバー 5番

flex

flex

.outer {
  display: flex;
  justify-content: center;
  align-items: center;
}

メリット

デメリット

対応ブラウザ表

IE10は古い仕様(-ms-flexbox)なので何かしらの変換ツールをかませる必要がある。仕様の遷移
IE11は一応いけることになってるけどcan i useのknown issuesだけでもそこそこある・・・

まとめ

比較表

negative margin transform offsets + auto table-cell flex
.outerサイズ可変
.innerサイズ可変
.outerが.innerの
大きさを下回る
不可能
その他 .innerのサイズが
marginの値に影響
対応ブラウザと
Offsetの値に注意
要素3つ モダンブラウザのみ

私はモダンブラウザならflex、それ以外をサポートする必要があるならtransformで書いてます。

中央寄せで消耗しない
2016年を迎えましょう!

Goodpatchでは中央寄せに消耗しない
フロントエンドエンジニアを募集しています

www.wantedly.com/projects/16402

1月から新フロア増床!オフィスにあそびにきてね!

学生さん向けに冬のインターンもやります!

Thank you

@yoshiko_pg

おまけ

inline-blockな要素の中で
テキストを縦横中央寄せしたいとき

heightと同じ高さをline-heightに指定すると楽

.button {
  width: 200px;
  height: 70px;
  line-height: 70px; /* 縦方向 */
  text-align: center; /* 横方向 */
}

複数行は不可。ボタンとかで便利

Page 1 of 40