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

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

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

对比效果

  • 左侧:未进行任何排版优化,采用浏览器默认的 User Agent Style。
  • 右侧:应用 @tailwindcss/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

通过对比可见,@tailwindcss/typography 插件的 prose 类在文本排版上带来了显著的视觉与可读性提升,比如:

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

在技术文档、博客文章等内容密集型页面提升可读性与设计感。

Typography 插件

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

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

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

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

什么是Typography?

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

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

有什么用?

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

Typography 插件的核心用途是:

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

适用于什么场景?

✅ 非常适合

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

🚫 不太适合

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

适用人群

初学者

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

中高级开发者

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

内容创作者/自媒体

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

Step-by-Step

接下来以 Next.js 为宿主框架,使用 Tailwind CSS v4 来演示相关的功能。

不用担心对 Next.js 不熟悉,按照步骤一步步操作,完全可以在本地进行实践。

先决条件:

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

创建应用

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

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

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

终端选择进入一个工程目录,输入如下命令,创建 Next.js 应用:

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

create-next-app 会提示输入工程名称,以及选项确认。

工程名称输入: tailwindcss-typography-demo,剩下的全部使用默认选项,15.4 的版本会建议将 code 目录 放到 src 目录下。

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

终端输入命令,进入刚刚创建的工程目录,这里,使用目录为 tailwindcss-typography-demo。

cd tailwindcss-typography-demo
  1. 安装@tailwindcss/typography,输入命令安装 typography 插件。
pnpm add -D @tailwindcss/typography

使用熟悉的编辑器 如:visual studio code 、cursor、windsurf、trae 等打开这个目录,查看 package.json,在 devDependencies 部分有插件的信息,如下:

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

至此,初始化项目部分已经完成。

在后续的流程中,如果出现 Next.js、React、TypeScript 等不熟悉的概念,不用担心,我们聚焦于 typography 的相关内容,脱离了这些,换成 JavaScript、Vite、Vue 等,一样可以正常使用,关注的始终是 typography 的核心理念,以及如何使用的内容。

初识 prose

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

  1. 编辑 app 目录下的 globals.css,在第二行,即:@import "tailwindcss"; 后面增加引入插件代码,如下:
@import "tailwindcss";
@plugin "@tailwindcss/typography";
  1. 编辑 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>
			</div>
 
			<div className="prose">
				<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>
	)
}
  1. 回到终端,在应用目录下,输入启动命令启动开发服务器,同时在浏览器中输入地址 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 插件后的样式效果,和最上面的对比效果一致。

如果此时观察代码,抛开 Tailwind CSS 实用类 flex flex-row space-x-6...,会发现,两个 div 唯一的不同是:仅增加了一个class=prose

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

发生了什么

接下来探究发生了什么,以及 Tailwind CSS 和 @typography 分别做了什么。

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

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

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

不像 Tailwind 实用类 text-lg 或 text-blue-100 等应用到单个元素上,prose 是一种作用于子元素的样式集,会自动生成大约 3000 多行的样式,涵盖了 h1~h4、p、a、blockquote、figure、figcaption、strong、em、kbd、code、pre、ol、ul、li、table、thead、tr、th、td、img、video、hr 等 20 余种标签以及内置文章导语或开头段落的样式。

.prose :where(h1):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
    color: var(--tw-prose-headings);
    margin-top: 0;
    margin-bottom: .888889em;
    font-size: 2.25em;
    font-weight: 800;
    line-height: 1.11111;
  }
 
  .prose :where(h1 strong):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
    color: inherit;
    font-weight: 900;
  }
 
  .prose :where(h2):not(:where([class~="not-prose"], [class~="not-prose"] *)) {
    color: var(--tw-prose-headings);
    margin-top: 2em;
    margin-bottom: 1em;
    font-size: 1.5em;
    font-weight: 700;
    line-height: 1.33333;
  }
/* ... 等数千行样式 */

生成的完整样式查看:

总结:在元素上加上 prose,@tailwindcss/typography 插件就会自动美化文章内容中常见的标签,让它们在不写任何额外样式的情况下看起来就像博客、技术文档那样整洁清晰。这一整套样式让文章内容在各种屏幕尺寸上都显得整洁美观。

不过,要让 Tailwind CSS 的响应式设计功能(例如 md:、lg: 等断点)在移动设备上正常工作,还需要一个重要的设置,即:

在使用 responsive design(响应式设计)的时候,需要在 <head> 中增加 meta 标签,目前大部分框架,如 Next.js 通过模版创建的应用都会包含该设置。

<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 种风格的灰色调主题,帮助开发者快速构建具有现代感的排版效果;
  • 响应式的尺寸修饰符,用于响应式排版;

灰色调主题对比

内置的 5 套灰色调主题,整体基本保持相同的背景与基础文本样式,但在引用块、代码区域、列表符号和表格边框等细节上,各主题呈现出微妙却有辨识度的差异。

  1. app 目录下,创建 2-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 p-2 rounded-lg border border-gray-300 shadow-sm ${config.proseClass}`}
						dangerouslySetInnerHTML={{
							__html: generateHtmlCode(config.proseClass, config.title, config.subtitle),
						}}
					/>
				))}
			</div>
		</div>
	)
}
  1. 浏览器中访问 http://localhost:3000/2-gray-scale,查看效果;

灰色调主题,目的在于适配不同设计语言中的灰度风格,但是在视觉效果中不太容易区分。

响应式尺寸修饰符

除了配色方案,插件还提供了响应式尺寸修饰符,使得不同屏幕尺寸下的排版表现也能灵活适配。

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

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

Breakpoint prefix最小 width对应的CSS常见设备示例
sm40rem (640px)@media (width >= 40rem) { ... }手机竖屏
md48rem (768px)@media (width >= 48rem) { ... }小型平板,iPad Air 竖屏
lg64rem (1024px)@media (width >= 64rem) { ... }iPad Pro 竖屏
xl80rem (1280px)@media (width >= 80rem) { ... }常规笔记本(13-15寸)
2xl96rem (1536px)@media (width >= 96rem) { ... }大屏显示器

断点的理解:当屏幕宽度达到某个宽度(1280px)时,应用对应的排版风格,本质是 CSS 的 media 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)

当使用prose时,默认采用的就是prose-base,若要适配不同的屏幕尺寸,可以搭配 tailwindcss 的 breakpoing prefix 使用。

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

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

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

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

通过实际操作,了解不同尺寸大小的效果。

  1. 在 app 目录下创建 3-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 ${config.proseClass}`}
					dangerouslySetInnerHTML={{
						__html: generateHtmlCode(config.title, config.subtitle),
					}}
				/>
			))}
		</div>
	)
}
  1. 浏览器输入:http://localhost:3000/3-size-modifiers,可以看到 5 种不同字体尺寸的实际效果。

后续,搭配 Tailwind CSS 的断点前缀和字体修饰符来实现不同分辨率下的字体大小调整。

Dark 模式

现代网页普遍支持亮色和暗色模式,基础实现通常依赖媒体查询 @media (prefers-color-scheme: dark),根据用户操作系统的主题偏好自动切换样式。

在 Tailwind CSS 中,Typography 插件同样提供了对暗色模式的支持。开发者可以使用 dark:prose-invert 工具类,在暗色模式下自动反转排版颜色,使其在深色背景上更具可读性。插件内置的每种灰阶主题(gray、slate、zinc、neutral、stone)均包含一套专门为暗色环境设计的配色方案,确保视觉一致性和阅读体验。

需要注意的是,prefers-color-scheme 是被动式切换方式,仅响应系统主题的变化。如果希望在网页中实现手动切换暗/亮模式(例如通过按钮切换),推荐的做法是使用 data-theme 属性,例如在 <html data-theme="dark"><html data-theme="light"> 上标记当前主题状态。配合 JavaScript 可以实现用户交互控制,同时通过 Tailwind 的 @custom-variant 或 &[data-theme=dark] 选择器来应用对应样式,进而覆盖默认的媒体查询行为,实现更灵活的主题管理。

通过实际操作,了解 dark 模式的实际效果。

  1. 在 app 目录下的 globals.css 文件,增加如下代码
@custom-variant dark (&:where([data-theme=dark], [data-theme=dark] *));
 
html[data-theme="dark"] {
	--background: #0a0a0a;
	--foreground: #ededed;
}

第一行的语法的含义是:

  • 定义了一个新的 dark 变体;
  • 只要在当前元素或其任意祖先元素中存在 data-theme="dark",就会激活这个变体;
  • 使用了 :where() 选择器以降低 CSS 优先级,确保更容易被覆盖。

有了这个变体定义后,就可以在组件中这样使用:

<div data-theme="dark">
  <div className="dark:bg-black dark:text-white">
    在暗色模式下背景为黑色,文字为白色
  </div>
</div>

无须添加 class="dark",只需设置 data-theme="dark" 即可让 Tailwind 的暗色工具类生效。

第三到六行的含义是:

  • 通过属性选择器 html[data-theme="dark"] 绑定暗色主题,当页面根元素(<html>)具有 data-theme="dark" 属性时,动态覆盖 CSS 变量 --background 和 --foreground 的默认值;
  • 这种方式可以实现基于主题的颜色切换,配合 var(--background) 和 var(--foreground) 的使用,实现组件级的主题适配,无需额外类名控制。
  1. 在 app 目录下,创建 4-dark-mode 目录,在该目录下创建 page.tsx 文件,拷贝如下代码:
"use client"
 
import { useState } from "react"
 
export default function Home() {
	const themes = ["gray", "slate", "zinc", "neutral", "stone"]
	const [theme, setTheme] = useState("gray")
	const setThemeMode = function (mode: string) {
		document.documentElement.setAttribute("data-theme", mode)
	}
 
	return (
		<div className="flex flex-col space-y-6 items-center justify-start h-screen w-screen p-8">
			<div className="flex flex-row space-x-3">
				<button
					className="bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200 px-4 py-2 rounded-md cursor-pointer"
					onClick={() => setThemeMode("light")}>
					Light
				</button>
				<button
					className="bg-gray-200 dark:bg-gray-800 text-gray-800 dark:text-gray-200 px-4 py-2 rounded-md cursor-pointer"
					onClick={() => setThemeMode("dark")}>
					Dark
				</button>
			</div>
 
			<div className="flex flex-wrap justify-center gap-3">
				{themes.map((t) => (
					<button
						key={t}
						onClick={() => setTheme(t)}
						className={`text-sm px-4 py-1.5 rounded-md border cursor-pointer
							${
								theme === t
									? "bg-gray-800 text-white border-gray-700"
									: "bg-gray-100 dark:bg-gray-700 text-gray-800 dark:text-gray-100 border-gray-300 dark:border-gray-600"
							}
						`}>
						{t}
					</button>
				))}
			</div>
 
			<div className={`prose prose-${theme} dark:prose-invert max-w-3xl`}>
				<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>
	)
}
  1. 浏览器输入:http://localhost:3000/4-dark-mode,可以看到 dark 模式的实际效果。

自定义样式

Typography 插件提供的默认样式已经能够满足大多数排版需求,包括合理的行高、段距、标题尺寸、列表缩进等。然而,在某些场景下可能希望进一步微调颜色、字体大小、边距或其他样式,以更贴合品牌或设计系统。

Tailwind CSS 提供了两种主要方式来自定义 Typography 插件的样式:

  1. ✅ 使用 Element Modifiers(元素修饰符) 通过类名的方式在 HTML 中直接为特定元素指定样式,语法简单,灵活高效:

  2. ⚙️ 使用 Tailwind 配置(tailwind.config.js) 在项目的 Tailwind 配置中通过 typography 插件的扩展机制,统一定义一组自定义的 prose 主题(如 prose-custom),以便在多个组件或页面中复用:

1. Element modifiers

Typography 插件支持通过 元素修饰符(element modifiers) 的形式,为 Markdown 或富文本内容中的特定 HTML 元素自定义样式。 这使得无需编写额外的 CSS,就可以在 HTML 中直接精细化控制诸如标题、段落、列表、链接等元素的视觉表现。

语法:

prose-[element]:[Tailwind 工具类]
  • [element] 是目标 HTML 元素的名称,如 h1、p、a 等;
  • [Tailwind 工具类] 是希望应用的 Tailwind CSS 实用类;

示例:prose-h1:text-blue-600,表示将渲染后的 h1 元素文字颜色设置为蓝色。

可以在同一个 prose 容器中组合多个修饰符,为不同的元素分配不同的样式,从而实现更精细的排版控制。

下表是 prose 的所有可用的元素修饰符,以及对应的 HTML 标签:

修饰符作用对象 HTML 标签
prose-headings:{utility}h1, h2, h3, h4, th
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

⚠️注意:这些修饰符必须应用在 .prose 类所在的元素上,才能生效。

实际操作:

  1. 在 app 目录创建 5-element-modifiers,在此目录下创建 page.tsx 文件,拷贝如下代码:
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>
			</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>
			</div>
		</div>
	)
}
  1. 打开浏览器,访问 http://localhost:3000/5-element-modifiers,如果一切顺利,h1、h2、h3、p、以及 table 的样式都发生了变化。

查看 tailwindcss utitlity 相关文档,了解 tailwindcss 实用类的具体效果;

2. 全局样式修改

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

  1. 在 src 根目录创建 tailwind.config.js 文件(和 app 目录同级),将如下代码复制进去:
/** @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'
            }
          },
        },
        pink: {
          css: {
            '--tw-prose-body': 'var(--color-pink-800)',
            '--tw-prose-headings': 'var(--color-pink-900)',
            '--tw-prose-lead': 'var(--color-pink-700)',
            '--tw-prose-links': 'var(--color-pink-900)',
            '--tw-prose-bold': 'var(--color-pink-900)',
            '--tw-prose-counters': 'var(--color-pink-600)',
            '--tw-prose-bullets': 'var(--color-pink-400)',
            '--tw-prose-hr': 'var(--color-pink-300)',
            '--tw-prose-quotes': 'var(--color-pink-900)',
            '--tw-prose-quote-borders': 'var(--color-pink-300)',
            '--tw-prose-captions': 'var(--color-pink-700)',
            '--tw-prose-code': 'var(--color-pink-900)',
            '--tw-prose-pre-code': 'var(--color-pink-100)',
            '--tw-prose-pre-bg': 'var(--color-pink-900)',
            '--tw-prose-th-borders': 'var(--color-pink-300)',
            '--tw-prose-td-borders': 'var(--color-pink-200)',
            '--tw-prose-invert-body': 'var(--color-pink-200)',
            '--tw-prose-invert-headings': 'var(--color-white)',
            '--tw-prose-invert-lead': 'var(--color-pink-300)',
            '--tw-prose-invert-links': 'var(--color-white)',
            '--tw-prose-invert-bold': 'var(--color-white)',
            '--tw-prose-invert-counters': 'var(--color-pink-400)',
            '--tw-prose-invert-bullets': 'var(--color-pink-600)',
            '--tw-prose-invert-hr': 'var(--color-pink-700)',
            '--tw-prose-invert-quotes': 'var(--color-pink-100)',
            '--tw-prose-invert-quote-borders': 'var(--color-pink-700)',
            '--tw-prose-invert-captions': 'var(--color-pink-400)',
            '--tw-prose-invert-code': 'var(--color-white)',
            '--tw-prose-invert-pre-code': 'var(--color-pink-300)',
            '--tw-prose-invert-pre-bg': 'rgb(0 0 0 / 50%)',
            '--tw-prose-invert-th-borders': 'var(--color-pink-600)',
            '--tw-prose-invert-td-borders': 'var(--color-pink-700)',
          },
        },
      }),
    },
  },
}
  1. 在 app 目录下创建 tailwind-config-demo.css 文件,拷贝如下代码:
@import "tailwindcss";
@plugin "@tailwindcss/typography";
@config "./tailwind.config.js";
  • @config 是 Tailwind CSS 的指令,用来加载基于 JavaScript 的配置;
  1. 在 app 目录下创建 6-tailwind-config 目录,在此目录下创建 page.tsx 文件,拷贝如下代码:
import "../tailwind-config-demo.css"
 
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>
			</div>
 
			<div className="prose prose-pink dark:prose-invert">
				<h1>⚙️ 使用 tailwind.config.js 配置样式,主题:prose-pink</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>
			</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>
			</div>
		</div>
	)
}
  1. 在浏览器中输入 http://localhost:3000/6-tailwind-config ,查看效果。

说明:

tailwind.config.js 是一个 JavaScript 文件,可以在这个文件中定义或扩展 Tailwind 的默认行为。

在Tailwind CSS v3 的版本中,该文件必不可少,V4 移除了该文件的依赖,但是如果使用 typography 插件进行自定义扩展时,该文件必不可少。

使用 JavaScript 意味着:

  • 动态计算、
  • 模块化、
  • 条件逻辑、
  • 扩展性

在构建过程中,Tailwind CSS 会读取该文件,根据配置来生成最终的CSS。

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

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

  • 属性名通常是驼峰式: 例如,CSS 中的 background-color 在 JavaScript 对象中会写成 backgroundColor。
  • 值通常是字符串: 大多数 CSS 值仍然是字符串,例如 '#fff', '1rem'。
  • 嵌套规则的表示: 对于嵌套的 CSS 规则(如媒体查询、伪类、伪元素),通常会在对象中使用嵌套的对象或特定的语法来表示。

第一步中的配置进行了以下的操作:

  • 使用 DEFAULT 来覆盖默认主题中 h1, h2, h3, p, table, th, td 的样式规则,这些都是修饰符作用对象 HTML 标签 ,对其颜色、字体、边框等进行了调整;
  • pink 是自定义颜色主题,使用 prose-pink 来应用该主题,也是通过该方式开增加自定义主题;

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

如何覆盖最大宽度限制

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

  1. 在app目录下,创建 7-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>H2:not-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

参考资料

暂无目录