TailwindCSS Layout 與 Display:block、flex、grid、overflow、object-fit 全解析 | TailwindCSS 完整教學

2026/08/08
TailwindCSS Layout 與 Display:block、flex、grid、overflow、object-fit 全解析 | TailwindCSS 完整教學

TailwindCSS 裡,Layoutdisplay 是版面的骨架——blockinlineflexgrid 決定元素怎麼排列,hidden 決定它出不出現,overflow 決定內容溢出時怎麼處理,object-fit 決定圖片如何填滿容器。這篇是 TailwindCSS 完整教學 系列的第八篇,也是版面章節(TW-3)的開場,我們會把這一整組「掌控排列方式」的工具類一次講透,並以 v4 為預設、標註每一項與 v3 的差異。

前言

Layout(版面) 在網頁裡指的是「元素如何在頁面上排列與佔位」的一整套規則——它該獨佔一行還是跟旁邊擠在一起、它是一個 Flex 容器還是 Grid 容器、內容太多溢出時要裁掉還是加捲軸、圖片要如何填進固定尺寸的框裡。這一切的最底層,是一個叫做 display 的 CSS 屬性:它決定了一個元素的「渲染模式」,也就是這個盒子到底用哪一套規則來排版。在傳統 CSS 裡,這些由 displayoverflowobject-fitaspect-ratiocolumnsbox-sizingfloat 等屬性分別掌管;而 TailwindCSS 的版面系統,就是把這些屬性一對一包裝成好記、可組合的 utility class。

用一個現實世界的類比來理解:如果說一個網頁是一間正在佈置的房間,那麼 display 就是每件家具的「擺放方式」block 是一張佔滿整面牆的大書櫃(獨佔一行);inline 是牆上並排掛著的小相框(隨文字流一個接一個);flex 是一排可以自動對齊、伸縮的層架(彈性容器);grid 是像圍棋盤那樣的格狀收納櫃(二維網格);hidden 則是直接把家具搬出房間(不佔空間)。而 overflow 決定抽屜塞不下時是關起來看不見還是加個滑軌拉出來,object-fit 決定一張照片怎麼裱進固定尺寸的相框。Tailwind 把整套「佈置規則」標準化,你不再需要每次都手寫 CSS,而是像挑選現成的擺法一樣組合它們。

本篇你將學到:

  • display 工具類blockinlineinline-blockflexgridhiddencontentsflow-root 各代表什麼渲染模式,以及響應式切換的寫法
  • 溢出與比例overflow-* 溢出處理、overscroll-* 滾動鏈控制、aspect-* 長寬比,以及它們如何一起避免版面跳動(CLS)
  • 圖片與多欄object-fitobject-position 圖片填充、columns-* 瀑布流多欄排版
  • 盒模型與其他box-sizingisolationfloatclear,以及 v4 新增的邏輯屬性 float-startfloat-end

本系列以 TailwindCSS v4 為預設版本,本篇會明確標註每一項與 v3 的差異。

核心概念

版面工具類全景:六大分類對照表

版面相關的工具數量不少,但只要按「它對應哪個 CSS 屬性」來分類,就會發現非常有條理。下面這張表把最核心的六類並列出來,先建立全景地圖:

分類CSS 屬性代表工具類用途
顯示模式displayblockflexgridhiddencontents決定元素的渲染/排列方式
長寬比aspect-ratioaspect-squareaspect-videoaspect-[4/3]鎖定容器比例,避免版面跳動
溢出處理overflow / overscroll-behavioroverflow-hiddenoverflow-autooverscroll-contain內容溢出時裁切、捲動或控制滾動鏈
物件填充object-fit / object-positionobject-coverobject-containobject-center圖片/影片如何填滿容器
多欄與斷點columns / break-*columns-3break-inside-avoid瀑布流多欄、控制欄間斷裂
盒模型與其他box-sizing / isolation / floatbox-borderisolatefloat-left尺寸計算基準、堆疊隔離、浮動

這張表最需要先建立的認知是:display 是版面的地基,其他工具都建在它之上。你得先決定一個容器是 flex 還是 grid,才有後續 justify-*grid-cols-* 這些排列工具可用;你得先讓一個元素 blockw-* 高寬設定才有完整意義。所以寫版面的第一個動作,幾乎總是「先想清楚這個盒子的 display 模式」。

理解了這張分類表,接下來寫版面就有一套穩定的思考順序:先決定顯示模式(這個容器用哪套排版規則)、再處理尺寸與比例(它多大、比例鎖不鎖)、接著考慮溢出(內容太多怎麼辦)、最後才是圖片填充、多欄、浮動這些細節。這個從「骨架到細節」的順序,正好對應排版師傅先搭結構、再填內容的直覺流程。而 Tailwind 的價值在於:每一步的決策都對應到一個清楚命名的 class,你不必記 overflow-x: auto; overflow-y: hidden 這種組合,只要 overflow-x-auto overflow-y-hidden 就好。

display 模式:block、inline、flex、grid 的本質差異

display 是這一切的核心,值得先把幾個最常用的模式講清楚。它們的差異,本質上是「這個盒子如何佔位、以及它的子元素用哪套規則排列」:

Tailwind classCSS display佔位方式典型用途
blockblock獨佔整行,可設寬高div、段落、區塊容器
inlineinline隨文字流,無法設寬高句子中的 span、連結
inline-blockinline-block隨文字流,但可設寬高並排的小標籤、按鈕
flexflex塊級容器,子元素橫/縱向彈性排列導覽列、卡片列、置中
inline-flexinline-flex行內版 flex 容器帶圖示的行內按鈕
gridgrid塊級容器,子元素依二維網格排列相簿、儀表板、複雜版面
hiddennone完全移除,不佔空間響應式隱藏、切換內容
contentscontents移除自身盒子,子元素上升參與祖層排版保留語義標籤又不破壞 Flex/Grid
flow-rootflow-root建立新的區塊格式化上下文(BFC)包住浮動元素(現代 clearfix)

這裡有三個關鍵術語值得記住。第一是 blockinline 的根本差異block 元素像積木一樣由上而下堆疊、各自獨佔一行、可以設定寬高與上下 margin;inline 元素則像文字一樣從左到右流動、不換行、設定寬高無效。inline-block 是折衷——它像 inline 一樣不換行並排,卻又像 block 一樣可以設寬高,很適合做並排的小標籤。

第二是 flexgrid 都是「容器」宣告:對元素本身寫 flexgrid,改變的不是它自己怎麼排,而是它的直接子元素要用哪套排版引擎。flex 是一維(一條軸線,橫或縱),grid 是二維(行與列同時控制)。這兩個是接下來兩篇的主角,本篇先建立「它們是 display 的一種模式」這個定位。

第三是 contentsflow-root 這兩個進階但實用的模式contents 會讓元素自身的盒子「消失」,把子元素直接提升到祖層去參與排版——這在你有一個語義上必要的包裝標籤(如 <header>),卻不想讓它破壞外層 Flex/Grid 的扁平結構時非常有用。flow-root 則會建立一個全新的 BFC(Block Formatting Context),最經典的用途是包住內部的浮動元素,取代過去那段又臭又長的 clearfix hack。

v4 的版面相關差異

v4 在版面工具上有幾處值得標註的變化,這是本篇要特別點出的:

  • overflow-clip 正式成為 utility:在 v3,若要用 overflow: clip 得寫任意值 overflow-[clip];v4 把它正式收編為 overflow-clip。它和 overflow-hidden 都會裁切溢出內容,但關鍵差異是 overflow-clip 不會建立新的 BFC、也不會建立滾動容器,因此不影響子層的 sticky 定位——這是很實用的精準工具。
  • float-start / float-end(v4 新增):對應 CSS 邏輯屬性 float: inline-start / inline-end,會依文字方向自動對應左右,天然支援 RTL(由右到左)語系。v3 只有 float-left / float-right 這種實體方向。
  • Container Queries 內建:v4 原生支援 @container 容器查詢,不再需要額外安裝 plugin。這讓元件可以根據「自身容器寬度」而非「視口寬度」來調整版面,對可重複使用的卡片元件特別有用(屬進階主題,本系列後續會深入)。
  • aspect-* 讀取主題變數:v4 的 aspect-video 實際上讀取 --aspect-ratio-video 這個 CSS 變數,延續 v4「CSS-first」的設計方向,你也能在 @theme 裡自訂比例 Token。

補充一個常被忽略的細節:box-sizing(盒模型)在 Tailwind 的 Preflight 基礎樣式裡預設就把所有元素設為 border-box,也就是說 paddingborder 會被算進你設定的寬高之內,這通常正是你想要的。box-borderbox-content 這兩個工具是用來在特定元素上覆蓋這個預設,多數時候你根本不需要動它——知道「預設是 border-box」這件事,本身就能省下很多對不上寬度的困惑。

實作範例

理論看完,我們用幾個可執行的範例把工具串起來。以下都是完整的 HTML + Tailwind,可直接貼進頁面觀察效果。

範例一:響應式顯示與隱藏(導覽列)

最能展現 display 工具威力的場景,就是響應式導覽列——手機顯示漢堡按鈕、桌面顯示完整選單。關鍵就是 hiddenmd:flexmd:hidden 的搭配:

<!-- 導覽列:手機顯示漢堡選單,桌面顯示完整選單 -->
<nav class="flex items-center justify-between p-4">
  <a href="/" class="text-xl font-bold text-gray-900">Logo</a>

  <!-- 漢堡按鈕:只有手機版(md 以下)顯示 -->
  <button class="block md:hidden p-2">
    <span class="block w-6 h-0.5 bg-gray-900 mb-1"></span>
    <span class="block w-6 h-0.5 bg-gray-900 mb-1"></span>
    <span class="block w-6 h-0.5 bg-gray-900"></span>
  </button>

  <!-- 完整選單:md 以上才顯示,且是 flex 排列 -->
  <ul class="hidden md:flex gap-8 text-sm font-medium">
    <li><a href="/about" class="hover:text-cyan-600">關於</a></li>
    <li><a href="/work" class="hover:text-cyan-600">作品</a></li>
    <li><a href="/contact" class="hover:text-cyan-600">聯絡</a></li>
  </ul>
</nav>

這個範例的重點在於用 CSS 而非 JavaScript 管理顯示邏輯。漢堡按鈕寫 block md:hidden——預設(手機)是 block 顯示,到了 md 斷點以上切成 hidden 隱藏;完整選單則相反,寫 hidden md:flex——預設隱藏,md 以上才變成 flex 顯示。兩者一開一關,靠斷點自動切換,不需要任何 JS。特別留意選單那行的 md:flex:它同時做了兩件事——顯示元素、並讓它成為 flex 容器讓內部項目橫向排列,這是 display 工具「切換模式」的典型用法。

範例二:固定比例圖片容器(aspect + object-fit + overflow)

第二個高頻場景是「固定比例的圖片框」——縮圖、頭像、影片封面都需要它,而且要能避免版面跳動。這裡示範 aspect-*object-*overflow-hidden 的黃金組合:

<!-- 16:9 影片封面:鎖定比例,圖片填滿並裁切 -->
<div class="aspect-video w-full overflow-hidden rounded-xl bg-gray-100">
  <img
    src="/cover.jpg"
    alt="影片封面"
    class="w-full h-full object-cover object-center"
  >
</div>

<!-- 正方形頭像:固定尺寸 + 圓形裁切 -->
<div class="w-16 h-16 rounded-full overflow-hidden border-2 border-white shadow-md">
  <img src="/avatar.jpg" alt="使用者頭像" class="w-full h-full object-cover">
</div>

<!-- 商品圖:保持完整比例不裁切(object-contain) -->
<div class="aspect-square bg-gray-50 flex items-center justify-center rounded-lg">
  <img src="/product.png" alt="商品" class="max-h-full max-w-full object-contain">
</div>

<!-- 直接把 iframe 鎖成 16:9,避免載入時版面抖動 -->
<iframe class="aspect-video w-full rounded-xl" src="https://www.youtube.com/embed/xxxx"></iframe>

這裡有兩個關鍵決策。第一是 aspect-video 先幫容器鎖定 16:9 比例,讓瀏覽器在圖片載入前就預留好正確空間,避免載入完才撐開版面造成 CLS(版面位移)。第二是 object-coverobject-contain 的選擇object-cover 讓圖片填滿容器並裁掉多餘部分(適合封面、頭像,寧可裁切也要填滿),object-contain 則讓圖片完整顯示不裁切、可能留白(適合商品圖、Logo,寧可留白也要看到全貌)。而容器的 overflow-hidden 搭配 rounded-* 圓角是必須的,否則圖片的直角會露在圓角之外。

範例三:可滾動容器與滾動鏈控制(overflow + overscroll)

當內容超過固定高度時,用 overflow-y-auto 做出可滾動區塊;而 overscroll-contain 則能防止滾動穿透到父層:

<!-- 固定高度的可滾動列表 -->
<div class="h-64 overflow-y-auto overscroll-contain border border-gray-200 rounded-lg">
  <ul class="divide-y divide-gray-100">
    <li class="px-4 py-3 hover:bg-gray-50">項目 1</li>
    <li class="px-4 py-3 hover:bg-gray-50">項目 2</li>
    <li class="px-4 py-3 hover:bg-gray-50">項目 3</li>
    <!-- 更多項目... -->
  </ul>
</div>

<!-- 水平滾動的程式碼區塊:長行不換行、改用捲軸 -->
<pre class="overflow-x-auto bg-gray-900 text-gray-100 p-4 rounded-lg text-sm">
<code>const veryLongLine = "Lorem ipsum dolor sit amet consectetur adipiscing elit";</code>
</pre>

overflow-y-auto 的意思是「垂直方向內容溢出時才出現捲軸,沒溢出就不顯示」,比 overflow-y-scroll(永遠顯示捲軸)更乾淨。而 overscroll-contain 是很多人不知道的救星:當你在一個內部可滾動的彈窗或側欄裡滑到底時,預設瀏覽器會把捲動「傳遞」給背後的頁面(叫做 scroll chaining),造成整個頁面跟著動;加上 overscroll-contain 就能把捲動鎖在這個容器內,滑到底就停。這在做 Modal、下拉選單、聊天視窗時特別重要。

範例四:瀑布流多欄(columns)與盒模型隔離(isolation)

最後示範 columns-* 做瀑布流版面,以及 isolate 建立獨立的堆疊上下文:

<!-- 瀑布流卡片:不同高度的卡片自動填入最短的欄 -->
<div class="columns-1 sm:columns-2 lg:columns-3 gap-6">
  <div class="break-inside-avoid mb-6 bg-white rounded-xl shadow-sm p-6">
    <img src="/pic1.jpg" class="w-full rounded-lg mb-4" alt="圖片一">
    <p class="text-gray-700">短卡片內容。</p>
  </div>
  <div class="break-inside-avoid mb-6 bg-white rounded-xl shadow-sm p-6">
    <p class="text-gray-700">較長的卡片內容段落,高度不同的卡片會自動填充到最短的欄,形成瀑布流效果。</p>
    <p class="text-gray-500 text-sm mt-4">副標記</p>
  </div>
  <!-- 更多卡片... -->
</div>

<!-- isolate:建立獨立堆疊上下文,讓內部的 z-index 不外洩 -->
<div class="isolate relative">
  <div class="absolute inset-0 z-10 bg-cyan-500/20"></div>
  <p class="relative z-20">這裡的 z-index 只在這個 isolate 容器內比較</p>
</div>

columns-3 會把內容切成三欄由上而下、由左而右流動,天生就是瀑布流版面(不需要 Grid 或 JS 計算高度)。但有一個必配的工具:break-inside-avoid,它防止一張卡片在欄與欄的交界處被硬生生切成兩半。忘了加這個,你會看到卡片上半截在左欄、下半截在右欄的災難畫面。

isolate(對應 isolation: isolate)則是處理堆疊順序的利器:它會建立一個新的堆疊上下文(stacking context),讓容器內部的 z-index 自成一個小世界、不會和外部的 z-index 互相干擾。當你的頁面有很多層 overlay、又不想讓某個元件的 z-50 意外蓋過或被蓋過其他區塊時,在它外層加 isolate 就能把它的 z-index 戰場隔離開來。

常見錯誤與最佳實踐

四個最容易踩的版面坑

坑一:用 invisible 卻以為元素會消失。 invisiblevisibility: hidden)雖然看不見,但仍佔著原本的空間,後面的元素不會補上來。想讓元素徹底消失、不佔空間,要用 hiddendisplay: none):

<div class="invisible">這個看不見,但還佔著空間!</div>  <!-- ❌ 多數情況不是你要的 -->
<div class="hidden">這個徹底消失,不佔空間</div>          <!-- ✅ 響應式隱藏的正解 -->

坑二:父層 overflow-hidden 讓子層 sticky 失效。 sticky 相對於「最近的可滾動祖先」定位,而任何 overflow-hidden/auto/scroll 的祖先都會成為滾動容器並干擾它。若那個 overflow 只是為了裁切裝飾,改用 v4 的 overflow-clip(裁切但不建立滾動容器、不影響 sticky):

<!-- ❌ 父層 overflow-hidden 讓內部 sticky 側欄失效 -->
<div class="overflow-hidden">
  <aside class="sticky top-4">側欄</aside>
</div>

<!-- ✅ 只需裁切裝飾時改用 overflow-clip,sticky 正常運作 -->
<div class="overflow-clip">
  <aside class="sticky top-4">側欄</aside>
</div>

坑三:columns 多欄忘了加 break-inside-avoid 沒加這個,卡片會在欄交界被切成兩半。凡是放進 columns-* 的子項目,幾乎都該加上它:

<div class="columns-3">
  <div>...</div>                        <!-- ❌ 卡片可能被切斷 -->
  <div class="break-inside-avoid">...</div>  <!-- ✅ 卡片保持完整 -->
</div>

坑四:在 <button><a> 上用 contents 造成無障礙問題。 display: contents 會移除元素的盒子與其語義角色,在互動元素(<button><a><summary>)上使用,會讓輔助科技無法正確辨識這些元素,破壞鍵盤與螢幕閱讀器操作。contents 應該只用在純結構性的包裝 <div><section> 上:

<button class="contents">送出</button>   <!-- ❌ 破壞按鈕語義與無障礙 -->
<div class="contents">...</div>          <!-- ✅ 只在無語義的包裝層使用 -->

版面最佳實踐清單

  • 響應式顯示用 hidden + 斷點前綴,不要用 JShidden md:blockblock md:hidden 讓 CSS 接管顯示邏輯,更快、無閃爍。
  • 圖片框用 aspect-* 鎖比例避免 CLS:容器先鎖定比例,瀏覽器就能預留空間,改善 Core Web Vitals。
  • 填滿用 object-cover、完整顯示用 object-contain:封面/頭像寧可裁切要 cover,商品/Logo 要看全貌用 contain。
  • 只需裁切且要保留 sticky 時用 overflow-clip:v4 新工具,比 overflow-hidden 更精準、不建立滾動容器。
  • 可滾動容器加 overscroll-contain:Modal、側欄、聊天視窗防止滾動穿透到背景頁面。
  • columns-* 的子項一律加 break-inside-avoid:防止卡片跨欄被切斷。

小結

這是 TailwindCSS 完整教學 系列的第八篇,也是 TW-3 版面與定位章節的開場。上一篇《排版與文字》我們把 font-*text-*leading-* 這些文字層的工具講透,讓字排得好看又好讀;這一篇則從文字往外走一層,進入版面的骨架——用 display 決定元素怎麼排列、用 overflow 處理溢出、用 object-fit 填充圖片。回顧幾個重點:

  • display 是地基blockinlineflexgridhiddencontentsflow-root 各代表一種渲染模式,先決定 display,後續版面工具才有意義。
  • 固定比例圖片框aspect-* 鎖比例 + object-cover/contain 填充 + overflow-hidden 裁切,是縮圖與頭像的黃金組合,還能避免 CLS。
  • 溢出與滾動鏈overflow-auto/hidden/clip 處理溢出,overscroll-contain 防止滾動穿透,v4 的 overflow-clip 不影響 sticky。
  • 多欄與其他columns-* 做瀑布流(記得配 break-inside-avoid)、isolate 隔離 z-index、box-border(v4 預設)掌管盒模型、float-start/end 是 v4 的 RTL 友善新工具。
  • 最容易踩的坑hiddeninvisible 別搞混、父層 overflow 會讓 sticky 失效、互動元素別用 contents

版面工具就像蓋房子的鋼骨——先立好骨架,後面的排列、對齊、間距才有地方掛。下一篇 《TailwindCSS Flexbox 完整指南》,我們會深入 flex 這個最常用的一維版面引擎,把 justify-*items-*flex-1gap-* 這些工具一次講清楚,看 Tailwind 如何用一組 utility 就搞定置中、等分、換行這些每天都在寫的版面需求。

BenZ Software Developer

熱愛技術的軟體開發者,在這裡分享程式開發經驗與學習筆記。

本週主打

AI 自動化入門包

你每天手動在做的那些煩事,其實 AI 可以自己跑。這份給你 10 個照著做就會的自動化工作流 + 50 個複製即用的提示詞,不用會寫程式。

看看這個產品 →