Prose
Typography styles for long-form content and markdown rendering
Overview
The s-prose component applies sensible typography defaults to long-form content like articles, blog posts, and markdown-rendered content. Instead of adding classes to every element, wrap your content and let the component handle the styling.
Import
/* Full framework (includes all components) */
@import "@shift-css/core";
/* Or import just the prose component */
@import "@shift-css/core/components/prose";
Note: When importing individual components, you also need
@shift-css/core/resetand@shift-css/core/tokensfor the base styles and design tokens.
Basic Usage
<article s-prose>
<h1>Article Title</h1>
<p>This is a paragraph with <a href="#">a link</a> and <code>inline code</code>.</p>
<h2>Section Heading</h2>
<p>More content here...</p>
<ul>
<li>List item one</li>
<li>List item two</li>
</ul>
<blockquote>
A notable quote or callout.
</blockquote>
<pre><code>const example = "code block";</code></pre>
</article>
Features
The prose component automatically styles:
- Headings (h1-h6) with proper hierarchy and spacing
- Paragraphs with comfortable line-height and margins
- Links with underlines and hover states
- Lists (ul, ol, dl) with proper indentation and markers
- Blockquotes with left border accent
- Code (inline and blocks) with syntax-appropriate styling
- Tables with borders and hover states
- Images and figures with captions
- Horizontal rules for section breaks
Variants
Full Width
By default, prose content is limited to 65 characters for optimal readability. Use the full variant to remove this limit:
<article s-prose="full">
<!-- Content spans full container width -->
</article>
Size Variants
Adjust the base font size:
<article s-prose s-size="sm">
<!-- Smaller text for compact layouts -->
</article>
<article s-prose s-size="lg">
<!-- Larger text for hero sections -->
</article>
| Attribute | Base Font Size |
|---|---|
s-size="sm" | --s-text-sm (0.875rem) |
| default | --s-text-base (1rem) |
s-size="lg" | --s-text-lg (1.125rem) |
Element Styling
Headings
Headings use a clear hierarchy with proper spacing:
<article s-prose>
<h1>Page Title</h1> <!-- 2.25rem, no top margin -->
<h2>Major Section</h2> <!-- 1.875rem, border-bottom -->
<h3>Subsection</h3> <!-- 1.5rem -->
<h4>Minor Heading</h4> <!-- 1.25rem -->
<h5>Small Heading</h5> <!-- 1.125rem -->
<h6>Tiny Heading</h6> <!-- 1rem, muted color -->
</article>
Links
Links are styled with underlines and smooth color transitions:
<article s-prose>
<p>Visit the <a href="/docs">documentation</a> for more info.</p>
</article>
Code
Inline code gets a subtle background, while code blocks have a dark theme:
<article s-prose>
<p>Use the <code>s-prose</code> attribute for content.</p>
<pre><code>// Code blocks use dark background
const framework = "Shift CSS";</code></pre>
</article>
Blockquotes
Blockquotes feature a colored left border and subtle background:
<article s-prose>
<blockquote>
<p>Design is not just what it looks like and feels like. Design is how it works.</p>
<p>— Steve Jobs</p>
</blockquote>
</article>
Lists
Both ordered and unordered lists are supported with proper nesting:
<article s-prose>
<ul>
<li>First item</li>
<li>Second item
<ul>
<li>Nested item</li>
</ul>
</li>
</ul>
<ol>
<li>Step one</li>
<li>Step two</li>
</ol>
<dl>
<dt>Term</dt>
<dd>Definition of the term</dd>
</dl>
</article>
Tables
Tables are full-width with hover states:
<article s-prose>
<table>
<thead>
<tr>
<th>Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td>Primary</td>
<td>Blue</td>
</tr>
<tr>
<td>Secondary</td>
<td>Teal</td>
</tr>
</tbody>
</table>
</article>
Images & Figures
Images get rounded corners, and figures support captions:
<article s-prose>
<figure>
<img src="/screenshot.png" alt="Screenshot" width="800" height="600" />
<figcaption>A screenshot of the interface</figcaption>
</figure>
</article>
Customization
Override prose CSS properties for custom styling:
[s-prose] {
/* Typography */
--_prose-body: var(--s-text-lg);
--_prose-leading: 1.8;
/* Links */
--_prose-link-color: var(--s-accent-600);
--_prose-link-hover: var(--s-accent-700);
/* Code */
--_prose-code-bg: var(--s-primary-100);
--_prose-code-color: var(--s-primary-700);
--_prose-pre-bg: var(--s-neutral-800);
--_prose-pre-color: var(--s-neutral-100);
/* Borders & Accents */
--_prose-border-color: var(--s-border-muted);
--_prose-quote-border: var(--s-accent-500);
}
Common Patterns
Blog Post Layout
<main s-container="prose">
<article s-prose>
<header>
<h1>Blog Post Title</h1>
<p><time datetime="2025-01-21">January 21, 2025</time></p>
</header>
<p>Introduction paragraph...</p>
<h2>First Section</h2>
<p>Content...</p>
<footer>
<hr />
<p>Written by <a href="/author">Author Name</a></p>
</footer>
</article>
</main>
Documentation Page
<div s-flex>
<aside><!-- Sidebar navigation --></aside>
<main s-prose>
<h1>API Reference</h1>
<h2>Installation</h2>
<pre><code>npm install @shift-css/core</code></pre>
<h2>Usage</h2>
<p>Import the framework in your CSS:</p>
<pre><code>@import "@shift-css/core";</code></pre>
</main>
</div>
Markdown Content
When rendering markdown (e.g., from a CMS or static site generator), simply wrap the output:
<article s-prose>
{{ content | safe }}
</article>
Dark Mode
The prose component automatically adjusts colors for dark mode:
- Link colors become lighter for visibility
- Code backgrounds shift to darker tones
- Inline code uses softer accent colors
No additional configuration needed—it works with Shift CSS’s automatic light-dark() theming.