prose 是强语义绑定的全局排版系统,会污染非文章区域;需通过唯一前缀类隔离作用域、禁用 prose-invert、禁用组件内原生语义标签、精简 typography 配置来防控。

prose 类不是“加了就完事”的装饰,它是一套强语义绑定的排版系统;一旦用在非文章容器里,会把 p、h2、ul 等全局标签样式强行覆盖,导致按钮文字变小、表单控件错位、UI 库弹窗标题挤成一团——这不是“样式没生效”,而是它太生效了。
prose 为什么一加就污染整个页面?
插件默认注入在 @layer base,作用域是全局匹配 .prose > *:not(.prose > *) 下的所有标准语义标签。这意味着:只要你在某个 <div class="prose"> 里写了 <code><p></p>,它就会重置该 p 的 margin、line-height、font-size,哪怕这个 p 其实是按钮文案或表单项提示。
- prose 不区分“内容区”和“组件区”,只认 class 和 HTML 标签结构
- 它对
h1–h6、blockquote、pre、ol、ul等全部做深度样式接管,且这些规则无法被普通工具类(如text-sm)覆盖 - 如果你在
prose容器里嵌套了 Element Plus 的<el-button></el-button>,它的内部span或div若被 prose 的通配规则误匹配(比如用了prose p但子元素含p),字体和行高就全乱了
怎么让 prose 只作用于真正的文章区域?
核心思路是物理隔离 + 选择器收束,而不是靠“尽量少用”。必须确保 prose 规则不会泄漏到业务组件中。
- 给文章容器加唯一前缀类,比如
article-content,然后在tailwind.config.js中配置 typography 的 selector:theme: { extend: { typography: { DEFAULT: { css: { '--tw-prose-body': 'var(--tw-prose-lead)', // 关键:限定只作用于 article-content 下的 prose selector: '.article-content .prose' } } } } } - HTML 中严格写成:
<div class="article-content"><div class="prose">...</div></div>,别把prose直接挂在body或根级div上 - 禁用 prose-invert(除非你真有深色模式反色需求),它单独增加约 12KB CSS,且所有 invert 规则都会作用于整个
.prose区域,进一步扩大污染面
UI 组件里的文本被 prose 拉垮了怎么办?
常见现象:Ant Design Vue 的 <a-card></a-card> 里放了个 <p></p>,结果段间距爆炸、字体变细、链接无下划线——因为 prose 把它当作文本段落处理了。
- 最稳妥的做法:UI 组件内部禁止使用原生语义标签承载 UI 文本。改用
<span></span>、<div> 并加明确工具类,例如:<code><div class="text-sm text-gray-600">操作说明</div> - 如果必须用
p,就在组件 scoped style 或 CSS Modules 里强制重置:.my-card p { @apply m-0 text-base font-normal; }注意:这条规则必须比 prose 的 base 层级更靠后(即放在@tailwind utilities之后),否则会被覆盖 - 别试图用
prose-none去“关掉”某一块——Tailwind 官方没提供这个类,硬写会破坏 prose 内部的垂直节奏计算逻辑
性能与维护上最容易被忽略的一点
prose 插件默认加载全部 5 种尺寸(sm/base/lg/xl/2xl)和全部 HTML 元素样式(blockquote、pre、table 等)。你只用 p 和 h2,却要为 figure 和 dl 多打包几 KB CSS——而这些未使用的规则,恰恰是未来某次重构时最可能被误触发的污染源。
务必在 tailwind.config.js 中精简:
typography: {
modifiers: ['base', 'lg'],
elements: {
blockquote: false,
pre: false,
table: false,
figure: false,
dl: false,
}
} 这不是可选项,是防止 prose 在你没注意的地方悄悄改掉按钮内边距的关键防线。











