Tailwind CSS Typography:低成本,高颜值的排版利器

@tailwindcss/typography 插件是 Tailwind CSS 世界中一个实用而典型的“反例”:在实用类驱动的设计中,引入了一种组合式抽象(prose 类),解决实际项目中“内容丰富但结构简单”的语义 HTML 所面临的样式问题。它不是适用于所有 UI 的万能解,但对于内容驱动的页面(如博客、知识库、教育平台)来说,是一项低成本、高颜值的排版利器。

Tailwind CSS 教程Tailwind CSS 排版Typography 插件prose 类富文本样式Markdown 样式美化Next.js 集成 Tailwind前端排版优化自定义 tailwind.config.js

对比效果

下面是使用 Tailwind CSS Typography 前后的对比效果。

  • 左侧展示了未进行任何排版优化的原始 HTML,采用浏览器默认的 User Agent Style
  • 右侧展示了应用 Typography 默认的 prose 类后的效果:
❌ 没用 Typography

H1:技术文档标题

H2:小节标题

H3:子小节标题

这是一个段落内容,用来演示浏览器默认样式。行高、字间距、段距等均未进行任何优化。

你可以写一些加粗斜体代码片段的文字。

这是一个引用区域。
  • 无序列表项 A
  • 无序列表项 B
  1. 有序列表 1
  2. 有序列表 2
function greet(name) {
  return 'Hello, ' + name + '!';
}
项目说明
HTML超文本标记语言
CSS层叠样式表
✅ 使用 Typography

H1:技术文档标题

H2:小节标题

H3:子小节标题

这是一个段落内容,用来演示Typography样式。行高、字间距、段距等均未进行任何优化。

你可以写一些加粗斜体代码片段的文字。

这是一个引用区域。
  • 无序列表项 A
  • 无序列表项 B
  1. 有序列表 1
  2. 有序列表 2
function greet(name) {
  return 'Hello, ' + name + '!';
}
项目说明
HTML超文本标记语言
CSS层叠样式表

💡注意,仅仅增加了一个class=prose

通过对比可见,Tailwind CSS Typography 插件(prose 类)在文本排版上带来了显著的视觉与可读性提升,包括:

  • 更协调的字体大小与行高,提高阅读舒适度
  • 恰当的段落与标题间距,使内容层次更清晰
  • 更美观的列表样式(项目符号、缩进、行距)
  • 统一优化的代码片段呈现(字体、背景、边距)
  • 引用块、表格等元素的专业化排版处理

整体上,prose 帮助原始 HTML 内容实现了更具可读性与设计感的排版表现,适用于技术文档、博客文章等内容密集型页面。

初识 Typography 插件

如果你对刚才展示的排版效果感兴趣,接下来我们将深入了解这个插件的由来、作用与适用场景。

  • 什么是Typography
  • 有什么用?
  • 适用于什么场景?
  • 适用人群?

近年来,Tailwind CSS 几乎成为现代前端项目的“默认选项”,不仅广泛应用于博客、文档、后台系统等场景,甚至像 OpenAIAI 产品官网也采用了它。这样的趋势本身就值得我们了解一下它背后的设计理念与实际价值。

Tailwind CSS 是一个 “实用优先”(utility-first)的 CSS 框架,它提供了大量原子级(单一职责)类名,用于直接在 HTML 中组合和构建复杂的用户界面,而无需编写传统意义上的 CSS。 相比 BootstrapFoundation 等“组件化”框架,Tailwind 不提供预设好的按钮、卡片、导航栏等组件,而是提供构建这些组件所需的低层级构建块(如 text-centerbg-blue-500p-4 等类名)。

什么是Typography

Tailwind CSS Typography 插件(也称为 @tailwindcss/typographyProse 插件)是 Tailwind Labs2020年左右推出的一款官方插件,提出了 prose 概念,将一套富文本样式整合成可复用的类名。旨在为开发者提供“优雅、合理、语义化的富文本样式”,专门为HTML 中的长文内容(如文章、博客、Markdown 渲染输出等)预设的富文本样式集。

通过 prose 类名提供了一套默认的 typographic 样式(排版样式),用于美化和统一文章中的段落、标题、列表、代码块、引用、图片、表格等常见 HTML 元素的外观。

有什么用?

在原生 Tailwind 中或者直接手写CSS样式,虽然可以为任何 HTML 元素添加类来控制样式,但渲染结构复杂、层级深的富文本内容(如从 CMSMarkdown 渲染文章)会变得比较繁琐。

Typography 插件的核心用途是:

  • 为未经自定义类名修饰的 HTML 提供一致、美观的排版默认值
  • 简化 MarkdownCMS 输出内容的样式美化
    • 尤其适用于将 Markdown 渲染为 HTML 的场景(如 MDXremarkrehype),可直接接管语义内容的样式渲染,无需手动标注类名。
  • 提供“开箱即用”的优雅排版体验
  • 通过可定制的主题,支持主题定制和深色模式

适用于什么场景?

✅ 非常适合

  • 博客系统;
  • 技术文档、知识库;
  • Markdown 内容渲染页面(如 Next.js.mdx);
  • 新闻/文章展示页;
  • 教育类内容平台;

Typography 插件虽然强大,但并不适用于所有页面类型:

🚫 不太适合

  • 高度组件化、视觉自由度高的 UI 模块;
  • 自定义结构、非标准语义内容(如复杂表单、图表交互);

适用人群

适合以下类型的用户:

初学者

  • 能快速获得排版美观的页面,不需要逐个微调每个 HTML 标签的样式;

中高级开发者

  • 可自定义主题或通过插件扩展,实现符合设计系统的排版;
  • 在构建内容平台、博客、静态站点时能大大节省工作量;

内容创作者/自媒体

  • 配合 Headless CMSNotion-to-blog 等架构,直接套用生成文章样式;

那么,下一步就让我们真正“动手”,看看如何在项目中使用它,并了解它的基本配置与最佳实践。

Step-by-Step 使用教程

接下来的演示中,以 Next.js 为宿主框架,使用的版本为Tailwind CSS v4,即使你对 Next.js 不熟悉,也可以完全按照步骤操作,本地也可以运行,我们主要关注Typography的实际效果。

先决条件:

  • 本机安装了Node.js 18.18及以上版本;
  • 安装pnpm

创建应用

  1. 首先创建一个next.js应用,采用pnpm作为包管理工具,这也是next.js官方推荐的方式,流程如下:

可选,如果网络不太好,通过如下方式使用pnpm镜像服务器;

# 放心使用,只会对当前的终端起作用,不会影响全局
export NPM_CONFIG_REGISTRY=https://registry.npmmirror.com

终端选择进入一个工程目录,输入如下命令:

npx create-next-app@latest --use-pnpm
 
# 如果本地没有安装会自动从 npm 注册表下载并安装最新版,
# 出现提示时,直接输入 `y` 确认
Need to install the following packages:
create-next-app@15.3.5
Ok to proceed? (y)

create-next-app 会提示输入工程名称,以及选项确认,工程名称输入: tailwindcss-typography,其余都保持默认,注意code不要放到src目录中,避免后面的流程中路径不一致。默认会集成tailwindcss

✔ What is your project named? … tailwindcss-typography
✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like your code inside a `src/` directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to use Turbopack for `next dev`? … No / Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No / Yes

终端输入以下命令,进入刚刚创建的工程目录,这里,我们用tailwindcss-typography

cd tailwindcss-typography
  1. 安装@tailwindcss/typography,我们输入以下命令安装typography插件
pnpm add -D @tailwindcss/typography

使用你熟悉的编辑器 如:visual studio codecursorwindsurftrae 等打开这个目录,查看package.json,在devDependencies部分应该有插件的信息,如下:

{
  ...
  
  "devDependencies": {
   ...
    "@tailwindcss/typography": "^0.5.16",
    "tailwindcss": "^4",
    ...
  }
}

至此,初始化项目部分已经完成。 在后续的流程中,如果出现next.jsreacttypescript等不熟悉的概念,不用担心,我们聚焦于typography的相关内容,脱离了这些, 换成javascriptvitevue等,一样可以正常使用,关注的始终是typography的核心理念,以及如何使用的内容。

认识 prose

打开编辑器,完成下面两个操作:

  • 编辑app目录下的globals.css,在第二行,即:@import "tailwindcss";后面增加引入插件代码,如下:
@import "tailwindcss";
@plugin "@tailwindcss/typography";
  • 编辑app目录下的page.tsx文件,将里面的内容全部删掉,替换成如下的代码:
import Link from "next/link"
 
export default function Home() {
	return (
		<div className="flex flex-row space-x-6 items-start justify-center h-screen w-screen p-8">
			<div>
				<h1>❌ 没用 Typography</h1>
				<h2>H2小节标题</h2>
				<h3>H3子小节标题</h3>
				<p>没有使用 typography 样式使用的是浏览器默认的样式User Agent Stylesheet</p>
				<p>
					你可以写一些<span style={{ fontWeight: "bold" }}>加粗</span><em>斜体</em><code>代码片段</code>的文字
				</p>
				<blockquote>这是一个引用区域</blockquote>
				<ul>
					<li>无序列表项 A</li>
					<li>无序列表项 B</li>
				</ul>
				<ol>
					<li>有序列表 1</li>
					<li>有序列表 2</li>
				</ol>
				<pre>
					<code>{`function greet(name) {
  return 'Hello, ' + name + '!';
}`}</code>
				</pre>
				<table>
					<thead>
						<tr>
							<th>项目</th>
							<th>说明</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>HTML</td>
							<td>超文本标记语言</td>
						</tr>
						<tr>
							<td>CSS</td>
							<td>层叠样式表</td>
						</tr>
					</tbody>
				</table>
 
				<h4>功能展示</h4>
				<ul>
					<li>
						<Link href="/1-size-modifiers">Size Modifiers 内置字号调整工具</Link>
					</li>
					<li>
						<Link href="/2-element-modifiers">Element Modifiers 个性化</Link>
					</li>
					<li>
						<Link href="/3-tailwind-config-js">Tailwind Config JS 个性化</Link>
					</li>
					<li>
						<Link href="/4-gray-scale">Gray Scale 灰度主题</Link>
					</li>
					<li>
						<Link href="/5-override-max-width">覆盖默认最大宽度</Link>
					</li>
					<li>
						<Link href="/6-undo-style">撤销prose样式</Link>
					</li>
				</ul>
			</div>
 
			<div className="prose dark:prose-invert">
				<h1>✅ 使用 Typography</h1>
				<h2>H2小节标题</h2>
				<h3>H3子小节标题</h3>
				<p>这是一个段落内容用来演示 typography 样式行高字间距段距等展示的视觉效果</p>
				<p>
					你可以写一些<span style={{ fontWeight: "bold" }}>加粗</span><em>斜体</em><code>代码片段</code>的文字
				</p>
				<blockquote>这是一个引用区域</blockquote>
				<ul>
					<li>无序列表项 A</li>
					<li>无序列表项 B</li>
				</ul>
				<ol>
					<li>有序列表 1</li>
					<li>有序列表 2</li>
				</ol>
				<pre>
					<code>{`function greet(name) {
  return 'Hello, ' + name + '!';
}`}</code>
				</pre>
				<table>
					<thead>
						<tr>
							<th>项目</th>
							<th>说明</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>HTML</td>
							<td>超文本标记语言</td>
						</tr>
						<tr>
							<td>CSS</td>
							<td>层叠样式表</td>
						</tr>
					</tbody>
				</table>
 
				<h4>功能展示</h4>
				<ul>
					<li>
						<Link href="/1-size-modifiers">Size Modifiers 内置字号调整工具</Link>
					</li>
					<li>
						<Link href="/2-element-modifiers">Element Modifiers 个性化</Link>
					</li>
					<li>
						<Link href="/3-tailwind-config-js">Tailwind Config JS 个性化</Link>
					</li>
					<li>
						<Link href="/4-gray-scale">Gray Scale 灰度主题</Link>
					</li>
					<li>
						<Link href="/5-override-max-width">覆盖默认最大宽度</Link>
					</li>
					<li>
						<Link href="/6-undo-style">撤销prose样式</Link>
					</li>
				</ul>
			</div>
		</div>
	)
}

回到终端,在应用目录下,输入启动命令启动开发服务器,同时在浏览器中输入地址 http://localhost:3000,默认端口是3000

pnpm dev
 
> tailwindcss-typography@0.1.0 dev /tailwindcss-typography
> next dev --turbopack
 
 Next.js 15.3.5 (Turbopack)
   - Local:        http://localhost:3000
   - Network:      http://192.168.5.35:3000

打开浏览器后,你会看到左侧展示了浏览器的默认样式(User Agent Style),右侧是typography的样式效果,和最上面的对比效果一致。

如果你此时观察代码发现,抛开那些tailwindcss原子类flex flex-row space-x-6...不管,你会发现,两个div唯一的不同是:仅仅增加了一个class=prose

<div>
	...
</div>
 
<div class="prose">
	...
</div>
 

接下来,我们来探究下发生了什么,以及Tailwind CSStypography做了什么。

当在一个 HTML 元素上添加类名 prose 时,Tailwind CSS + @tailwindcss/typography 插件背后会做很多事。它并不像其他 Tailwind 原子类一样只应用一两个样式,而是注入了一整套针对“文章类内容”优化的排版样式

prose 是一组预设的 “文章内容排版样式集合”,它通过设置嵌套元素(如 h1~h6pulolblockquotecode 等)的默认样式,让原始 HTML 呈现出更优雅、结构清晰、可读性强的排版效果。

从技术实现上,当安装typography插件并应用prose类后,Tailwind会扫描htmlmdxtsx等文件,若发现了prose类,就会把这一套排版样式编译进最终 CSS 文件中。

不像Tailwind原子类text-lgtext-blue-100等应用到单个元素上,prose 是一种 “作用于子元素的样式集”,会生成如下的内容:

.prose h1 { font-size: 2.25rem; font-weight: 800; line-height: 1.2; }
.prose p { margin-top: 1.25em; margin-bottom: 1.25em; }
.prose ul { padding-left: 1.5em; list-style-type: disc; }
.prose code { background-color: rgba(0,0,0,0.05); padding: 0.2em 0.4em; }
.prose blockquote { border-left: 0.25em solid #ccc; padding-left: 1em; color: #666; font-style: italic; }
/* ... 等数百行样式 */

总之:在元素上加上 .proseTailwind Typography 插件就会帮你自动美化文章内容中常见的标签,比如段落、标题、列表、引用、代码、表格等,让它们在不写任何额外样式的情况下看起来就像博客、技术文档那样整洁清晰。

在使用responsive design(响应式设计)的时候,需要在<head>中增加:

<meta name="viewport" content="width=device-width, initial-scale=1.0" />

为什么需要添加 <meta name=....?

  • meta 标签的作用是告诉浏览器如何控制页面的视口(viewport
  • width=device-width: 将视口的宽度设置为设备自身的宽度。例如,在手机上,它会使页面的宽度与手机屏幕的物理宽度匹配。如果没有这一项,浏览器可能会默认将页面渲染成实际大小(例如980px),然后缩小以适应移动设备屏幕,这会导致文字过小、布局混乱。
  • initial-scale=1.0: 设置页面首次加载时的缩放比例为1.0,即不进行任何缩放。结合 width=device-width,这确保了页面的CSS像素与设备独立像素(device-independent pixels)之间是1:1的关系,从而使响应式设计能够按照预期工作。
  • 若没有 meta 标签,浏览器无法正确识别设备的屏幕宽度, Tailwind CSS 响应式类(例如 md:, lg: 等)将无法按照预期在不同的屏幕尺寸上生效,因为浏览器不会触发正确的断点。

typography 还提供了5种开箱即用的排版响应式尺寸修饰符和灰度修饰类。我们来继续了解。

响应式尺寸修饰符

首先,要理解Tailwind CSS是移动优先(mobile-first)的策略,即:默认的样式是适用于最小视口(手机端),然后通过内置的breakpoint prefix(断点前缀),来覆盖更大屏幕的样式。通过该策略,可以实现响应式设计。

Tailwind CSS 内置了5个常用的断点:

Breakpoint prefix最小 width对应的CSS
sm40rem (640px)@media (width >= 40rem) { ... }
md48rem (768px)@media (width >= 48rem) { ... }
lg64rem (1024px)@media (width >= 64rem) { ... }
xl80rem (1280px)@media (width >= 80rem) { ... }
2xl96rem (1536px)@media (width >= 96rem) { ... }

断点的理解:当屏幕宽度达到某个宽度(1280px)时,应用对应排版风格,本质就是CSSmedia query,也就是最基础的响应式设计。

相应的,typography也基于此,提供了5种不同尺寸的字体大小,size modifiers

ClassBody font size
prose-sm0.875rem (14px)
prose-base (default)1rem (16px)
prose-lg1.125rem (18px)
prose-xl1.25rem (20px)
prose-2xl1.5rem (24px)

可以配合breakpoing prefix或单独使用。

如:prose lg:prose-xl 意思是,默认使用prose(移动端,字体较小),当页面宽度≥1024px 时,通过size modifiers来整体增大字体,即: prose-xl

⚠️,在添加尺寸修饰符时,始终需要包含prose类。

typography提供的尺寸调整参数由专业设计师精心手动调校,旨在呈现最完美的视觉效果,参数涵盖了字体大小之间的关系、标题间距、代码块内边距等多个方面,比起非设计专业的开发人员,要美观很多,即使不用,这些设计模式亦俱备参考价值。

可以查看插件的默认样式styles.js,深入查看每个修饰符的示例。

我们看下不同尺寸大小的效果。

app目录下创建1-size-modifiers目录,在该目录下创建page.tsx文件,复制如下的代码:

export const metadata = {
	title: "Size Modifiers",
	description: "Size Modifiers",
}
 
export default function SizeModifiersPage() {
	const generateHtmlCode = (title: string = "技术文档标题", subtitle: string = "小节标题") => {
		return `
			<h1>H1:${title}</h1>
			<h2>H2:${subtitle}</h2>
			<h3>H3:子小节标题</h3>
			<p>Tailwind CSS 遵循的是移动优先的设计原则。这意味着:默认情况下不加任何修饰符(比如 text-blue-500 或 p-4)的 CSS 规则会应用于所有屏幕尺寸,包括最小的移动设备屏幕。当你使用像 sm:, md:, lg: 这样的断点前缀时,你是在为更大(或等于)的屏幕尺寸添加或覆盖样式。断点是累积和覆盖的。 如果你只使用了 sm: 而没有使用 md: 或 lg:,那么 sm: 的样式将从 640px 开始一直生效到无限大(或者直到被另一个断点样式覆盖)。</p>
			<p>
				你可以写一些<span style="font-weight: bold;">加粗</span>、<em>斜体</em>或<code>代码片段</code>的文字。
			</p>
			<blockquote>这是一个引用区域。</blockquote>
			<ul>
				<li>无序列表项 A</li>
				<li>无序列表项 B</li>
			</ul>
			<ol>
				<li>有序列表 1</li>
				<li>有序列表 2</li>
			</ol>
			<pre><code>function greet(name) {
  return 'Hello, ' + name + '!';
}</code>
			</pre>
			<table>
				<thead>
					<tr>
						<th>项目</th>
						<th>说明</th>
					</tr>
				</thead>
				<tbody>
					<tr>
						<td>HTML</td>
						<td>超文本标记语言</td>
					</tr>
					<tr>
						<td>CSS</td>
						<td>层叠样式表</td>
					</tr>
				</tbody>
			</table>`
	}
 
	const configurations = [
		{ proseClass: "prose-sm", title: "prose-sm 0.875rem (14px)", subtitle: "适用于 640px 以上屏幕" },
		{ proseClass: "prose-base", title: "prose-base 1rem (16px)", subtitle: "也可写成 prose,是默认规则,适用于 768px 以上屏幕" },
		{ proseClass: "prose-lg", title: "prose-lg 1.125rem (18px)", subtitle: "适用于 1024px 以上屏幕" },
		{ proseClass: "prose-xl", title: "prose-xl 1.25rem (20px)", subtitle: "适用于 1280px 以上屏幕" },
		{ proseClass: "prose-2xl", title: "prose-2xl 1.5rem (24px)", subtitle: "适用于 1536px 以上屏幕" },
	]
 
	return (
		<div className="flex flex-row space-x-4 p-3">
			{configurations.map((config, index) => (
				<div
					key={index}
					className={`w-1/5 border-1 border-gray-300 p-2 prose dark:prose-invert ${config.proseClass}`}
					dangerouslySetInnerHTML={{
						__html: generateHtmlCode(config.title, config.subtitle),
					}}
				/>
			))}
		</div>
	)
}

然后回到浏览器,在应用首页:功能展示-->点击:- Size Modifiers 内置字号调整工具,或者直接地址上输入:http://localhost:3000/1-size-modifiers,可以看到5种不同字体尺寸的实际效果。后续,可以搭配tailwindcss的断点前缀和字体修饰符来实现不同分辨率下的字体大小调整。

样式自定义方式

如果上面默认的修饰符的颜色或字体大小需要进行进行调整,我们有以下几种方式:

1. Element modifiers

使用元素修饰符element modifiers直接在HTML中自定义内容中的各个元素的样式。

在app目录创建2-element-modifiers,在此目录下创建page.tsx,拷贝如下代码,然后在浏览器中访问地址 http://localhost:3000/2-element-modifiers,看看自定义样式的效果。

import Link from "next/link"
 
export default function Home() {
	return (
		<div className="flex flex-row space-x-6 items-start justify-center h-screen w-screen p-8">
			<div className="prose dark:prose-invert">
				<h1>⚙️ 默认样式</h1>
				<h2>H2小节标题</h2>
				<h3>H3子小节标题</h3>
				<p>没有使用 typography 样式使用的是浏览器默认的样式User Agent Stylesheet</p>
				<p>
					你可以写一些<span style={{ fontWeight: "bold" }}>加粗</span><em>斜体</em><code>代码片段</code>的文字
				</p>
				<blockquote>这是一个引用区域</blockquote>
				<ul>
					<li>无序列表项 A</li>
					<li>无序列表项 B</li>
				</ul>
				<ol>
					<li>有序列表 1</li>
					<li>有序列表 2</li>
				</ol>
				<pre>
					<code>{`function greet(name) {
  return 'Hello, ' + name + '!';
}`}</code>
				</pre>
				<table>
					<thead>
						<tr>
							<th>项目</th>
							<th>说明</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>HTML</td>
							<td>超文本标记语言</td>
						</tr>
						<tr>
							<td>CSS</td>
							<td>层叠样式表</td>
						</tr>
					</tbody>
				</table>
 
				<h4>功能展示</h4>
				<ul>
					<li>
						<Link href="/size-modifiers">Size Modifiers 内置字号调整工具</Link>
					</li>
					<li>
						<Link href="/size-modifiers">自定义字号 & 颜色</Link>
					</li>
					<li>
						<Link href="/size-modifiers">不使用 typography 样式</Link>
					</li>
					<li>
						<Link href="/gray-scale">Gray Scale 灰度主题</Link>
					</li>
				</ul>
			</div>
 
			<div className="prose dark:prose-invert prose-h1:text-blue-600 prose-h2:text-base prose-h3:text-pink-400 prose-h3:border prose-h3:border-orange-600 prose-h3:rounded-md prose-h3:p-2 prose-p:italic prose-table:border-collapse prose-table:border prose-table:border-gray-300 prose-th:border prose-th:border-gray-300 prose-th:text-center prose-td:border prose-td:border-gray-300 prose-td:text-center">
				<h1>✍️ 使用Element Modifiers 个性化prose-h1:text-blue-600</h1>
				<h2>H2小节标题使用 prose-h2:text-base h2 的字号设置为 base</h2>
				<h3>H3子小节标题使用 prose-h3:text-pink-400 prose-h3:border prose-h3:border-orange-600 prose-h3:rounded-md prose-h3:p-2 个性化</h3>
				<p>这是一个段落内容用来演示 typography 样式行高字间距段距等展示的视觉效果prose-p:italic</p>
				<p>
					你可以写一些<span style={{ fontWeight: "bold" }}>加粗</span><em>斜体</em><code>代码片段</code>的文字
				</p>
				<blockquote>这是一个引用区域</blockquote>
				<ul>
					<li>无序列表项 A</li>
					<li>无序列表项 B</li>
				</ul>
				<ol>
					<li>有序列表 1</li>
					<li>有序列表 2</li>
				</ol>
				<pre>
					<code>{`function greet(name) {
  return 'Hello, ' + name + '!';
}`}</code>
				</pre>
				<table>
					<thead>
						<tr>
							<th>项目</th>
							<th>说明</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>HTML</td>
							<td>超文本标记语言</td>
						</tr>
						<tr>
							<td>CSS</td>
							<td>层叠样式表</td>
						</tr>
						<tr>
							<td>示例样式</td>
							<td>
								prose-table:border-collapse prose-table:border prose-table:border-gray-300 prose-th:border prose-th:border-gray-300 prose-th:text-center prose-td:border
								prose-td:border-gray-300 prose-td:text-center
							</td>
						</tr>
					</tbody>
				</table>
 
				<h4>功能展示</h4>
				<ul>
					<li>
						<Link href="/1-size-modifiers">Size Modifiers 内置字号调整工具</Link>
					</li>
					<li>
						<Link href="/2-element-modifiers">Element Modifiers 个性化</Link>
					</li>
					<li>
						<Link href="/3-tailwind-config-js">Tailwind Config JS 个性化</Link>
					</li>
					<li>
						<Link href="/4-gray-scale">Gray Scale 灰度主题</Link>
					</li>
					<li>
						<Link href="/5-override-max-width">覆盖默认最大宽度</Link>
					</li>
					<li>
						<Link href="/6-undo-style">撤销prose样式</Link>
					</li>
				</ul>
			</div>
		</div>
	)
}

如果一切顺利,h1h2h3p、以及table的样式都发生了变化,这是最简单的方式,可以通过 prose-[element]:[tailwindcss utitlity]的方式快速调整成需要的样式。

可以查看tailwindcss utitlity相关文档,来查看其具体的效果;

下表是全部修饰符:

ModifierTarget
prose-headings:{utility}h1h2h3h4th
prose-lead:{utility}[class~="lead"]
prose-h1:{utility}h1
prose-h2:{utility}h2
prose-h3:{utility}h3
prose-h4:{utility}h4
prose-p:{utility}p
prose-a:{utility}a
prose-blockquote:{utility}blockquote
prose-figure:{utility}figure
prose-figcaption:{utility}figcaption
prose-strong:{utility}strong
prose-em:{utility}em
prose-kbd:{utility}kbd
prose-code:{utility}code
prose-pre:{utility}pre
prose-ol:{utility}ol
prose-ul:{utility}ul
prose-li:{utility}li
prose-table:{utility}table
prose-thead:{utility}thead
prose-tr:{utility}tr
prose-th:{utility}th
prose-td:{utility}td
prose-img:{utility}img
prose-video:{utility}video
prose-hr:{utility}hr
2. 全局修改

Element Modifiers虽然很方便,但是比较适合较少页面的场景,如果应用有很多页面,每个页面都需要调整的话,工作量很大,这种场景,需要“全局修改”,通过配置tailwind.config.js的方式来实现。

我们来实现上面同样的效果,先按照步骤一步一步完成,之后再解释相关内容。

在根目录创建 tailwind.config.js 文件,将如下代码复制进去:

/** @type {import('tailwindcss').Config} */
module.exports = {
	theme: {
		extend: {
			typography: () => ({
				DEFAULT: {
					css: {
						h1: {
							color: 'var(--color-blue-600)'
						},
						h2: {
							fontSize: 'var(--font-size-base)'
						},
						h3: {
							color: 'var(--color-pink-400)',
							border: '1px solid var(--color-orange-600)',
							padding: '8px',
							borderRadius: '0.6rem'
						},
						p: {
							fontStyle: 'italic'
						},
						table: {
							borderCollapse: 'collapse',
							border: '1px solid var(--color-gray-300)'
						},
						th: {
							border: '1px solid var(--color-gray-300)',
							textAlign: 'center'
						},
						td: {
							border: '1px solid var(--color-gray-300)',
							textAlign: 'center'
						}
					},
				},
				xl: {
					css: {
						h1: {
							color: 'blue'
						}
					}
				},
				extend: {
					css: {
						h1: {
							color: 'green'
						}
					}
				}
			}),
		},
	},
}

app目录下创建custom.css,输入如下代码:

@import "tailwindcss";
@plugin "@tailwindcss/typography";
@config "../tailwind.config.js";
  • custom.cssapp目录下,而tailwind.config.js在项目根目录,所以路径使用../,意思是相对于该目录的上级目录。
  • @configtailwindcss的指令,用来加载基于JavaScript的配置;

app目录下创建 3-tailwind-config-js 目录,在此目录下创建page.tsx,拷贝如下代码:

import Link from "next/link"
import "../custom.css"
 
export default function TailwindConfigJS() {
	return (
		<div className="flex flex-row space-x-6 items-start justify-center h-screen w-screen p-8">
			<div className="prose dark:prose-invert">
				<h1>⚙️ Tailwind Config JS 样式</h1>
				<h2>H2小节标题</h2>
				<h3>H3子小节标题</h3>
				<p>没有使用 typography 样式使用的是浏览器默认的样式User Agent Stylesheet</p>
				<p>
					你可以写一些<span style={{ fontWeight: "bold" }}>加粗</span><em>斜体</em><code>代码片段</code>的文字
				</p>
				<blockquote>这是一个引用区域</blockquote>
				<ul>
					<li>无序列表项 A</li>
					<li>无序列表项 B</li>
				</ul>
				<ol>
					<li>有序列表 1</li>
					<li>有序列表 2</li>
				</ol>
				<pre>
					<code>{`function greet(name) {
  return 'Hello, ' + name + '!';
}`}</code>
				</pre>
				<table>
					<thead>
						<tr>
							<th>项目</th>
							<th>说明</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>HTML</td>
							<td>超文本标记语言</td>
						</tr>
						<tr>
							<td>CSS</td>
							<td>层叠样式表</td>
						</tr>
					</tbody>
				</table>
 
				<h4>功能展示</h4>
				<ul>
					<li>
						<Link href="/1-size-modifiers">Size Modifiers 内置字号调整工具</Link>
					</li>
					<li>
						<Link href="/2-element-modifiers">Element Modifiers 个性化</Link>
					</li>
					<li>
						<Link href="/3-tailwind-config-js">Tailwind Config JS 个性化</Link>
					</li>
					<li>
						<Link href="/4-gray-scale">Gray Scale 灰度主题</Link>
					</li>
					<li>
						<Link href="/5-override-max-width">覆盖默认最大宽度</Link>
					</li>
					<li>
						<Link href="/6-undo-style">撤销prose样式</Link>
					</li>
				</ul>
			</div>
		</div>
	)
}

注意,文件顶部的 import "../custom.css"

然后,在浏览器中输入 http://localhost:3000/3-tailwind-config-js ,也会发生同样的变化。

我们来解释下相关的代码。

tailwind.config.js 是一个JavaScript文件,可以在这个文件中定义或扩展 Tailwind 的默认行为,在Tailwind CSS v3的版本中,该文件必不可少,V4移除了该文件的依赖,但是如果使用typography插件进行自定义扩展时,该文件必不可少。

使用JavaScript意味着可以实现:动态计算、模块化、条件逻辑、扩展性,在构建过程中,Tailwind CSS会读取该文件,根据配置来生成最终的CSS,所以我们重点关注下配置相关的内容。

DEFAULT使用CSS-in-JS syntax来表示CSS规则。

  • 传统 CSS 是由选择器、属性和值组成的字符串。而 CSS-in-JS 语法通常使用 JavaScript 对象来表示这些 CSS 规则。

  • 属性名通常是驼峰式: 例如,CSS 中的 background-colorJavaScript 对象中会写成 backgroundColor

  • 值通常是字符串: 大多数 CSS 值仍然是字符串,例如 '#fff', '1rem'

  • 嵌套规则的表示: 对于嵌套的 CSS 规则(如媒体查询、伪类、伪元素),通常会在对象中使用嵌套的对象或特定的语法来表示。

  • 使用DEFAULT来覆盖默认的样式规则,同时里面使用了Tailwind CSS中的一些变量,如果不熟悉这些,可以不使用这些变量,直接使用传统CSS的值。

  • 同样xl是覆盖了内置的prose-xlh1颜色;

  • 如果不想修改内置的颜色,可以使用自定义名称,比如:extend,在使用时只需要传入prose:extend即可,该名称可以自定义;

custom.css是定义要加载自定义的配置,同时在需要使用的页面引入这个样式,即完成了全局样式的处理。

⚠️ 虽然globals.css中已经引入了tailwindcsstypography,但是如果在该文件中增加自定义配置,会影响全局效果,为了演示其功能,单独增加该文件,重复引用了tailwindcsstypography,在生产环境中,尽量避免此类做法,Next.js + Tailwind 的构建流程是:只要 CSS 文件被引用,就作为入口构建。所以每个被 importCSS 文件,都会单独走 Tailwind 编译流程。这就使得 globals.csscustom.css两个独立的 Tailwind 编译入口,可以使用不同的配置(甚至插件、preset),但这样也失去了 Tailwind 原本统一性、按需生成的优势。同时会造成体积大、重复样式。

按照此方式,可以定义不同的主题,比如蓝色系、红色系等等。

灰度主题与风格说明

同样的,该插件默认提供了5种不同的灰阶主题。

app目录下,创建4-gray-scale目录,在此目录下创建page.tsx,拷贝如下代码:

export const metadata = {
	title: "Tailwind Typography 灰阶主题演示",
	description: "对比 prose-gray、slate、zinc、neutral、stone 的视觉差异与设计意图",
}
 
export default function GrayScalePage() {
	const generateHtmlCode = (proseClass: string, title: string = "技术文档标题", subtitle: string = "小节标题") => {
		return `<div class="${proseClass} dark:prose-invert">
			<h1>H1:${title}</h1>
			<h2>H2:${subtitle}</h2>
			<h3>H3:子小节标题</h3>
			<p>这是一个段落内容,用来演示 \`p\` 的样式。包括行高、字间距、段距等相关的内容。</p>
			<p>
				你可以写一些<strong>加粗</strong>、<em>斜体</em>或<code>代码片段</code>的文字。
			</p>
			<blockquote>这是一个引用区域。</blockquote>
			<ul>
				<li>无序列表项 A</li>
				<li>无序列表项 B</li>
			</ul>
			<ol>
				<li>有序列表 1</li>
				<li>有序列表 2</li>
			</ol>
			<pre><code>function greet(name) {
  return 'Hello, ' + name + '!';
}</code></pre>
			<table>
				<thead>
					<tr><th>项目</th><th>说明</th></tr>
				</thead>
				<tbody>
					<tr><td>HTML</td><td>超文本标记语言</td></tr>
					<tr><td>CSS</td><td>层叠样式表</td></tr>
				</tbody>
			</table>
		</div>`
	}
 
	const configurations = [
		{ proseClass: "prose-gray", title: "灰色主题 gray", subtitle: "灰色小节" },
		{ proseClass: "prose-slate", title: "石板色主题 slate", subtitle: "石板色小节" },
		{ proseClass: "prose-zinc", title: "锌色主题 zinc", subtitle: "锌色小节" },
		{ proseClass: "prose-neutral", title: "中性色主题 neutral", subtitle: "中性色小节" },
		{ proseClass: "prose-stone", title: "石色主题 stone", subtitle: "石色小节" },
	]
 
	return (
		<div className="p-4 w-screen space-y-4">
			{/* 顶部说明文案 */}
			<section className="max-w-5xl prose dark:prose-invert">
				<h1>Tailwind Typography 灰阶主题对比</h1>
				<p>
					Tailwind 提供了<code>5</code>种灰度排版主题其目的在于适配不同设计语言中的灰度风格
				</p>
				<table>
					<thead>
						<tr>
							<th>名称</th>
							<th>风格倾向</th>
							<th>色温倾向</th>
							<th>应用感受</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>gray</td>
							<td>默认 / 通用</td>
							<td>中性偏暖</td>
							<td>最通用最传统</td>
						</tr>
						<tr>
							<td>slate</td>
							<td>冷感 / 科技风</td>
							<td>偏冷</td>
							<td>稍偏蓝调适合代码类文档</td>
						</tr>
						<tr>
							<td>zinc</td>
							<td>金属感 / 极简风</td>
							<td>冷灰</td>
							<td>非常中性适合 UI 组件说明文档</td>
						</tr>
						<tr>
							<td>neutral</td>
							<td>纯中性色</td>
							<td>极中性</td>
							<td>略偏灰黄视觉最柔和</td>
						</tr>
						<tr>
							<td>stone</td>
							<td>自然风 / 柔和感</td>
							<td>偏暖</td>
							<td>类似纸张石块有自然复古感</td>
						</tr>
					</tbody>
				</table>
 
				<h2>为什么看起来好像都差不多”?</h2>
				<p>默认背景色相同字体较小会掩盖它们在引用列表符号代码块表格边框等处的细节色彩差异但在不同主题中会有微妙差异</p>
			</section>
 
			{/* 灰阶主题演示区域 */}
			<div className="flex flex-row space-x-2">
				{configurations.map((config, index) => (
					<div
						key={index}
						className={`w-1/5 prose dark:prose-invert p-2 rounded-lg border border-gray-300 shadow-sm ${config.proseClass}`}
						dangerouslySetInnerHTML={{
							__html: generateHtmlCode(config.proseClass, config.title, config.subtitle),
						}}
					/>
				))}
			</div>
		</div>
	)
}

然后在浏览器中访问 http://localhost:3000/4-gray-scale,查看其效果,灰度排版主题,其目的在于适配不同设计语言中的灰度风格,但是在视觉效果中不太容易区分。

暗黑模式支持

  • 每个默认的主题都包含一个精心设计的暗黑模式的版本,如果你在本地测试的时候,正在在晚上,且系统切换为了暗黑模式,那么你会发现在这种情况下,显示的视觉效果很差,不用担心,我们直接在每个使用prose的地方增加一个dark:prose-invert即可。但是最好给自定义的调整或者主题也配置一个暗黑模式。
  • 如果不希望使用暗黑模式,最简单的方式:
  • globals.css中,将如下代码进行修改,将前景色和背景色进行调整即可;
@media (prefers-color-scheme: dark) {
 
:root {
@media (prefers-color-scheme: dark) {
  :root {
    /*--background: #0a0a0a;
    --foreground: #ededed; */
    --background: #ffffff;
    --foreground: #171717;
  }
}
  • 同时移除dark:prose-invert

如何覆盖最大宽度限制

每个尺寸修饰符都内置了max-width,旨在尽可能保持内容的可读性,若希望内容完全填充其所在容器的宽度,只需在内容中添加 max-w-none即可覆盖内置的最大宽度。

app目录下,创建5-override-max-with目录,在此目录下创建page.tsx,拷贝如下代码:

export default function OverrideMaxWidth() {
	return (
		<div className="flex flex-col space-y-8 p-8">
			<div className="prose dark:prose-invert">
				<h1>默认行为</h1>
				<p>
					覆盖最大宽度: 每个尺寸修饰符都内置了一个
					max-width最大宽度),旨在尽可能保持内容的可读性然而这并非总是你想要的效果有时你可能希望内容完全填充其容器的宽度在这些情况下你只需在内容中添加 max-w-none
					即可覆盖内置的最大宽度总结要点prose 类默认行为Tailwind CSS prose例如 prose-lg, prose-xl在应用到内容块时会内置一个max-width 限制目的这个默认的 max-width
					是为了提高文本内容的阅读舒适性防止文本行过长导致难以阅读覆盖需求有时你可能不希望内容受到这个 max-width的限制而是希望它完全填充其父容器的可用宽度解决方案
					若要实现内容完全填充容器只需在应用了 prose 类的元素上额外添加 max-w-none 这个 Tailwind CSS 工具类示例max-w-none会移除 prose 默认设置的最大宽度约束
				</p>
			</div>
			<div className="prose dark:prose-invert max-w-none">
				<h1>Override Max Width</h1>
				<p>
					覆盖最大宽度 每个尺寸修饰符都内置了一个
					max-width最大宽度),旨在尽可能保持内容的可读性然而这并非总是你想要的效果有时你可能希望内容完全填充其容器的宽度在这些情况下你只需在内容中添加 max-w-none
					即可覆盖内置的最大宽度总结要点prose 类默认行为Tailwind CSS prose例如 prose-lg, prose-xl在应用到内容块时会内置一个max-width 限制目的这个默认的 max-width
					是为了提高文本内容的阅读舒适性防止文本行过长导致难以阅读覆盖需求有时你可能不希望内容受到这个 max-width的限制而是希望它完全填充其父容器的可用宽度解决方案
					若要实现内容完全填充容器只需在应用了 prose 类的元素上额外添加 max-w-none 这个 Tailwind CSS 工具类示例max-w-none会移除 prose 默认设置的最大宽度约束
				</p>
			</div>
		</div>
	)
}

在浏览器中访问http://localhost:3000/5-override-max-width,可以查看实际的效果。

如何撤销 prose 样式

如果某些内容不想应用prose的样式,可以通过在元素上增加not-prose来撤消typography样式。

app目录下,创建6-undo-style目录,在此目录下创建page.tsx,拷贝如下代码:

export default function UndoStyle() {
	return (
		<div className="flex flex-row space-x-6 items-start justify-center h-screen w-screen p-8">
			<div className="prose dark:prose-invert">
				<h1>✅ 使用 Typography</h1>
				<h2>H2小节标题</h2>
				<h3>H3子小节标题</h3>
				<p>这是一个段落内容用来演示 typography 样式行高字间距段距等展示的视觉效果</p>
				<p>
					你可以写一些<span style={{ fontWeight: "bold" }}>加粗</span><em>斜体</em><code>代码片段</code>的文字
				</p>
				<blockquote>这是一个引用区域</blockquote>
				<ul>
					<li>无序列表项 A</li>
					<li>无序列表项 B</li>
				</ul>
				<ol>
					<li>有序列表 1</li>
					<li>有序列表 2</li>
				</ol>
				<pre>
					<code>{`function greet(name) {
  return 'Hello, ' + name + '!';
}`}</code>
				</pre>
				<table>
					<thead>
						<tr>
							<th>项目</th>
							<th>说明</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>HTML</td>
							<td>超文本标记语言</td>
						</tr>
						<tr>
							<td>CSS</td>
							<td>层叠样式表</td>
						</tr>
					</tbody>
				</table>
			</div>
 
			<div className="prose dark:prose-invert">
				<h1 className="not-prose">撤销 Typography部分样式</h1>
				<h2>H2not-prose</h2>
				<h3>H3子小节标题</h3>
				<p>这是一个段落内容用来演示 typography 样式行高字间距段距等展示的视觉效果</p>
				<p>
					你可以写一些<span style={{ fontWeight: "bold" }}>加粗</span><em>斜体</em><code>代码片段</code>的文字
				</p>
				<blockquote>这是一个引用区域</blockquote>
				<ul className="not-prose">
					<li>无序列表项 A</li>
					<li>无序列表项 B</li>
					<li className="text-red-500">增加 not-prose撤销 typography 样式</li>
				</ul>
				<ol>
					<li>有序列表 1</li>
					<li>有序列表 2</li>
				</ol>
				<pre>
					<code>{`function greet(name) {
  return 'Hello, ' + name + '!';
}`}</code>
				</pre>
				<table className="not-prose">
					<thead>
						<tr>
							<th>项目</th>
							<th>说明</th>
						</tr>
					</thead>
					<tbody>
						<tr>
							<td>HTML</td>
							<td>超文本标记语言</td>
						</tr>
						<tr>
							<td>CSS</td>
							<td>层叠样式表</td>
						</tr>
						<tr>
							<td className="text-red-500">增加 not-prose撤销 typography 样式</td>
							<td className="text-red-500">增加 not-prose撤销 typography 样式</td>
						</tr>
					</tbody>
				</table>
			</div>
		</div>
	)
}

在浏览器中访问http://localhost:3000/6-undo-style,可以查看实际的效果。

修改默认 prose 类名

若出于任何原因的需求,需要修改默认的prose名称,可以在注册插件的使用className选项来进行处理:

@import "tailwindcss";
@plugin "@tailwindcss/typography" {
  className: yourdefinename;
}

⚠️ 同时,需要所有使用prose类的地方都要进行替换,包括前缀。

总结

  • @tailwindcss/typography 插件为内容密集型页面提供了极致的排版体验,几乎可以一键美化文章、博客、文档等富文本内容。它不仅提升了可读性和专业感,也帮助开发者节省了大量排版与样式调整时间。
  • 本篇文章带你从创建项目、基础使用,到进阶技巧(如响应式字号、主题灰度、暗黑模式、自定义样式等),系统性掌握了 Typography 插件的使用方式。
  • 无论你是内容创作者、独立开发者,还是在搭建自己的博客或文档系统,Tailwind Typography 都值得作为你的首选排版解决方案。

📎 示例项目源码:

👉 GitHub 仓库地址

👉 Live Demo

参考资料

暂无目录