こんにちは、フロントエンドエンジニアのコウです!
この記事はTech KAYAC Advent Calendar 201524日目です。
小テスト
問題:CSSで、灰色の円 div.circle
をラッパー div.wrapper
の中央に配置する方法は?
CSSを下のテキストエリアに書いてください。.circle
の高さと幅は 100px
です。
See the Pen center the block both vertically and horizontally by GSSxGSS (@gssxgss) on CodePen.
できましたか?
おめでとうございます〜
どの方法をつかいましたか?
それでは、様々なセンターリングの方法を見てみましょう!
(プレビューコード画面右下の"+"と"-"を何回か押してみてください)
CSSレベル1の大先輩ーーvertical-align
と text-align
vertical-align
プロパティは、インラインまたはテーブルセル要素の、縦方向の整列方法を定義します。 -- MDN
text-align
プロパティは、テキストのようなインラインコンテンツが、その親ブロックの中でどのように文字寄せされるのかを定義します。 -- MDN
vertical-alignとtext-alignはCSSレベル1のプロパティなので、IE8のような古いブラウザでも安心してセンタリングに使うことができます。
table での解決方法
.table {
display: table;
width: 100%;
height: 100%;
}
.wrapper.table-cell {
display: table-cell;
text-align: center;
vertical-align: middle;
}
.target.inline-block {
display: inline-block;
}
inline-block での解決方法
inline-block
要素を縦方向にセンタリングするためには、親要素の高さが重要です。
親要素の高さが定義されていない場合は
- 親要素に高さ100%で inline-block
の擬似要素(:before or :after)を作る
- 親要素のline-heightをheightと同じ値にする
のどちらかが必要です。
方法1 height: 100%
の擬似要素を作る
.wrapper.block {
text-align: center;
&:before {
content: "";
display: inline-block;
width: 0;
height: 100%;
vertical-align: middle;
}
}
.target.inline-block {
display: inline-block;
vertical-align: middle;
}
方法2 親要素のline-height
をheight
と同じ値にする
.wrapper.block {
text-align: center;
line-height: 465px;
}
.target.inline-block {
display: inline-block;
vertical-align: middle;
}
まとめ
inline-block
での解決方法を使うときは親要素の高さが重要です。
またこの方法はIE8でも使うことができますが、複数の子要素をセンタリングしたい場合に、
子要素の幅の合計が親要素の幅を超えると、親要素をはみ出して表示が崩れてしまうので注意が必要です(画面右下の"+"を何回か押してみてください)。
inline-block
要素はinline要素の特徴を持っているため、.target
の周りにはスペースができてしまいます。こちらも注意してみてください。
使いやすいなposition: absolute
もしセンタリングしたい要素が1つだけの場合、position: absolute
はとても便利です。
margin: auto
での解決方法
この方法でもいけますが、ある場合にバグが起きるのでお勧めはできません。
何故この方法でセンタリングできるかについては、この記事に詳しく書いてあります
.wrapper.relative {
position: relative;
}
.target.absolute {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
ネガティブ margin
での解決方法
IE8でも使うことができます。
しかし、.target
自身の高さと幅に依存するので、使うときは注意してください。
.wrapper.relative {
position: relative;
}
.target.absolute {
position: absolute;
top: 50%;
left: 50%;
margin: -50px 0 0 -50px;
}
transform
での解決方法
transformはCSSレベル3のプロパティですが、IE9以降のブラウザ全てが対応しています。
おすすめです。
.wrapper.relative {
position: relative;
}
.target.absolute {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
flexの凄さ
flex要素は、ブロック要素のようにふるまいつつ、そのコンテンツを flexbox モデルに従ってレイアウトします。 -- MDN
flexboxモデルはすごく便利です。たったの3行で子要素をセンタリングすることができます。
勿論、センタリングだけではなくflexboxモデルはとても柔軟で色々なレイアウトに適用できるので、これから是非使ってください。
flexboxは3回仕様策定(box, flexbox, flex)されていて、ベンダープレフィックスもあるため、記述が複雑になってしまいます。
なので、compassやstylusやgrunt, gulp-moduleのautoprefixerを使うとよいと思います。
興味ある方はこの記事(flexboxの旧仕様、改定仕様、現行仕様の一覧)を読んで下さい。
IEは10以降、Androidは4以降で対応していますが複数行の場合、Andoroid4.3以下(4.0~4.3)で使えません。
一行センタリング例
複数行センタリング例
.wrapper.flex {
display: flex;
align-items: center;
justify-content: center;
// 下の二行は複数行対応です。
align-content: center;
flex-wrap: wrap;
}
サイトフレックスカエルで、Flexboxモデルを簡単に勉強できます。
是非試してみてください。
最後に
まだ日本語が上手くできないので、基礎的な話をしました。
来年のAdvent Calendarでは上手に発表できるように、日本語頑張ります!
それでは、また来年のAdvent Calendarでお会いしましょう。
皆さん、メリークリスマス!