目次
- はじめに|縦中央が決まらないと、地味に心が折れる
- CSSで縦中央とは(スニペット用の一文)
- まず結論|迷ったらこの形(ほぼ勝ちパターン)
- 縦中央が難しい理由|縦だけは“基準の高さ”が必要
- よくある原因① 親要素に高さがない(最頻出)
- なぜ縦中央にならない?
- 解決方法(よくある2パターン)
- よくある原因② justify-content と align-items を混同している
- 縦中央にしたいなら?
- よくある原因③ flex-direction: column で軸が入れ替わっている
- よくある原因④ align-itemsを“子要素”に書いている
- よくある原因⑤ height: 100% が効かない(100vhにすべき?問題)
- なぜ効かない?
- よくある原因⑥ line-heightで縦中央にしようとして崩れる
- これはいつ使う?
- なぜ危ない?
- Flexboxで縦中央の基本形(用途別)
- 1)縦だけ中央(横はそのまま)
- 2)縦横どちらも中央(定番)
- 3)縦並び(column)で縦横中央
- positionで縦中央にする方法(Flexboxが使えない・重ねたい時)
- 定番:top:50% + translateY(-50%)
- 縦横どっちも中央にするなら
- ここでハマりやすい点
- table-cellで縦中央(非推奨だけど、見ることはある)
- DevToolsで“効いてない理由”を特定する手順(差別化ポイント)
- 手順(Chrome)
- よくある“見つけ方”
- スマホ崩れ・横スクロール問題につながる縦中央の罠
- 1)100vhがスマホで微妙にズレる
- 2)positionで外に押し出して横スクロール
- 縦中央できないときのチェックリスト(保存用)
- よくある質問
- 縦中央はFlexboxとpositionどっちがいい?
- 高さを100%にしても効きません
- まとめ|縦中央が効かない原因は“プロパティ”より“基準の高さ”が多い
はじめに|縦中央が決まらないと、地味に心が折れる
CSSでレイアウトを調整していると、だいたい一度はこれに当たります。
- 横は中央なのに、縦だけ合わない
align-items: center;を書いたのに効かない- コピペしたコードがなぜか動かない
- なんとか揃えたら、スマホで崩れた
私も昔、ボタンを縦中央に置きたくてFlexboxを入れたのに全然効かず、
「え、これで合うって記事に書いてたのに…」と詰みました。
原因は単純で、親要素の高さがゼロに近かっただけでした。DevToolsで見たら一瞬。
この記事は「css 縦中央 できない」で検索してきた人が、“効かない理由を自分で特定して直せる”ようになるための実務ガイドです。
Flexbox・position別に、よくあるハマりを全部つぶしていきます。
CSSで縦中央とは(スニペット用の一文)
CSSで縦中央にするとは、要素を「親要素の高さ」を基準にして上下の余白を均等にし、中央位置に配置することです。
ここで大事なのは「高さが基準」という部分です。
縦方向は、高さが決まらないと“中央”が作れません。
まず結論|迷ったらこの形(ほぼ勝ちパターン)
画面いっぱいのエリアで中央にしたいなら、まずこれでOKです。
.container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
height ではなく min-height にしているのが地味に効きます。
中身が増えても潰れにくいからです。
縦中央が難しい理由|縦だけは“基準の高さ”が必要
横中央は、親の幅がほぼ常にあります。
でも縦は、親の高さが「中身に合わせて伸びる」ことが多いです。
つまり、親の高さが決まっていないとこうなります。
- 高さが中身と同じ
- 中央を計算しても、結局その場から動かない
align-itemsを書いても“効いてないように見える”
縦中央は、プロパティの暗記より「高さがあるか?」で勝負が決まります。
よくある原因① 親要素に高さがない(最頻出)
.container {
display: flex;
align-items: center;
}
なぜ縦中央にならない?
親要素の高さが中身と同じだと、縦の余白が生まれません。
余白がないので、中央も作れません。
解決方法(よくある2パターン)
画面いっぱいのエリアなら 100vh
.container {
display: flex;
align-items: center;
height: 100vh;
}
中身が増える可能性があるなら min-height
.container {
display: flex;
align-items: center;
min-height: 100vh;
}
実務では min-height の方が事故りにくいです。
あとで文章が増えても、潰れません。
よくある原因② justify-content と align-items を混同している
Flexboxは「軸」で考えると一気に楽になります。
- justify-content:主軸(メインの並び方向)
- align-items:交差軸(主軸と直交する方向)
初期状態(flex-direction: row;)なら主軸は横です。
.container {
display: flex;
justify-content: center; /* 横中央 */
}
縦中央にしたいなら?
.container {
display: flex;
align-items: center; /* 縦中央 */
}
横も縦も中央ならこの定番です。
.container {
display: flex;
justify-content: center;
align-items: center;
}
よくある原因③ flex-direction: column で軸が入れ替わっている
flex-direction を変えると、主軸が入れ替わります。
.container {
display: flex;
flex-direction: column;
}
この場合、主軸は縦です。
- 縦中央:justify-content
- 横中央:align-items
.container {
display: flex;
flex-direction: column;
justify-content: center; /* 縦中央 */
align-items: center; /* 横中央 */
}
「前は効いてたのに、急に効かなくなった」時は、
どこかで flex-direction を変えてるケースが多いです。
よくある原因④ align-itemsを“子要素”に書いている
Flexboxの指定は、基本的に親に書きます。
よくある間違いがこれです。
.item {
align-items: center; /* 効かない */
}
正しくはこれ。
.container {
display: flex;
align-items: center;
}
「親か子か」で迷ったら、まず親を疑うのが早いです。
よくある原因⑤ height: 100% が効かない(100vhにすべき?問題)
これも検索されがちです。
.container {
height: 100%;
}
なぜ効かない?
100% は「親の高さ」を基準にします。
親の高さが未指定だと、計算できません。
なので、100% を使うなら階層ごとに高さが必要です。
html, body {
height: 100%;
}
.container {
height: 100%;
}
ただ、実務ではここまでやるより 100vh の方が楽な場面が多いです。
よくある原因⑥ line-heightで縦中央にしようとして崩れる
.text {
line-height: 200px;
}
これはいつ使う?
1行のテキストだけならアリです。
例えば「ボタン内の文字を縦中央に見せたい」みたいな時。
なぜ危ない?
- 2行になった瞬間に破綻する
- レスポンシブで高さが変わると合わない
- 文字サイズ変更で崩れる
「ボタンが2行になる可能性がある」なら、line-height頼みはやめた方が安全です。
Flexboxで縦中央の基本形(用途別)
1)縦だけ中央(横はそのまま)
.container {
display: flex;
align-items: center;
min-height: 100vh;
}
2)縦横どちらも中央(定番)
.container {
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
}
3)縦並び(column)で縦横中央
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 100vh;
}
positionで縦中央にする方法(Flexboxが使えない・重ねたい時)
Flexboxが使えないというより、重ねるUIだとpositionが便利です。
バッジ、ローディング、モーダル中央など。
定番:top:50% + translateY(-50%)
.parent {
position: relative;
}
.box {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
縦横どっちも中央にするなら
.parent {
position: relative;
}
.box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
ここでハマりやすい点
- 親に
position: relative;がないと基準がズレる transformの影響でz-indexが思った通りにならないことがある- 文字量が増えると見た目の中心がズレたように感じる(視覚中心の問題)
「きっちり中央」は取れていても、
見た目がズレて感じるケースがあるのがposition系の難しさです。
table-cellで縦中央(非推奨だけど、見ることはある)
.container {
display: table-cell;
vertical-align: middle;
}
古い実装で残っていることがあります。
新規で組むならFlexboxでOKです。
DevToolsで“効いてない理由”を特定する手順(差別化ポイント)
縦中央が効かない時、勘で直すと遠回りになりがちです。
DevToolsで「親の高さ」と「適用されてるCSS」を見れば早いです。
手順(Chrome)
- 縦中央にしたい要素を右クリック → 検証
- 親要素(container)を選ぶ
- Styles で
display: flexが付いているか確認 - Computed で
height(またはmin-height)がいくつになっているか確認 align-itemsが打ち消し線になってないか確認(上書きされてる可能性)- Layoutパネル(Flexの可視化)で、Flexが効いてるかを見る
よくある“見つけ方”
- Computedのheightが
0に近い → 高さ問題 display: blockになってる → flexがそもそも入ってないalign-itemsに打ち消し線 → どこか別のCSSが勝ってる
「原因が何か」を切り分けるだけで、解決が速くなります。
スマホ崩れ・横スクロール問題につながる縦中央の罠
縦中央のつもりが、スマホで崩れるパターンもあります。
1)100vhがスマホで微妙にズレる
スマホはアドレスバーの表示でviewportの高さが変わることがあります。
「ちょっと上下が切れる」「中央がズレる」みたいな現象が出ることもあります。
まずは min-height: 100vh; で様子を見るのが無難です。
ピタッと詰めすぎない方が安全です。
2)positionで外に押し出して横スクロール
left: 50% + transform は基本大丈夫ですが、
別の指定ではみ出すと横スクロールが出ます。
「スマホで横にスーッと動く」時は、
position要素が画面外へ出てないか疑ってください。
縦中央できないときのチェックリスト(保存用)
- 親要素に高さ(height / min-height)はある?
- Flexboxの指定は親に書いてる?
justify-contentとalign-itemsを混同してない?flex-directionは row / column どっち?height: 100%を使ってるなら、親の高さは指定されてる?- positionなら、親に
position: relative;はある? - DevToolsで
display: flexとComputed heightを見た? - スマホで崩れるなら、100vhの影響を疑った?
よくある質問
縦中央はFlexboxとpositionどっちがいい?
普通のレイアウトならFlexboxが楽です。
重ねるUI(モーダル・バッジ・ローディング)ならpositionが便利です。
高さを100%にしても効きません
100% は親の高さが必要です。
親の高さが未指定なら、100vh の方が手早く解決できます。
まとめ|縦中央が効かない原因は“プロパティ”より“基準の高さ”が多い
CSSで縦中央にできない原因は、たいてい次のどれかです。
- 親要素の高さがない(中央が作れない)
- Flexboxの軸(justify/align)を混同している
- flex-directionで軸が入れ替わっている
- 指定する場所(親/子)を間違えている
- positionの基準(relative)が抜けている
「css 縦中央 できない」で検索した方は、まず 親要素に高さがあるか を見てください。
そこがクリアできると、縦中央は急に簡単になります。