案例:部落格 — 用 prose 打造內容型閱讀站 | TailwindCSS 完整教學

2026/09/13
案例:部落格 — 用 prose 打造內容型閱讀站 | TailwindCSS 完整教學

上一篇我們做了講究「轉換」的行銷 Landing Page,這一篇要換個完全不同的場域——講究「閱讀體驗」的內容型部落格。我們會用 TailwindCSS v4 逐段打造文章列表頁(卡片、封面、標籤)與文章閱讀頁,並祭出本篇的主角 @tailwindcss/typographyprose 類,用一行 class 就把一整篇 Markdown 長文變得像出版品般好讀,再補上側邊欄目錄 TOC、精緻程式碼區塊、響應式與暗色模式。做完你會得到一個可以直接放文章上去的閱讀站。

前言

如果說 Landing Page 的任務是「讓人行動」,那部落格的任務就是「讓人願意讀完」。這兩種頁面的版面哲學幾乎相反:行銷頁要大字、要氣勢、要滿版視覺衝擊;內容型網站則要克制、要留白、要把文字的可讀性擺在第一位。這一篇實戰,我們就來練這種「以文字為主角」的版面。

這是本系列實戰案例的第二課。上一篇《案例:Landing Page》我們把 flexgrid、響應式、暗色模式串成一個作品;這一篇我們會延續同樣的逐段實作節奏,但重點放到一個前面還沒好好登場的利器上——@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 啟用,以及 proseprose-invertprose-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-colflex-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-smprose-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-24max-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-2xlmax-w-3xl 把正文收窄,把多出來的橫向空間讓給側邊欄或留白。記住:行銷頁要滿版氣勢,部落格要適中行寬。

坑二:動態內容不用 prose,手動加 class 加到崩潰

有些人試圖替 Markdown 渲染出的每個 <p><h2> 手動加 utility——這根本行不通,因為內容是動態的、你碰不到那些標籤。正解就是 @tailwindcss/typographyprose:包一層 prose 容器,長文一次排好。內容型網站的排版,九成應該交給 prose,而不是手刻。

坑三:想改 prose 樣式,卻整組推翻重寫

想把連結改成品牌色、或某個區塊要自訂設計,結果直接放棄 prose、全部手刻——太浪費了。正解是分層處理:小範圍微調用 element modifier(prose-a:text-cyan-600prose-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-2flex-1 讓卡片牆整齊。
  • 正式站走建置:別掛 Play CDN,用 @import "tailwindcss";@plugin 走建置流程產出精簡 CSS。

小結

這是 TailwindCSS 完整教學 系列的第四十四篇,也是實戰案例的第二課。上一篇《案例:Landing Page》我們做的是講究轉換的行銷頁,把 flexgrid、響應式、暗色模式串成作品;這一篇則轉向講究閱讀體驗的內容型部落格,主角換成 @tailwindcss/typographyprose 類。兩種頁面的版面思路正好互補,對照著看能補齊你版面能力的另一半。回顧幾個重點:

  • 版面拆解:列表頁是 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。那裡有側邊導覽、統計卡、資料表格、圖表版位,是 gridflex 綜合排版的硬仗,也會用到更多狀態與互動的處理。從行銷頁到部落格再到後台,三種截然不同的版面練完,你的 Tailwind 實戰功力就完整了。實戰之路,繼續往前。

BenZ Software Developer

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

本週主打

AI 自動化入門包

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

看看這個產品 →