Prose Customization
Customize the typography plugin to match your design system
The prose utility styles long-form content — blog posts, documentation, anything generated from Markdown. It comes with sensible defaults out of the box, but you'll often want to tune individual elements (links, blockquotes, code blocks) to match your design system. That's what ProseCustomization is for.
Adding Element Rules
ProseCustomization takes a function that receives the current theme and returns a per-modifier dictionary of element rules. The modifier keys are "DEFAULT", "base", "sm", "lg", "xl", "2xl", and "invert" — the same set you reach for in markup with prose-lg, prose-invert, etc.
public static CssFramework Build()
{
var customization = new ProseCustomization
{
Customization = _ => new Dictionary<string, ProseElementRules>
{
["DEFAULT"] = new()
{
Rules = new ProseElementRule
{
Selector = "a",
Declarations =
[
new ProseDeclaration { Property = "font-weight", Value = "700" },
new ProseDeclaration { Property = "text-decoration-line", Value = "underline" },
],
},
},
["lg"] = new()
{
Rules = new ProseElementRule
{
Selector = "blockquote",
Declarations = new ProseDeclaration { Property = "font-weight", Value = "600" },
},
},
}.ToImmutableDictionary(),
};
return new CssFramework(new CssFrameworkSettings
{
Theme = new ThemeModel(),
ProseCustomization = customization,
});
}
Two things are happening here: every link inside a prose block becomes bold and underlined (in DEFAULT), and blockquotes get a heavier font-weight when the user opts into prose-lg (in lg).
Element Rules in Detail
Each ProseElementRule has:
Selector— any CSS selector."a","blockquote","pre > code","h2 + p"all work.Declarations— the properties to apply.UseWhereWrapper(defaulttrue) — wraps the selector in:where()so it doesn't compete with utility specificity.ExcludeClass(default"not-prose") — gives users an escape hatch: anything inside<div class="not-prose">is exempt.
Pulling From the Theme
The customization function receives the theme so you can reference design tokens:
Customization = theme => /* ... */
Inside your ProseDeclaration values you can use var(--color-brand-500) directly, knowing those CSS variables are emitted alongside the prose rules.
Next steps
- Add the brand colors prose pulls from in theme & colors.
- See every customization point assembled in one full example.