Contents

flex 重直置中 內容大於畫面,上面被截掉解決方法

在使用 Flexbox 做垂直置中時,如果容器設定了 align-items: center,當內容高度超過視窗高度,捲動後會發現上方的內容被截掉,無法捲到最頂端。這是 Flexbox 規格的一個常見陷阱。

問題原因

當容器設定如下:

1
2
3
4
5
6
.container {
  display: flex;
  align-items: center;        /* 垂直置中 */
  justify-content: center;    /* 水平置中 */
  min-height: 100vh;
}

align-items: center 的行為是將子元素對齊到容器的中心點。當內容高度超過視窗時,容器雖然能捲動,但子元素的「中心」被固定在容器中央計算,導致超出視窗頂部的部分永遠捲不到,因為瀏覽器的捲軸 overflow 不會往負值方向捲動。

解決方法一:改用 align-items: flex-start(最直接)

align-items: center 改為 flex-start,元素從頂部對齊,搭配 margin: auto 達到置中效果:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
.container {
  display: flex;
  align-items: flex-start;    /* 改這裡 */
  justify-content: center;
  min-height: 100vh;
}

.content {
  margin: auto;               /* 讓子元素自行置中 */
}

解決方法二:子項目使用 margin: auto

Flexbox 中,margin: auto 會自動吸收容器的剩餘空間,達到置中效果,且不會有截斷問題:

1
2
3
4
5
6
7
8
.container {
  display: flex;
  min-height: 100vh;
}

.content {
  margin: auto;    /* 上下左右都置中 */
}

這個方法非常簡潔,也是最推薦的做法之一。

解決方法三:加上 overflow: auto

在容器上加上 overflow: auto,讓容器本身可捲動:

1
2
3
4
5
6
7
.container {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  overflow: auto;    /* 加這行 */
}

但這個方法有時會讓捲軸出現在容器上而不是頁面,視布局情況判斷是否適合。

解決方法四:safe 關鍵字(現代瀏覽器)

CSS Flexbox 規格新增了 safe 關鍵字,在內容溢出時自動切換為 flex-start

1
2
3
4
5
.container {
  display: flex;
  align-items: safe center;
  justify-content: safe center;
}

目前主流瀏覽器(Chrome、Firefox)已支援,但舊版瀏覽器不支援,需確認相容性需求。

常用的全頁垂直置中布局

結合以上技巧,推薦的全頁垂直置中寫法:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
body {
  margin: 0;
}

.page-wrapper {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.main-content {
  flex: 1;                /* 佔滿剩餘空間 */
  display: flex;
  align-items: center;
  justify-content: center;
}

搭配 flex-direction: columnflex: 1,讓主內容區域自動撐滿整頁,也避免截斷問題。

參考資料