Skip to main content

Your Design System Should Style Your Words, Too

Web Awesome gives your prose the same design-system treatment as your components: one class for automatic content styling, a full type scale for manual control, and text utilities within reach. Plus CSS @scope keeps it from bleeding where it shouldn't. That's coverage most design systems leave to you.


Nearly every product has a blog. Most have documentation and a changelog too. And almost every team ends up styling that content from scratch, with a custom typography stylesheet somebody wrote once, nobody owns, and everyone quietly dreads. That stylesheet exists because design systems typically end where flowing content begins.

Web Awesome covers that with three tools: an automatic mode that styles entire content blocks, a type scale you can apply manually anywhere, and text utilities for alignment and casing. Between them, you can handle a blog post, a docs page, or a long-form article without writing a typography stylesheet.

Here's how.

The One-Class Route with Prose

Wrap your content in a wa-prose container, and every typographic element inside it picks up spacing, sizing, and rhythm that match your theme.

<div class="wa-prose">
	<h1>Release Notes: v3.2</h1>
	<p>
		This release includes improvements to form validation, a new color picker
		component, and performance fixes across the board.
	</p>
	<h2>What's New</h2>
	<ul>
		<li>Color picker with alpha channel support</li>
		<li>Form validation messages now animate in</li>
	</ul>
	<blockquote>
		<p>
			"The best component library update is the one you don't have to migrate."
			— nobody, but it should be everyone
		</p>
	</blockquote>
	<pre><code>npm install @aspect/core@3.2</code></pre>
</div>

That's it. Headings fall onto a hierarchical scale, paragraphs get a comfortable line height, lists indent consistently. Blockquotes pick up a left border with a subtle inset. Code blocks get proper spacing (the visual styling comes from Native Styles, Web Awesome's base layer for standard HTML elements). The whole system hangs off a single token, --wa-space-scale, so swap themes and your prose syncs up.

The point of wa-prose is that you don't think about it. Drop CMS content, a Markdown-rendered article, or hand-authored HTML into the wrapper, and it reads well. No class-per-element surgery.

See it in Action: Holodeck Incident 47225.7 Entry

A Star Trek captain's log styled with a single wa-prose class. Headings, paragraphs, lists, blockquotes, tables, figures, and code blocks, all handled automatically with zero interior classes. Prose makes it so.

See the Pen Web Awesome's Word Styling: Prose Example by Web Awesome (@webawesome) on CodePen.

Prose That Stays in Its Lane

Styling everything inside a container only works if it stays inside that container. If your article's heading styles leak into an embedded component, you're back to writing overrides. Just in a different place.

wa-prose uses CSS @scope under the hood. @scope lets styles flow down from a root and stop at a boundary, so when you embed a component inside your article, the prose typography stays put.

<div class="wa-prose">
	<h2>This heading gets prose styles</h2>
	<p>So does this paragraph.</p>

	<div class="wa-not-prose">
		<!-- Everything in here is untouched by prose styles -->
		<wa-card>
			<h2>This heading is the card's business</h2>
		</wa-card>
	</div>

	<p>Back to prose styles here.</p>
</div>

One class opts in, the other opts out. No specificity wars, no !important overrides. wa-prose can style headings, lists, tables, and blockquotes aggressively because wa-not-prose keeps it honest at the boundary.

Picking Sizes by Hand

wa-prose works when you control the container. But plenty of text lives outside a prose block: a hero headline, a card title, a caption under a product image, a metadata line in a sidebar. These need the same typographic scale without the full prose treatment.

That's where the standalone type classes come in. Three families, each available bare (style without forcing a size) or with a clear stop from 3xs up to 5xl. All three families share the same range, so you're always working on one scale.

Headings

wa-heading for default heading treatment, or wa-heading-3xs through wa-heading-5xl when you need a specific size.

<!-- Hero headline: not inside wa-prose, but on the same scale -->
<h1 class="wa-heading-4xl">
	Build with components.
	<br />
	Ship real products.
</h1>

<!-- Card title: just needs heading treatment, default size -->
<h3 class="wa-heading">Latest from the blog</h3>

Body

wa-body for base body copy, or sized variants for when the default doesn't fit.

<!-- Sidebar description: slightly smaller than default body -->
<p class="wa-body-sm">
	Updated weekly with framework guides, release notes, and community highlights.
</p>

Captions

wa-caption for small supporting text: image credits, metadata, timestamps.

<!-- Image caption -->
<figcaption class="wa-caption">
	Fig 3. Component rendering benchmark: Lit vs React vs Svelte
</figcaption>

<!-- Metadata line -->
<span class="wa-caption">Published Mar 14, 2025 · 8 min read</span>

These aren't a parallel system. Both wa-prose and the manual type classes pull from the same design tokens, so a wa-heading-2xl on a card and an <h2> inside wa-prose always match up. One system, two access patterns. Automatic inside prose, manual everywhere else.

See it in Action: Ratatouille Was Right Article

A food essay where the body is wa-prose and nothing around it is. Eyebrow labels, metadata, an author card, footnotes, suggestion cards: all placed by hand.

See the Pen Web Awesome's Word Styling: Type Sizing Example by Web Awesome (@webawesome) on CodePen.

Nudging Alignment and Case

The type scale classes handle what size your text is. The text utilities handle everything else: alignment and casing. They compose with both wa-prose and the manual classes, so you can center a pull quote or uppercase an eyebrow label without custom CSS.

Alignment

wa-text-start, wa-text-center, wa-text-end, wa-text-justify.

These use logical properties (start/end rather than left/right), so they flip automatically in RTL layouts.

<!-- Centered pull quote -->
<blockquote class="wa-text-center wa-heading-lg">
	Design systems should have opinions about typography. Most don't.
</blockquote>

<!-- Justified body copy for a print-style article (use sparingly in narrow columns) -->
<div class="wa-prose wa-text-justify">...</div>

That second example works because wa-prose never sets text-align. It deliberately leaves that gap for you to fill. Composing the two on the same element is the intended pattern.

Casing

wa-text-uppercase, wa-text-lowercase, wa-text-capitalize.

<!-- Eyebrow label above a section -->
<span class="wa-caption wa-text-uppercase">Case Study</span>

<!-- Normalize user-entered headings -->
<h2 class="wa-heading-xl wa-text-capitalize"></h2>

See it in Action: Thneed Changelog

A fictitious product changelog built entirely without wa-prose. Every piece of text is placed on the scale manually: wa-heading-4xl for the page title, wa-caption wa-text-uppercase for category labels, wa-body-sm for change descriptions.

See the Pen Web Awesome's Word Styling: Text Utilities Example by Web Awesome (@webawesome) on CodePen.

Get Started

Check your <head> first. Every class in this post lives in utilities.css, and the element styling underneath prose comes from native.css, which the install docs list as optional. For long-form content it isn't.

<!-- Required: default theme + autoloader -->
<link
	rel="stylesheet"
	href="https://ka-f.webawesome.com/webawesome@3.12.0/styles/themes/default.css"
/>
<script
	type="module"
	src="https://ka-f.webawesome.com/webawesome@3.12.0/webawesome.loader.js"
></script>

<!-- Utility classes: wa-prose, the type scale, the text utilities -->
<link
	rel="stylesheet"
	href="https://ka-f.webawesome.com/webawesome@3.12.0/styles/utilities.css"
/>

<!-- Native Styles: color, fonts, and borders for the elements inside your prose -->
<link
	rel="stylesheet"
	href="https://ka-f.webawesome.com/webawesome@3.12.0/styles/native.css"
/>

Prefer one line? styles/webawesome.css pulls in all three.

Then wrap your content container in wa-prose and see how far one class gets you. When you need to break out of the defaults (a hero heading here, a caption there), reach for the type scale classes.

Dig Into the Docs

Prose Docs Text Utilities Docs Typography Tokens

One note: syntax highlighting isn't included with Web Awesome. Bring your own Prism, Shiki, or highlight.js.