CSS Flexbox 教學:彈性盒子屬性、範例與常見問題

學會 css flexbox 的核心概念、display flex、主軸與交叉軸、justify-content、align-items、gap 與 flex 屬性用法,搭配 flexbox 教學範例、常見排版陷阱與除錯清單,判斷何時該用彈性盒子完成導覽列、卡片與表單排列。

css flexboxFlexbox 教學彈性盒子CSS 排版版面對齊

CSS Flexbox 是什麼?適合解決什麼版面問題

CSS Flexbox 是一種一維 CSS 彈性盒子版面配置,適合處理單列或單欄的排列、對齊、等高與剩餘空間分配。

它的核心是讓父層成為 flex container,直接控制子層 flex item 的排列方向與對齊方式。做導覽列、按鈕群組、表單列、卡片內部排列、垂直置中時,Flexbox 通常比手寫 float、inline-block 或複雜 margin 更穩。

Flex container / flex item

設定 display: flex 的元素就是 flex container,裡面的直接子元素就是 flex item。Flexbox 只會影響直接子層,不會自動控制孫層,這點在巢狀卡片與表單元件很常踩到。

名詞 意思 實務判斷
flex container 啟用 Flexbox 的父層 負責方向、換行、對齊、間距
flex item container 的直接子元素 負責伸展、收縮、基準尺寸、順序
一維版面 一次主要處理一個方向 導覽列、工具列、列表、卡片內排版很適合

主軸與交叉軸

主軸 main axis 是 flex item 排列的主要方向,交叉軸 cross axis 是垂直於主軸的方向。預設 flex-direction: row 時,主軸是水平,交叉軸是垂直。

設定 主軸 main axis 交叉軸 cross axis
row 左到右 上到下
column 上到下 左到右

Flexbox 基本寫法:display flex 後發生什麼事

父層設定 display: flex 後,直接子元素會沿主軸排列,並開始接受 Flexbox 的對齊與尺寸分配規則。

display: flex

display: flex 會讓元素本身仍像 block 一樣佔滿可用寬度,但內部子項目改由 Flexbox 排列。我的習慣是先只開 display: flex,確認子項目排列方向,再逐步加 gap、align-items、flex,除錯會乾淨很多。

display: inline-flex

display: inline-flex 讓容器本身像 inline 元素一樣依內容寬度收合,但內部仍使用 Flexbox。適合標籤、膠囊按鈕、小型 icon 加文字元件。

最小 HTML/CSS 範例

<div class="toolbar">
  <button>儲存</button>
  <button>預覽</button>
  <button>發布</button>
</div>

.toolbar { display: flex; gap: 12px; align-items: center; }

.tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
}

Flex container 屬性怎麼用

Flex container 屬性負責決定 flex item 的排列方向、是否換行,以及主軸與交叉軸上的空間分配。

主軸方向

flex-direction 決定主軸方向。導覽列多半用 row,側邊選單或卡片內文字堆疊常用 column。

屬性值 效果 常見用途
row 水平排列 navbar、工具列、表單列
column 垂直排列 卡片內容、側欄區塊、整頁框架
row-reverse 水平反向 少量視覺微調
column-reverse 垂直反向 少用,需注意閱讀順序

是否換行

flex-wrap 控制項目超出容器時要擠在同一行,或換到下一行。卡片列表、標籤列表通常要加 flex-wrap: wrap,不然容易撐出橫向捲動。

shorthand

flex-flow 是 flex-direction 與 flex-wrap 的縮寫。團隊專案裡,若新手多,我會拆開寫;若是局部元件樣式,flex-flow 可以讓規則更短。

.cards {
  display: flex;
  flex-flow: row wrap;
  gap: 16px;
}

Flexbox 對齊屬性:justify-content、align-items、align-content

justify-content 管主軸對齊,align-items 管交叉軸對齊,align-content 只在多行 flex 內容時明顯生效。

主軸對齊

justify-content 分配主軸上的剩餘空間。若主軸是水平,它看起來像在控制水平對齊;若主軸改成 column,它就會變成控制垂直方向。

交叉軸對齊

align-items 控制每一行 item 在交叉軸上的對齊方式。做按鈕 icon 對齊、表單 label 對齊、卡片內容置中時,它比手動調 padding 更穩。

多行對齊

align-content 只有在 flex-wrap: wrap 且容器交叉軸還有額外空間時才有感。很多人以為它壞掉,其實是內容只有一行,或容器高度沒有多餘空間。

屬性 控制方向 常用值 常見誤會
justify-content 主軸 center、space-between 不一定是水平,要看 flex-direction
align-items 交叉軸 center、stretch 不一定是垂直,要看主軸方向
align-content 多行的交叉軸空間 center、space-between 單行通常看不出效果

水平垂直置中

.center-box {
  min-height: 240px;
  display: flex;
  justify-content: center;
  align-items: center;
}

Flex item 屬性:grow、shrink、basis、flex

Flex item 屬性決定子項目的伸展、收縮與基準尺寸,是 css flexbox 能處理等寬、等高、剩餘空間分配的關鍵。

flex-grow

flex-grow 控制有剩餘空間時,item 要不要放大。值是比例,不是像素。兩個 item 分別設 1 和 2,代表後者分到的剩餘空間比例較高。

flex-shrink

flex-shrink 控制空間不足時,item 要不要縮小。預設通常會縮,但內容本身有最小寬度時,還是可能把容器撐爆,這也是 min-width: 0 會出場的原因。

flex-basis

flex-basis 是 item 進入彈性分配前的基準尺寸。主軸是水平時,它接近寬度概念;主軸是垂直時,它接近高度概念。

flex shorthand

flex 是 flex-grow、flex-shrink、flex-basis 的縮寫。實務上最常見的是 flex: 1、flex: 0 0 auto、flex: 1 1 240px。

寫法 常見含意 適合場景
flex: 1 可伸展、可收縮,基準接近 0 等分剩餘空間
flex: 0 0 auto 不伸展、不收縮,依內容或尺寸 固定寬度按鈕、側邊小區塊
flex: 1 1 240px 以 240px 為基準,可伸縮 RWD 卡片列表

flex: 1 實際代表什麼

flex: 1 不等於任何情況都平均寬度。內容長度、min-width、padding、gap、容器寬度都會影響最後結果。要做可預期的卡片寬度,我偏好寫出基準值。

.layout {
  display: flex;
  gap: 16px;
}

.main { flex: 1 1 0; min-width: 0; }

.sidebar { flex: 0 0 280px; }

Flexbox 常見版面範例與可複製寫法

Flexbox 最適合拿來做導覽列、卡片列表、表單列、media object 與 sticky footer,因為這些版面主要都在解決單一方向的排列。

navbar

導覽列通常需要左側品牌、右側選單,中間用剩餘空間推開。這種一列式排列是 Flexbox 的強項。

<nav class="nav">
  <a class="brand" href="/">Make Websites</a>
  <div class="nav-links">
    <a href="/posts">文章</a>
    <a href="/about">關於</a>
  </div>
</nav>

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

.nav-links { display: flex; gap: 16px; }

card list

卡片列表可以用 Flexbox 做可換行排列。若需要嚴格控制欄與列,後面會看到 Grid 更適合;若只是內容流式排列,Flexbox 夠用。

.post-list {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.post-card { flex: 1 1 260px; min-width: 0; }

form row

表單列常見需求是 label 固定寬度、輸入框吃剩餘空間。這時不用手算寬度,讓 input 區塊 flex: 1 即可。

.form-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

.form-row label { flex: 0 0 96px; }

.form-row input { flex: 1 1 auto; min-width: 0; }

media object

頭像加文字、縮圖加摘要、作者資訊列都屬於 media object。圖片固定,文字區吃剩餘空間,並補上 min-width: 0 防止長標題爆版。

.media {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}

.media-thumb { flex: 0 0 64px; }

.media-body { flex: 1 1 auto; min-width: 0; }

sticky footer

整頁 sticky footer 可以用垂直 Flexbox:頁面容器吃滿視窗高度,主要內容 flex: 1,footer 自然被推到底。

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

.page-main { flex: 1 1 auto; }

Flexbox 常見錯誤與修正流程

Flexbox 爆版、對不齊、截斷失敗,多半不是屬性失效,而是主軸判斷、item 最小尺寸、換行條件或 overflow 沒處理好。

文字不截斷

在 flex item 裡做單行省略時,只寫 overflow: hidden 不一定成功。若 item 的預設最小寬度被內容撐開,必須在可收縮的 flex item 上加 min-width: 0。

.title-wrap {
  flex: 1 1 auto;
  min-width: 0;
}

.title { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }

子項目不縮

子項目不縮通常和 flex-basis、min-width、長字串、固定寬度有關。先查 item 是否有 width、min-width 或不可斷行內容,再調整 flex-shrink。

間距不如預期

gap 是 item 之間的距離,不是容器外距。若同時用了 justify-content: space-between 和 gap,空間會一起參與分配,視覺間距可能比預期大。

DevTools 檢查順序

除錯時先看父層是否真的成為 flex container,再看主軸方向、是否換行、gap、item 的 grow/shrink/basis,最後才看內容本身是否有長字串或固定尺寸。這個順序比隨機改 CSS 快很多。

問題 常見原因 修正方向
長標題撐爆卡片 flex item 沒有 min-width: 0 在文字外層 item 加 min-width: 0
卡片沒有換行 container 少了 flex-wrap 加 flex-wrap: wrap 與合理 flex-basis
垂直置中失敗 主軸方向判斷錯或容器沒有高度 確認 flex-direction 與容器高度
間距過大 gap 與 space-between 疊加 優先保留其中一種空間策略

Flexbox 和 CSS Grid 怎麼選

Flexbox 適合一維版面,CSS Grid 適合二維版面;只排一列或一欄先用 Flexbox,同時控制欄與列通常先選 Grid。

決策表

需求 優先選擇 原因
導覽列、按鈕列、工具列 Flexbox 主要處理水平排列與剩餘空間
卡片內的標題、摘要、按鈕 Flexbox 單一方向堆疊與推底很方便
整齊的多欄多列卡片牆 CSS Grid 需要同時控制欄與列
頁面主欄、側欄、內容區 Grid 或混用 外層用 Grid,內部元件用 Flexbox

常見混用方式

我在 production 專案裡最常用的做法是外層 Grid、內層 Flexbox。Grid 負責頁面區塊,Flexbox 負責元件內部對齊,例如卡片內的標籤、作者列、按鈕列。

卡片列表用哪個

如果卡片只是依容器寬度自然換行,Flexbox 可以處理。若需要每列欄寬一致、列高規律、空位也要對齊,CSS Grid 會更可控。

order、視覺順序與無障礙注意事項

order 只改變 Flexbox 的視覺排列,不會改變 DOM 順序;過度使用會影響鍵盤操作與螢幕閱讀器理解。

order 改了什麼

order 讓 flex item 在畫面上的順序改變,但 HTML 原始順序仍然存在。搜尋引擎、鍵盤焦點、螢幕閱讀器通常仍會受到 DOM 順序影響。

什麼情況不要用

不要用 order 重新安排文章標題、主要內容、表單步驟、購買流程這類有語意順序的內容。我不建議把 order 當手機版重排的主要工具,除非只是很小的裝飾性區塊。

替代做法

優先調整 HTML 結構,讓 DOM 順序本身符合閱讀順序。需要 RWD 視覺變化時,可用 Grid template、不同容器結構,或在內容策略上重新安排區塊,而不是硬靠 order 補救。

2026 年使用 Flexbox 還需要注意什麼

2026 年寫 Flexbox 的重點不是 vendor prefix,而是善用 gap、搭配 container queries,並清楚決定何時與 Grid 混用。

gap 在 Flexbox 的使用

gap 已經是 Flexbox 排列間距的主流寫法。相較於替每個 item 寫 margin,gap 不會產生第一個或最後一個元素多餘外距,元件可搬移性也更好。

.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 12px;
}

RWD 與 container queries

RWD 不一定只看 viewport。元件放在側欄、主內容、彈窗時,可用 container queries 依父容器寬度調整 Flexbox 方向。這比只依螢幕寬度切換更貼近元件實際空間。

.profile-card {
  container-type: inline-size;
}

.profile-inner { display: flex; gap: 16px; }

@container (max-width: 360px) { .profile-inner { flex-direction: column; } }

是否還需要 prefix

一般現代網站不需要把舊版 Flexbox prefix 當主軸維護。若專案仍支援非常舊的瀏覽器,再交給建置工具處理相容性;手寫多套舊語法容易讓樣式變難讀。

結論:Flexbox 的學習順序與實作檢查表

學 Flexbox 先掌握 container、item、主軸、交叉軸,再練對齊、尺寸分配、換行與除錯,比背完整屬性字典有效。

先學哪些屬性

學習順序可以從 display: flex、flex-direction、gap、justify-content、align-items 開始,再補 flex-wrap、flex、flex-basis、min-width: 0。這些已足以處理多數切版工作。

切版前檢查

檢查項目 判斷問題 建議做法
版面是一維還是二維 只排一列或一欄嗎 一維優先 Flexbox,二維優先 Grid
主軸方向 item 是水平還是垂直排列 先設定 flex-direction
是否需要換行 窄版會不會爆出容器 列表加 flex-wrap: wrap
內容是否會截斷 長標題、網址、英文單字是否撐開 可收縮 item 加 min-width: 0
順序是否有語意 鍵盤與閱讀順序是否重要 少用 order 重排主要內容

CSS Flexbox 是什麼?

CSS Flexbox 是 CSS 的一維彈性盒子版面配置模型,主要用來處理單列或單欄的排列、對齊與剩餘空間分配。父層設定 display: flex 後,直接子元素就會變成 flex item。

Flexbox 和 Grid 差在哪裡?

Flexbox 主要處理一維版面,例如一列導覽或一欄卡片內容。CSS Grid 主要處理二維版面,例如同時控制欄與列的頁面框架或卡片牆。實務上常見做法是外層用 Grid,元件內部用 Flexbox。

justify-content 和 align-items 有什麼不同?

justify-content 控制主軸 main axis 上的對齊與空間分配,align-items 控制交叉軸 cross axis 上的對齊。方向要看 flex-direction,不一定永遠是水平或垂直。

為什麼 Flexbox 垂直置中沒有成功?

常見原因是容器沒有高度、主軸方向判斷錯,或置中屬性下在錯的元素上。若使用預設 flex-direction: row,垂直置中通常要在 flex container 設定 align-items: center,並確認容器有可對齊的高度。

flex: 1 是什麼意思?

flex: 1 是 flex-grow、flex-shrink、flex-basis 的縮寫,通常表示 item 可以伸展、可以收縮,並參與剩餘空間分配。它不保證任何情況都平均寬度,內容最小尺寸仍會影響結果。

flex-basis 和 width 差在哪裡?

flex-basis 是 Flexbox 計算彈性分配前的主軸基準尺寸;width 是一般 CSS 寬度。主軸為水平時兩者感覺相近,但在彈性分配、收縮、伸展時,flex-basis 更直接參與 Flexbox 計算。

Flex item 為什麼會爆版或不縮小?

常見原因是 item 內容有不可斷行文字、固定寬度、過大的 min-width,或 flex-shrink 沒有發揮作用。處理文字與卡片內容時,通常要在可收縮的 flex item 上加 min-width: 0。

什麼時候要加 min-width: 0?

當 flex item 裡有長標題、網址、單行省略、卡片摘要,並且內容撐開容器時,就該檢查 min-width: 0。它通常加在文字外層的 flex item,不是加在最外層 container。

gap 可以用在 Flexbox 嗎?

可以。gap 很適合用在 Flexbox 的 item 間距,尤其是導覽列、按鈕列、卡片列表與標籤列表。它比替每個 item 寫 margin 更乾淨,也比較不會產生首尾多餘外距。

order 會影響 SEO 或無障礙嗎?

order 只改視覺順序,不改 DOM 順序。若拿來重排主要內容,可能讓鍵盤焦點、螢幕閱讀器順序與畫面不一致。SEO 也應以清楚的 HTML 語意順序為基礎,不建議用 order 補救內容結構問題。

Flexbox 適合做整頁 layout 嗎?

可以做簡單整頁版面,例如 sticky footer 或單欄頁面框架。但若頁面需要同時控制主欄、側欄、多列區塊與欄寬,CSS Grid 通常更適合。Flexbox 比較適合放在元件內部處理排列與對齊。

2026 年寫 Flexbox 還需要加瀏覽器前綴嗎?

一般現代網站不需要手寫舊版 Flexbox 前綴。若專案有特殊舊瀏覽器支援需求,交給建置工具依瀏覽器支援清單處理,比在原始碼中手寫多套舊語法更穩。