土薯工具 Toolshu.com 登錄 用戶注冊

CSS flex 佈局裏,justify-content 和 align-items 爲什麼老是記混?

作者:bhnw 於 2026-05-22 16:52 發佈 6次瀏覽 收藏 (0)

flex 佈局用了這麼多年,justify-contentalign-items 還是有人老是記混。不是因爲笨,是因爲這兩個屬性的行爲會隨 flex-direction 變化,記住"橫向縱向"沒用,下次換了方向又亂了。

這篇文章從主軸和交叉軸的概念出發,講清楚爲什麼記混、怎麼記對,以及幾個常見場景的寫法。


先搞清楚一件事:軸的方向不是固定的

很多人背的是"justify-content 控制水平方向,align-items 控制垂直方向"。這句話在默認情況下是對的,但只要 flex-direction 改了,這句話就錯了。

準確的描述是:

  • justify-content:控制主軸方向的對齊
  • align-items:控制交叉軸方向的對齊

主軸是什麼?就是 flex-direction 指定的方向:

flex-direction: row;         /* 主軸是水平方向(默認) */
flex-direction: row-reverse; /* 主軸是水平方向,但從右往左 */
flex-direction: column;      /* 主軸是垂直方向 */
flex-direction: column-reverse; /* 主軸是垂直方向,但從下往上 */

交叉軸永遠和主軸垂直。主軸是水平的,交叉軸就是垂直的;主軸是垂直的,交叉軸就是水平的。

所以當你把 flex-direction 改成 column,兩個屬性的效果就完全反過來了:

/* flex-direction: row(默認) */
.container {
  display: flex;
  justify-content: center;  /* 水平居中 */
  align-items: center;      /* 垂直居中 */
}

/* flex-direction: column */
.container {
  display: flex;
  flex-direction: column;
  justify-content: center;  /* 垂直居中! */
  align-items: center;      /* 水平居中! */
}

記這個最簡單的方式:justify 跟着主軸走,align 跟着交叉軸走,主軸在哪 justify 就控制哪個方向。


垂直居中,爲什麼有時候不生效?

這是最常見的問題。寫了 align-items: center,元素就是不居中。

原因幾乎只有一個:容器沒有高度,或者高度不夠。

align-items 控制的是元素在交叉軸上的位置,但如果容器本身沒有指定高度,它的高度就等於子元素的高度,根本沒有多餘的空間,居中也就無從談起。

/* 不生效:容器高度就是內容高度,沒有空間居中 */
.container {
  display: flex;
  align-items: center;
}

/* 生效:給容器一個高度 */
.container {
  display: flex;
  align-items: center;
  height: 300px; /* 或者 min-height,或者 100vh */
}

做全屏垂直居中:

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

space-between、space-around、space-evenly 有什麼區別?

這三個值都是 justify-content 的選項,都是把剩餘空間分配給間距,但分配方式不同。

假設容器裏有三個元素,用示意圖來看:

space-between:  |A    B    C|   首尾元素貼邊,間距在中間平均分
space-around:   | A   B   C |   每個元素兩側各有等量空間(首尾是內部間距的一半)
space-evenly:   |  A   B   C  | 所有間距完全相等,包括首尾

實際寫代碼時:

/* 導航欄:logo 在左,鏈接在右 */
.nav {
  display: flex;
  justify-content: space-between;
}

/* 卡片列表:卡片之間和兩側都有間距 */
.cards {
  display: flex;
  justify-content: space-evenly;
}

不過現在更推薦直接用 gap 來控制間距,而不是依賴 justify-content 的 space 系列值,因爲 gap 更直觀,而且在換行時行爲也更符合預期:

.container {
  display: flex;
  flex-wrap: wrap;
  gap: 16px; /* 元素之間的間距,首尾不加 */
}

align-items 和 align-content 的區別

這也是常見的困惑點。

  • align-items:控制每一行內部,子元素在交叉軸上的對齊方式
  • align-content:控制多行在容器交叉軸上整體的分佈方式,只有在 flex-wrap: wrap 且實際發生了換行時纔有效果
/* 只有一行內容時,align-content 沒有效果 */
.container {
  display: flex;
  align-items: center;    /* 這行有效:控制行內對齊 */
  align-content: center;  /* 這行無效:只有一行,沒有多行分佈可言 */
}

/* 多行時,兩個屬性同時發揮作用 */
.container {
  display: flex;
  flex-wrap: wrap;
  height: 400px;
  align-items: flex-start;   /* 每行內部:頂部對齊 */
  align-content: space-between; /* 多行之間:兩端對齊 */
}

記憶方式:items 管的是行內的事,content 管的是行與行之間的事。


幾個常見佈局的寫法

水平垂直居中(最常用)

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

導航欄:左邊 logo,右邊按鈕

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

把最後一個元素推到最右邊

.nav {
  display: flex;
  align-items: center;
}

.nav .last-item {
  margin-left: auto; /* auto margin 會吃掉所有剩餘空間 */
}

等高卡片列表

.cards {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  align-items: stretch; /* 默認值,子元素自動拉伸到等高 */
}

豎向排列,水平居中

.container {
  display: flex;
  flex-direction: column;
  align-items: center; /* 注意:column 時,align-items 控制水平方向 */
}

想直接驗證這些佈局效果,把 HTML 和 CSS 粘到 HTML 在線編輯器 裏實時預覽,改一個屬性馬上看到變化,比在本地建文件測試快多了。

发现周边 发现周边
評論區

加載中...