对比效果
下面是使用 Tailwind CSS Typography
前后的对比效果。
- 左侧展示了未进行任何排版优化的原始
HTML
,采用浏览器默认的User Agent Style
。 - 右侧展示了应用
Typography
默认的prose
类后的效果:
H1:技术文档标题
H2:小节标题
H3:子小节标题
这是一个段落内容,用来演示浏览器默认样式。行高、字间距、段距等均未进行任何优化。
你可以写一些加粗、斜体或代码片段
的文字。
这是一个引用区域。
- 无序列表项 A
- 无序列表项 B
- 有序列表 1
- 有序列表 2
function greet(name) {
return 'Hello, ' + name + '!';
}
项目 | 说明 |
---|---|
HTML | 超文本标记语言 |
CSS | 层叠样式表 |
H1:技术文档标题
H2:小节标题
H3:子小节标题
这是一个段落内容,用来演示Typography样式。行高、字间距、段距等均未进行任何优化。
你可以写一些加粗、斜体或代码片段
的文字。
这是一个引用区域。
- 无序列表项 A
- 无序列表项 B
- 有序列表 1
- 有序列表 2
function greet(name) {
return 'Hello, ' + name + '!';
}
项目 | 说明 |
---|---|
HTML | 超文本标记语言 |
CSS | 层叠样式表 |
💡注意,仅仅增加了一个class=prose
。
通过对比可见,Tailwind CSS Typography
插件(prose
类)在文本排版上带来了显著的视觉与可读性提升,包括:
- 更协调的字体大小与行高,提高阅读舒适度
- 恰当的段落与标题间距,使内容层次更清晰
- 更美观的列表样式(项目符号、缩进、行距)
- 统一优化的代码片段呈现(字体、背景、边距)
- 引用块、表格等元素的专业化排版处理
整体上,prose
帮助原始 HTML
内容实现了更具可读性与设计感的排版表现,适用于技术文档、博客文章等内容密集型页面。
初识 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
);- 新闻/文章展示页;
- 教育类内容平台;
Typography
插件虽然强大,但并不适用于所有页面类型:
🚫 不太适合
- 高度组件化、视觉自由度高的
UI
模块; - 自定义结构、非标准语义内容(如复杂表单、图表交互);
适用人群
适合以下类型的用户:
初学者
- 能快速获得排版美观的页面,不需要逐个微调每个
HTML
标签的样式;
中高级开发者
- 可自定义主题或通过插件扩展,实现符合设计系统的排版;
- 在构建内容平台、博客、静态站点时能大大节省工作量;
内容创作者/自媒体
- 配合
Headless CMS
、Notion-to-blog
等架构,直接套用生成文章样式;
那么,下一步就让我们真正“动手”,看看如何在项目中使用它,并了解它的基本配置与最佳实践。
Step-by-Step
使用教程
接下来的演示中,以 Next.js
为宿主框架,使用的版本为Tailwind CSS v4
,即使你对 Next.js
不熟悉,也可以完全按照步骤操作,本地也可以运行,我们主要关注Typography
的实际效果。
- 完整示例可查看 GitHub 仓库
- 在线演示查看 Github Pages Demo
先决条件:
- 本机安装了
Node.js 18.18
及以上版本; - 安装
pnpm
创建应用
- 首先创建一个
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
- 安装
@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
打开编辑器,完成下面两个操作:
- 编辑
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 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
是一种 “作用于子元素的样式集”,会生成如下的内容:
.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; }
/* ... 等数百行样式 */
总之:在元素上加上 .prose
,Tailwind 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 |
---|---|---|
sm | 40rem (640px) | @media (width >= 40rem) { ... } |
md | 48rem (768px) | @media (width >= 48rem) { ... } |
lg | 64rem (1024px) | @media (width >= 64rem) { ... } |
xl | 80rem (1280px) | @media (width >= 80rem) { ... } |
2xl | 96rem (1536px) | @media (width >= 96rem) { ... } |
断点的理解:当屏幕宽度达到某个宽度(1280px
)时,应用对应排版风格,本质就是CSS
的media query
,也就是最基础的响应式设计。
相应的,typography
也基于此,提供了5
种不同尺寸的字体大小,size modifiers
。
Class | Body font size |
---|---|
prose-sm | 0.875rem (14px) |
prose-base (default) | 1rem (16px) |
prose-lg | 1.125rem (18px) |
prose-xl | 1.25rem (20px) |
prose-2xl | 1.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>
)
}
如果一切顺利,h1
、h2
、h3
、p
、以及table
的样式都发生了变化,这是最简单的方式,可以通过 prose-[element]:[tailwindcss utitlity]
的方式快速调整成需要的样式。
可以查看tailwindcss utitlity相关文档,来查看其具体的效果;
下表是全部修饰符:
Modifier | Target |
---|---|
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 |
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.css
在app
目录下,而tailwind.config.js
在项目根目录,所以路径使用../
,意思是相对于该目录的上级目录。@config
是tailwindcss
的指令,用来加载基于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-color
在JavaScript
对象中会写成backgroundColor
。 -
值通常是字符串: 大多数 CSS 值仍然是字符串,例如
'#fff'
,'1rem'
。 -
嵌套规则的表示: 对于嵌套的 CSS 规则(如媒体查询、伪类、伪元素),通常会在对象中使用嵌套的对象或特定的语法来表示。
-
使用
DEFAULT
来覆盖默认的样式规则,同时里面使用了Tailwind CSS
中的一些变量,如果不熟悉这些,可以不使用这些变量,直接使用传统CSS
的值。 -
同样
xl
是覆盖了内置的prose-xl
的h1
颜色; -
如果不想修改内置的颜色,可以使用自定义名称,比如:
extend
,在使用时只需要传入prose:extend
即可,该名称可以自定义;
custom.css
是定义要加载自定义的配置,同时在需要使用的页面引入这个样式,即完成了全局样式的处理。
⚠️ 虽然
globals.css
中已经引入了tailwindcss
和typography
,但是如果在该文件中增加自定义配置,会影响全局效果,为了演示其功能,单独增加该文件,重复引用了tailwindcss
和typography
,在生产环境中,尽量避免此类做法,Next.js + Tailwind
的构建流程是:只要CSS
文件被引用,就作为入口构建。所以每个被import
的CSS
文件,都会单独走Tailwind
编译流程。这就使得globals.css
和custom.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>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
都值得作为你的首选排版解决方案。
📎 示例项目源码: