案例:部落格 — 用 prose 打造內容型閱讀站 | TailwindCSS 完整教學
上一篇我們做了講究「轉換」的行銷 Landing Page,這一篇要換個完全不同的場域——講究「閱讀體驗」的內容型部落格。我們會用 TailwindCSS v4 逐段打造文章列表頁(卡片、封面、標籤)與文章閱讀頁,並祭出本篇的主角 @tailwindcss/typography 的 prose 類,用一行 class 就把一整篇 Markdown 長文變得像出版品般好讀,再補上側邊欄目錄 TOC、精緻程式碼區塊、響應式與暗色模式。做完你會得到一個可以直接放文章上去的閱讀站。
前言
如果說 Landing Page 的任務是「讓人行動」,那部落格的任務就是「讓人願意讀完」。這兩種頁面的版面哲學幾乎相反:行銷頁要大字、要氣勢、要滿版視覺衝擊;內容型網站則要克制、要留白、要把文字的可讀性擺在第一位。這一篇實戰,我們就來練這種「以文字為主角」的版面。
這是本系列實戰案例的第二課。上一篇《案例:Landing Page》我們把 flex、grid、響應式、暗色模式串成一個作品;這一篇我們會延續同樣的逐段實作節奏,但重點放到一個前面還沒好好登場的利器上——@tailwindcss/typography 這個官方外掛,以及它提供的 prose 類。內容型網站最大的痛點是:文章內文是 Markdown 或 CMS 動態渲染出來的一大坨 HTML,裡面的 <h2>、<p>、<ul>、<blockquote> 全都沒有 class,你不可能手動替每個標籤加 utility。prose 正是為了這個場景而生——把整坨內容包進一個 prose 容器,它就自動幫你把長文排到好看。
為什麼部落格值得單獨做一課?因為它跟行銷頁的挑戰完全不同,能補齊你版面能力的另一半。行銷頁你面對的是「固定、可控、每個元素都能加 class」的區塊;部落格你面對的是「動態、不可控、內容長度未知」的長文。前者練的是排版佈局,後者練的是內容排版(typography)與閱讀節奏——行寬多少最好讀、標題與段落的間距、程式碼區塊怎麼呈現、目錄怎麼跟著捲動高亮。這些是每一個技術部落格、文件站、知識庫都會遇到的真實需求,學會了,你就能獨立交付一個讓人讀得下去的內容站。
成品有兩個頁面。文章列表頁:響應式的文章卡片牆,每張卡有封面圖、分類標籤、標題、摘要與作者資訊。文章閱讀頁:三欄佈局(左留白 / 文章主體 / 右側 TOC),文章主體用 prose 美化、用 max-w-prose 控制行寬,右側是 sticky 固定的目錄。兩頁都完全響應式並支援暗色模式。
本系列以 TailwindCSS v4 為預設版本,範例皆以 v4 語法示範。凡涉及 v3 差異之處,我會特別標註。
本篇你將學到:
- @tailwindcss/typography:如何在 v4 用
@plugin啟用,以及prose、prose-invert、prose-lg、element modifier 的用法 - 內容排版思維:為什麼要用
max-w-prose收窄行寬、閱讀頁的三欄佈局怎麼拆 - 逐段實作:列表卡片 → 閱讀頁 prose 排版 → sticky TOC → 精緻程式碼區塊 → 側邊欄,每段一個可執行區塊
- 內容站的坑:長文行寬失控、prose 覆寫、標題錨點被 Navbar 蓋住等常見錯誤與正確做法
版面拆解
動手前,先把這兩個頁面在腦中拆塊。它們共用同一個 Header,但主體佈局差很多。
文章列表頁很單純,就是一面「卡片牆」:
┌─────────────────────────────────────────────┐
│ [LOGO] 文章 分類 關於 🔍 🌙 │ ← Header
├─────────────────────────────────────────────┤
│ 最新文章 │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ 封面圖 │ │ 封面圖 │ │ 封面圖 │ │ ← 卡片牆
│ │ #標籤 │ │ #標籤 │ │ #標籤 │ │ (grid 換欄)
│ │ 標題 │ │ 標題 │ │ 標題 │ │
│ │ 摘要 │ │ 摘要 │ │ 摘要 │ │
│ │ 👤 作者│ │ 👤 作者│ │ 👤 作者│ │
│ └────────┘ └────────┘ └────────┘ │
└─────────────────────────────────────────────┘
文章閱讀頁則是內容型網站的經典三欄:
┌─────────────────────────────────────────────┐
│ [LOGO] 文章 分類 關於 🔍 🌙 │ ← Header
├─────────────────────────────────────────────┤
│ ┌──────────────────┐ ┌──────────┐ │
│ (留白) │ 分類 · 標題 │ │ 本頁目錄 │ │
│ │ 作者 · 日期 │ │ • 前言 │ │ ← 三欄
│ │ ─────────────── │ │ • 安裝 │ │ grid
│ │ prose 長文內容 │ │ • 設定 │ │
│ │ ## 安裝 │ │ (sticky) │ │
│ │ ```程式碼區塊``` │ │ │ │
│ │ ## 設定 │ └──────────┘ │
│ │ #標籤 #標籤 │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────┘
拆完之後,一樣先替每塊選對佈局工具,並定好共用規則:
- 列表卡片牆:多張等寬卡片、手機要換行,這是
grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3的主場。 - 閱讀頁三欄:文章主體固定寬、右側 TOC 固定寬、左側吃剩餘空間,適合用
grid搭配lg:grid-cols-[1fr_16rem]這種混合欄寬。TOC 用sticky top-24讓它捲動時黏在視窗頂端。 - 共用外殼:兩頁的內容區都包在
max-w-7xl mx-auto px-4 sm:px-6 lg:px-8裡(這在上一篇已是老朋友)。 - 關鍵差異:行銷頁文字可以滿版求氣勢,但部落格的文章正文一定要用
max-w-prose收窄——這是內容型版面最重要的一條規則,下面會反覆強調。
還有一個貫穿全篇的主角要先介紹:prose 類的啟用。在 v4 裡,你不再需要 tailwind.config.js,而是直接在你的主 CSS 檔用 @plugin 載入 typography 外掛:
/* app.css:v4 用 @import 引入 Tailwind,再用 @plugin 掛上 typography */
@import "tailwindcss";
@plugin "@tailwindcss/typography";
寫完這兩行,prose 這一整組排版類就能在任何地方使用了。心裡有了這張地圖——列表用卡片牆、閱讀頁用三欄、正文用 max-w-prose 收窄、typography 用 @plugin 掛上——接下來逐段填肉。
逐段實作
以下每段都是可獨立執行的 HTML 片段,搭配一個掛好 Tailwind v4 與 typography 外掛的頁面即可。我們由外而內:先做列表頁的卡片,再進到閱讀頁的 prose 排版、TOC、程式碼區塊,最後補側邊欄。
文章列表卡片:封面、標籤、摘要
列表頁的核心是文章卡片。整張卡用 group 讓 hover 時封面圖放大、標題變色;封面用 aspect-[16/9] 固定比例避免高度參差;卡片內文用 flex flex-col 垂直堆疊,讓卡片高度一致。外層用 grid 排成響應式卡片牆。
<!-- 文章列表:grid 卡片牆,響應式換欄 -->
<section class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
<h1 class="text-3xl font-bold text-gray-900 dark:text-white mb-10">最新文章</h1>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<!-- 單張文章卡(group 讓整張卡可互動)-->
<article class="group flex flex-col">
<!-- 封面圖:固定 16:9 比例,hover 時放大 -->
<a href="/post/tailwindcss-v4-intro" class="block overflow-hidden rounded-2xl mb-4 aspect-[16/9]
bg-gray-100 dark:bg-gray-800">
<img src="/cover.jpg" alt="TailwindCSS v4 入門"
class="w-full h-full object-cover
group-hover:scale-105 transition-transform duration-500 ease-out" />
</a>
<div class="flex flex-col flex-1">
<!-- 分類標籤 -->
<a href="/category/tutorial"
class="text-xs font-semibold text-cyan-600 dark:text-cyan-400 uppercase tracking-wider mb-2
hover:text-cyan-700 dark:hover:text-cyan-300 transition-colors">教學</a>
<!-- 標題(最多兩行,超出省略)-->
<a href="/post/tailwindcss-v4-intro">
<h2 class="text-lg font-bold text-gray-900 dark:text-white mb-2 leading-snug line-clamp-2
group-hover:text-cyan-600 dark:group-hover:text-cyan-400 transition-colors">
TailwindCSS v4 快速入門:從零到部署
</h2>
</a>
<!-- 摘要(最多兩行)-->
<p class="text-sm text-gray-600 dark:text-gray-400 leading-relaxed line-clamp-2 flex-1">
從全新的 Oxide 引擎到 CSS-first 設定,帶你一次搞懂 v4 的核心變化與遷移要點。
</p>
<!-- 作者與日期(釘在卡片底部)-->
<div class="flex items-center gap-3 mt-4 text-xs text-gray-500 dark:text-gray-400">
<div class="flex items-center gap-2">
<div class="w-7 h-7 rounded-full bg-cyan-500 text-white text-xs font-bold
flex items-center justify-center">B</div>
<span>BenzHub</span>
</div>
<span class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-600"></span>
<time datetime="2026-09-13">9 月 13 日</time>
<span class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-600"></span>
<span>8 分鐘</span>
</div>
</div>
</article>
<!-- 更多卡片依樣複製 -->
</div>
</section>
這張卡有三個值得留意的細節。第一是 aspect-[16/9]:給封面容器一個固定長寬比,不管原圖尺寸如何,object-cover 都會把它裁切填滿,卡片牆就不會因為圖片高低不一而錯落。第二是 line-clamp-2:標題與摘要不管內容多長,都限制在兩行內、超出用 … 省略,確保每張卡的視覺高度一致——這在文章標題長短不一的列表頁幾乎是必備。第三是 flex flex-col 搭 flex-1:讓卡片內文垂直排列,摘要區用 flex-1 吃掉多餘空間,把「作者與日期」那一列推到卡片底部對齊,即使各卡摘要長度不同,底部資訊列也會齊平。
文章閱讀頁:prose 一行美化長文
進到閱讀頁,重頭戲登場。文章主體分兩部分:上方是我們自己手刻的文章 meta(分類、標題、作者),下方是交給 prose 自動排版的長文內容。關鍵就在那個 prose 容器——裡面的 HTML 完全沒有 class,全靠 prose 幫它們套上排版。
<!-- 閱讀頁三欄佈局:左留白 / 文章 / 右 TOC -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="grid grid-cols-1 lg:grid-cols-[1fr_16rem] gap-12">
<!-- 文章主體 -->
<main class="min-w-0">
<!-- 手刻的文章 meta -->
<header class="mb-10">
<a href="/category/tutorial"
class="text-sm font-semibold text-cyan-600 dark:text-cyan-400 uppercase tracking-wider">教學</a>
<h1 class="mt-3 text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-white
leading-tight tracking-tight">TailwindCSS v4 快速入門</h1>
<div class="flex items-center gap-3 mt-6 pb-8 text-sm text-gray-500 dark:text-gray-400
border-b border-gray-200 dark:border-gray-800">
<div class="w-9 h-9 rounded-full bg-cyan-500 text-white font-bold
flex items-center justify-center">B</div>
<span class="font-medium text-gray-900 dark:text-white">BenzHub</span>
<span class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-600"></span>
<time datetime="2026-09-13">2026 年 9 月 13 日</time>
<span class="w-1 h-1 rounded-full bg-gray-300 dark:bg-gray-600"></span>
<span>8 分鐘閱讀</span>
</div>
</header>
<!-- prose 容器:裡面的 HTML 全無 class,靠 prose 自動排版 -->
<div class="prose prose-slate prose-lg dark:prose-invert max-w-prose
prose-headings:scroll-mt-24
prose-a:text-cyan-600 dark:prose-a:text-cyan-400 prose-a:no-underline hover:prose-a:underline
prose-code:before:content-none prose-code:after:content-none">
<p>本文帶你從頭認識 TailwindCSS v4 的全新特性,包含 Oxide 引擎與 CSS-first 設定。</p>
<h2 id="install">安裝</h2>
<p>透過 npm 安裝 v4 版本:</p>
<pre><code>npm install tailwindcss @tailwindcss/vite</code></pre>
<h2 id="config">設定</h2>
<p>v4 最大的改變是把設定搬進 CSS。</p>
<blockquote><p>v4 移除了 tailwind.config.js,改用 @theme directive 在 CSS 裡定義設計變數。</p></blockquote>
<ul>
<li>更快的建置速度</li>
<li>更簡潔的設定方式</li>
</ul>
</div>
<!-- 文章底部標籤 -->
<footer class="mt-12 pt-8 border-t border-gray-200 dark:border-gray-800 flex flex-wrap gap-2">
<a href="/tags/tailwindcss" class="px-3 py-1 rounded-full text-sm bg-gray-100 dark:bg-gray-800
text-gray-700 dark:text-gray-300 hover:bg-gray-200
dark:hover:bg-gray-700 transition-colors">#TailwindCSS</a>
<a href="/tags/css" class="px-3 py-1 rounded-full text-sm bg-gray-100 dark:bg-gray-800
text-gray-700 dark:text-gray-300 hover:bg-gray-200
dark:hover:bg-gray-700 transition-colors">#CSS</a>
</footer>
</main>
<!-- 右側 TOC(下一段實作)-->
<aside class="hidden lg:block"><!-- ... --></aside>
</div>
</div>
這段的靈魂全在那一長串 prose class,值得逐個拆解:
prose:核心開關。一掛上,容器內所有<h2>、<p>、<ul>、<blockquote>、<pre>、<img>就立刻獲得經過設計的字級、行高、上下間距與列表縮排。prose-slate:選色系。typography 內建多種灰階色調(slate、gray、zinc、neutral、stone),prose-slate讓文字帶點冷灰,比預設更沉穩。prose-lg:放大整體字級與間距,長文閱讀更舒服。還有prose-sm、prose-xl等尺寸可選。dark:prose-invert:暗色模式的關鍵。它會把 prose 的所有顏色(文字、標題、連結、邊框)整組反轉成適合深色底的版本,你不必逐一寫dark:覆寫。max-w-prose:內容型版面最重要的一條。它把正文寬度限制在約 65ch(最佳行寬),即使螢幕再寬,文字也不會撐成難讀的長行。- element modifier(元素修飾前綴):
prose-headings:scroll-mt-24讓標題錨點捲動時預留 Navbar 高度;prose-a:text-cyan-600 ... hover:prose-a:underline把連結改成品牌色、平常不畫底線、hover 才畫;prose-code:before:content-none prose-code:after:content-none移除行內程式碼預設的前後反引號。
一句話總結:你負責產出乾淨的語意化 HTML,prose 負責把它排到好看,你只在需要品牌化的地方用修飾前綴微調。這就是內容型網站排版的正確分工。
順帶一提,這種「手刻 meta + prose 排內文」的分工不只適用部落格,文件站、知識庫、產品更新日誌都是同一套模式:凡是「內容由 Markdown 或 CMS 動態產生、你碰不到內部標籤」的頁面,都應該讓 prose 接手。你甚至可以在同一個容器同時掛多個尺寸與色系前綴(例如 prose-sm sm:prose-base lg:prose-lg),讓字級隨螢幕成長,手機看小一點、桌機放大一點,閱讀節奏自動適配裝置。
Sticky TOC:目錄跟著捲動、當前章節高亮
閱讀頁右側的目錄(Table of Contents)能大幅提升長文的導覽體驗。它的兩個關鍵是 sticky top-24(捲動時黏在視窗頂端、top-24 給 Header 留 6rem 空間)與 當前章節高亮(用左側 border-l 指示線標出你正在讀哪一節)。
<!-- 右側 TOC:sticky 固定,當前章節高亮 -->
<aside class="hidden lg:block">
<nav aria-label="本頁目錄"
class="sticky top-24 max-h-[calc(100vh-8rem)] overflow-y-auto">
<p class="text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-4">
本頁目錄
</p>
<ul class="border-l border-gray-200 dark:border-gray-800 space-y-1 text-sm">
<!-- 當前章節:品牌色 + 加粗的左指示線 -->
<li>
<a href="#install"
class="block -ml-px pl-4 py-1.5 border-l-2 border-cyan-500
text-cyan-600 dark:text-cyan-400 font-medium"
aria-current="location">安裝</a>
</li>
<!-- 其他章節:hover 時才浮現指示線 -->
<li>
<a href="#config"
class="block -ml-px pl-4 py-1.5 border-l-2 border-transparent
text-gray-600 dark:text-gray-400
hover:border-gray-400 hover:text-gray-900 dark:hover:text-white
transition-colors">設定</a>
</li>
</ul>
<!-- 回到頂部 -->
<a href="#top" class="flex items-center gap-2 mt-6 text-xs text-gray-500 dark:text-gray-400
hover:text-gray-900 dark:hover:text-white transition-colors">
<svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7"/>
</svg>
回到頂部
</a>
</nav>
</aside>
這裡有兩個技巧。第一是 sticky top-24 搭 max-h-[calc(100vh-8rem)] overflow-y-auto:前者讓 TOC 捲動時黏住頂端,後者限制它的最大高度並在超出時自己捲動——避免目錄項目太多時超出視窗、擋住內容。第二是用 border-l 做當前指示線:整個 <ul> 有一條淡淡的左邊框,當前章節的連結覆蓋一條 border-l-2 border-cyan-500 的粗色框並用 -ml-px 對齊,其他章節則是 border-transparent、hover 才浮現。至於「捲到哪、哪一節就自動高亮」的偵測,需要一點 JavaScript(用 IntersectionObserver 監看標題進入視窗時切換 class),這是本頁少數需要 JS 的地方,版面本身純 CSS 就到位了。
精緻程式碼區塊:not-prose 接管、手刻視窗感
技術部落格少不了程式碼區塊。prose 其實已經幫 <pre> 套了深色底的基本樣式,足夠一般使用。但如果你想要更精緻的效果——像是 Mac 視窗的三顆圓點、檔名標籤、複製按鈕——就該用 not-prose 讓這一塊「跳出 prose 的管轄」,自己完全手刻。
<!-- 精緻程式碼區塊:not-prose 讓 prose 不干涉,自己手刻視窗感 -->
<div class="not-prose my-6 rounded-xl overflow-hidden border border-gray-800 bg-gray-900 shadow-xl">
<!-- 標題列:Mac 圓點 + 檔名 + 複製按鈕 -->
<div class="flex items-center justify-between px-4 py-3 border-b border-gray-800 bg-gray-800/50">
<div class="flex items-center gap-3">
<div class="flex gap-1.5">
<span class="w-3 h-3 rounded-full bg-red-500"></span>
<span class="w-3 h-3 rounded-full bg-amber-500"></span>
<span class="w-3 h-3 rounded-full bg-green-500"></span>
</div>
<span class="text-xs font-mono text-gray-400">app.css</span>
</div>
<button class="flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium
text-gray-400 hover:text-white hover:bg-gray-700 transition-colors"
aria-label="複製程式碼">
<svg class="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
</svg>
複製
</button>
</div>
<!-- 程式碼內容:水平捲動避免長行破版 -->
<div class="overflow-x-auto">
<pre class="p-5 text-sm leading-relaxed font-mono text-gray-300"><code><span class="text-blue-400">@import</span> <span class="text-green-400">"tailwindcss"</span>;
<span class="text-purple-400">@plugin</span> <span class="text-green-400">"@tailwindcss/typography"</span>;</code></pre>
</div>
</div>
這段的關鍵字是 not-prose。當你在 prose 容器裡放一個自訂設計的區塊,prose 的樣式會滲透進去,把你手刻的字級、間距全打亂。not-prose 就像一道防火牆,加在這個 <div> 上,prose 的規則就到此為止、不再往裡套,你就能在裡面自由地用 utility 做出視窗標題列、複製按鈕這些精緻效果。另一個實用細節是 overflow-x-auto:程式碼常有長行,包一層水平捲動容器,長行就會在區塊內橫向捲動,而不會撐破版面或強制換行破壞縮排。
側邊欄:分類、熱門文章與訂閱
最後補上內容站常見的側邊欄(列表頁常用)。它通常放分類清單、熱門文章、訂閱區,用 space-y-* 把幾個區塊垂直堆疊,一樣可以 sticky 固定。
<!-- 側邊欄:分類 + 熱門文章 + 訂閱,sticky 固定 -->
<aside class="space-y-8 lg:sticky lg:top-24">
<!-- 分類清單 -->
<div class="rounded-2xl border border-gray-200 dark:border-gray-800 p-6">
<h3 class="text-sm font-bold text-gray-900 dark:text-white uppercase tracking-wider mb-4">文章分類</h3>
<ul class="space-y-2 text-sm">
<li><a href="/category/tutorial"
class="flex items-center justify-between text-gray-600 dark:text-gray-400
hover:text-cyan-600 dark:hover:text-cyan-400 transition-colors">
<span>教學</span><span class="text-xs text-gray-400">24</span></a></li>
<li><a href="/category/case"
class="flex items-center justify-between text-gray-600 dark:text-gray-400
hover:text-cyan-600 dark:hover:text-cyan-400 transition-colors">
<span>實戰案例</span><span class="text-xs text-gray-400">12</span></a></li>
</ul>
</div>
<!-- 訂閱區 -->
<div class="rounded-2xl bg-cyan-50 dark:bg-cyan-950/30 border border-cyan-100 dark:border-cyan-900 p-6">
<h3 class="text-base font-bold text-gray-900 dark:text-white mb-2">訂閱電子報</h3>
<p class="text-sm text-gray-600 dark:text-gray-400 mb-4">每週一篇前端實戰,直送信箱。</p>
<form class="flex flex-col gap-2">
<input type="email" placeholder="你的 Email"
class="w-full px-3 py-2 rounded-lg text-sm bg-white dark:bg-gray-900
border border-gray-200 dark:border-gray-700 text-gray-900 dark:text-white
placeholder:text-gray-400 focus:outline-none focus:ring-2 focus:ring-cyan-500" />
<button type="submit"
class="w-full px-4 py-2 rounded-lg text-sm font-semibold bg-cyan-500 text-white
hover:bg-cyan-400 transition-colors">訂閱</button>
</form>
</div>
</aside>
側邊欄的重點是克制——它是配角,不能搶走文章的注意力,所以用細邊框、淺底色、小字級,和主內容拉開視覺權重。lg:sticky lg:top-24 讓它在桌機捲動時黏住(手機則正常隨頁面流動,因為手機上側邊欄通常會堆疊到文章下方)。訂閱區用一點品牌色底(bg-cyan-50)稍微跳出,是側邊欄裡唯一允許稍微搶眼的區塊,因為那正是你希望讀者採取的動作。至此,列表卡片、prose 閱讀頁、sticky TOC、程式碼區塊、側邊欄五大塊全部到位,一個完整的內容型部落格就成形了。
常見錯誤與最佳實踐
內容型網站的坑跟行銷頁很不一樣,幾乎都圍繞「可讀性」打轉。
坑一:文章正文行寬失控,一行拉到天邊
最常見也最傷的錯誤:在寬螢幕上讓文章正文撐滿整個容器,一行變成上百個字。行太長,眼睛從行尾掃回下一行開頭時極易跳行、重讀,閱讀非常累。正解是永遠用 max-w-prose(約 65ch)或 max-w-2xl、max-w-3xl 把正文收窄,把多出來的橫向空間讓給側邊欄或留白。記住:行銷頁要滿版氣勢,部落格要適中行寬。
坑二:動態內容不用 prose,手動加 class 加到崩潰
有些人試圖替 Markdown 渲染出的每個 <p>、<h2> 手動加 utility——這根本行不通,因為內容是動態的、你碰不到那些標籤。正解就是 @tailwindcss/typography 的 prose:包一層 prose 容器,長文一次排好。內容型網站的排版,九成應該交給 prose,而不是手刻。
坑三:想改 prose 樣式,卻整組推翻重寫
想把連結改成品牌色、或某個區塊要自訂設計,結果直接放棄 prose、全部手刻——太浪費了。正解是分層處理:小範圍微調用 element modifier(prose-a:text-cyan-600、prose-headings:scroll-mt-24);某一塊要完全自訂(如精緻程式碼區塊、圖表卡)就用 not-prose 局部接管。既保留 prose 的自動排版,又能在需要處品牌化。
坑四:標題錨點捲動後被固定 Navbar 蓋住
當你點 TOC 跳到 #install,該標題常會被固定 Navbar 遮住半截,因為錨點捲動預設把標題頂到視窗最上緣。正解是給標題加 scroll-mt-24(scroll margin top),捲動定位時預留 Navbar 的高度;在 prose 內就用 prose-headings:scroll-mt-24 一次套用到所有標題。這個小 class 能省掉「點目錄後標題不見了」的困惑。
最佳實踐小結
- 正文一定收窄:文章欄用
max-w-prose,別讓行寬失控。 - 長文交給 prose:動態內容用
@tailwindcss/typography,別手動加 class。 - 暗色一鍵反轉:
dark:prose-invert處理長文暗色,不必逐標籤覆寫。 - 微調用修飾前綴、自訂用 not-prose:分層處理 prose,別整組推翻。
- 標題留錨點空間:
prose-headings:scroll-mt-24避免被 Navbar 蓋住。 - 卡片高度對齊:列表卡用
aspect-[16/9]、line-clamp-2、flex-1讓卡片牆整齊。 - 正式站走建置:別掛 Play CDN,用
@import "tailwindcss";加@plugin走建置流程產出精簡 CSS。
小結
這是 TailwindCSS 完整教學 系列的第四十四篇,也是實戰案例的第二課。上一篇《案例:Landing Page》我們做的是講究轉換的行銷頁,把 flex、grid、響應式、暗色模式串成作品;這一篇則轉向講究閱讀體驗的內容型部落格,主角換成 @tailwindcss/typography 的 prose 類。兩種頁面的版面思路正好互補,對照著看能補齊你版面能力的另一半。回顧幾個重點:
- 版面拆解:列表頁是
grid卡片牆、閱讀頁是三欄佈局,正文一定用max-w-prose收窄行寬。 - 逐段實作:列表卡片(
aspect+line-clamp+flex-1對齊)、prose 閱讀頁(一行美化長文 + element modifier 微調)、sticky TOC(sticky top-24+border-l高亮)、精緻程式碼區塊(not-prose接管)、側邊欄(克制的配角)。 - typography 心法:
prose自動排版、prose-invert暗色、prose-lg尺寸、修飾前綴微調、not-prose局部接管。 - 內容站的坑:行寬失控、不用 prose、覆寫方式錯、標題被 Navbar 蓋住,以及對應的正確做法。
下一篇《案例:儀表板》,我們會挑戰更複雜的一種頁面——管理後台 Dashboard。那裡有側邊導覽、統計卡、資料表格、圖表版位,是 grid 與 flex 綜合排版的硬仗,也會用到更多狀態與互動的處理。從行銷頁到部落格再到後台,三種截然不同的版面練完,你的 Tailwind 實戰功力就完整了。實戰之路,繼續往前。