惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

人人都是产品经理
人人都是产品经理
博客园_首页
博客园 - 三生石上(FineUI控件)
V
Visual Studio Blog
Hugging Face - Blog
Hugging Face - Blog
美团技术团队
小众软件
小众软件
T
Tailwind CSS Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
月光博客
月光博客
有赞技术团队
有赞技术团队
WordPress大学
WordPress大学
博客园 - 【当耐特】
Apple Machine Learning Research
Apple Machine Learning Research
罗磊的独立博客
V
V2EX
酷 壳 – CoolShell
酷 壳 – CoolShell
IT之家
IT之家
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Recent Announcements
Recent Announcements
M
MIT News - Artificial intelligence
阮一峰的网络日志
阮一峰的网络日志
The GitHub Blog
The GitHub Blog

Streamdown Documentation

Configuration FAQ Getting Started Introduction Security Animation Carets Code Blocks Components GitHub Flavored Markdown Interactivity Internationalization Link Safety Memoization Migrate from react-markdown Unterminated Block Parsing Typography Usage @streamdown/cjk @streamdown/code Built-in Plugins @streamdown/math @streamdown/mermaid Custom renderers
Styling
Vercel · 2026-04-11 · via Streamdown Documentation

Learn how to customize the appearance of Streamdown components.

Streamdown is designed to be flexible and customizable, allowing you to adapt its appearance to match your application's design system. This guide covers the various ways you can modify Streamdown's styles to suit your needs.

Streamdown components are built using shadcn/ui's design system, which means they use CSS variables for theming. This is the simplest way to customize colors, borders, and other design tokens across all Streamdown components.

Setting Up Variables

Add or modify the CSS variables in your globals.css file:

@layer base {
  :root {
    --background: 0 0% 100%;
    --foreground: 222.2 84% 4.9%;
    --card: 0 0% 100%;
    --card-foreground: 222.2 84% 4.9%;
    --popover: 0 0% 100%;
    --popover-foreground: 222.2 84% 4.9%;
    --primary: 222.2 47.4% 11.2%;
    --primary-foreground: 210 40% 98%;
    --secondary: 210 40% 96.1%;
    --secondary-foreground: 222.2 47.4% 11.2%;
    --muted: 210 40% 96.1%;
    --muted-foreground: 215.4 16.3% 46.9%;
    --accent: 210 40% 96.1%;
    --accent-foreground: 222.2 47.4% 11.2%;
    --destructive: 0 84.2% 60.2%;
    --destructive-foreground: 210 40% 98%;
    --border: 214.3 31.8% 91.4%;
    --input: 214.3 31.8% 91.4%;
    --ring: 222.2 84% 4.9%;
    --radius: 0.5rem;
  }

  .dark {
    --background: 222.2 84% 4.9%;
    --foreground: 210 40% 98%;
    --card: 222.2 84% 4.9%;
    --card-foreground: 210 40% 98%;
    --popover: 222.2 84% 4.9%;
    --popover-foreground: 210 40% 98%;
    --primary: 210 40% 98%;
    --primary-foreground: 222.2 47.4% 11.2%;
    --secondary: 217.2 32.6% 17.5%;
    --secondary-foreground: 210 40% 98%;
    --muted: 217.2 32.6% 17.5%;
    --muted-foreground: 215 20.2% 65.1%;
    --accent: 217.2 32.6% 17.5%;
    --accent-foreground: 210 40% 98%;
    --destructive: 0 62.8% 30.6%;
    --destructive-foreground: 210 40% 98%;
    --border: 217.2 32.6% 17.5%;
    --input: 217.2 32.6% 17.5%;
    --ring: 212.7 26.8% 83.9%;
  }
}

Variables Used by Streamdown

Streamdown components primarily use these CSS variables:

VariableUsageExample Elements
--primaryLinks, accent colorsLinks (<a>)
--primary-foregroundText on primary backgroundsN/A
--mutedSubtle backgroundsCode blocks, table headers
--muted-foregroundDe-emphasized textBlockquote text
--borderBorders and dividersTables, horizontal rules, code blocks
--ringFocus rings on interactive elementsButtons (copy, download)
--radiusBorder radiusCode blocks, tables, buttons

Quick Theme Examples

Minimal Gray Theme:

:root {
  --primary: 0 0% 20%;
  --muted: 0 0% 96%;
  --border: 0 0% 90%;
  --radius: 0.25rem;
}

Vibrant Blue Theme:

:root {
  --primary: 217 91% 60%;
  --muted: 214 100% 97%;
  --border: 214 32% 91%;
  --radius: 0.75rem;
}

No Borders Theme:

:root {
  --border: transparent;
  --muted: 0 0% 98%;
  --radius: 0rem;
}

For structural changes like replacing Markdown elements with custom React components, see the Components documentation.

For simpler styling needs, you can use global CSS to target Streamdown elements using the data-streamdown attribute. Every Streamdown element includes a unique data-streamdown attribute that makes it easy to apply custom styles.

Available Selectors

Target specific Streamdown elements using these data attributes:

/* Headings */
[data-streamdown="heading-1"] { }
[data-streamdown="heading-2"] { }
[data-streamdown="heading-3"] { }
[data-streamdown="heading-4"] { }
[data-streamdown="heading-5"] { }
[data-streamdown="heading-6"] { }

/* Text elements */
[data-streamdown="strong"] { }
[data-streamdown="link"] { }
[data-streamdown="inline-code"] { }

/* Lists */
[data-streamdown="ordered-list"] { }
[data-streamdown="unordered-list"] { }
[data-streamdown="list-item"] { }

/* Blocks */
[data-streamdown="blockquote"] { }
[data-streamdown="horizontal-rule"] { }

/* Code */
[data-streamdown="code-block"] { }
[data-streamdown="mermaid-block"] { }

/* Tables */
[data-streamdown="table-wrapper"] { }
[data-streamdown="table"] { }
[data-streamdown="table-header"] { }
[data-streamdown="table-body"] { }
[data-streamdown="table-row"] { }
[data-streamdown="table-header-cell"] { }
[data-streamdown="table-cell"] { }
[data-streamdown="table-fullscreen"] { }

/* Other */
[data-streamdown="superscript"] { }
[data-streamdown="subscript"] { }

Example Usage

Here's a practical example of customizing Streamdown styles with CSS:

/* Custom heading styles */
[data-streamdown="heading-1"] {
  color: #1a202c;
  border-bottom: 2px solid #e2e8f0;
  padding-bottom: 0.5rem;
}

[data-streamdown="heading-2"] {
  color: #2d3748;
  margin-top: 2rem;
}

/* Custom link appearance */
[data-streamdown="link"] {
  color: #3182ce;
  text-decoration: none;
  border-bottom: 1px solid #90cdf4;
  transition: border-color 0.2s;
}

[data-streamdown="link"]:hover {
  border-bottom-color: #3182ce;
}

/* Custom code block styling */
[data-streamdown="code-block"] {
  border-radius: 0.5rem;
  border: 1px solid #e2e8f0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* Custom table styling */
[data-streamdown="table"] {
  border-radius: 0.5rem;
  overflow: hidden;
}

[data-streamdown="table-header"] {
  background: linear-gradient(to bottom, #f7fafc, #edf2f7);
}

/* Custom blockquote styling */
[data-streamdown="blockquote"] {
  background-color: #f7fafc;
  border-left-color: #4299e1;
  border-radius: 0.25rem;
}

Scoped Styling

You can scope your styles to specific instances of Streamdown by using the className prop:

<Streamdown className="docs-content">
  {markdown}
</Streamdown>
/* Styles only apply to this specific instance */
.docs-content [data-streamdown="heading-1"] {
  font-family: 'Inter', sans-serif;
  letter-spacing: -0.02em;
}

.docs-content [data-streamdown="code-block"] {
  font-family: 'Fira Code', monospace;
}

For maximum flexibility, you can combine both approaches - using custom components for structural changes and CSS for visual styling:

<Streamdown
  className="custom-markdown"
  components={{
    h1: ({ children, ...props }) => (
      <h1 {...props}>
        <span className="heading-icon">📖</span>
        {children}
      </h1>
    ),
  }}
>
  {markdown}
</Streamdown>
.custom-markdown [data-streamdown="heading-1"] {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.custom-markdown .heading-icon {
  font-size: 1.5rem;
}

Beyond component overrides and CSS, Streamdown provides additional styling-related props:

Container Class Name

Use the className prop to add custom classes to the Streamdown container:

<Streamdown className="prose prose-lg dark:prose-invert max-w-none">
  {markdown}
</Streamdown>

Syntax Highlighting Themes

Customize code block appearance with Shiki themes:

<Streamdown
  shikiTheme={['github-light', 'github-dark']}
>
  {markdown}
</Streamdown>

See the Code Blocks documentation for more details on syntax highlighting customization.

If your project uses Tailwind v4's prefix() feature to namespace utility classes, pass the same prefix to Streamdown so its internal classes match:

<Streamdown prefix="tw">{markdown}</Streamdown>

With the matching Tailwind config:

@import "tailwindcss" prefix(tw);

This transforms all internal utility classes from flex to tw:flex, items-center to tw:items-center, and so on.

The prefix also applies to user-supplied className values. If you pass className="prose max-w-none", Streamdown outputs tw:prose tw:max-w-none.

When customizing Streamdown styles, consider these best practices:

  1. Start with CSS Variables - For most theming needs (colors, borders, radius), modifying CSS variables in globals.css is the simplest and most maintainable approach.

  2. Use data-streamdown Selectors for Specific Elements - When you need to target individual elements without affecting the entire theme, use the data-streamdown attribute selectors.

  3. Use Custom Components for Structural Changes - When you need to change the HTML structure or add wrapper elements, use the components prop. See the Components documentation for details.

  4. Maintain Accessibility - Ensure your custom styles maintain proper color contrast, focus states, and semantic HTML structure.

  5. Test During Streaming - Verify that your custom styles work well with incomplete content during streaming.

  6. Scope Your Styles - Use the className prop to scope styles and avoid conflicts with other parts of your application.

  7. Preserve Animations - Streamdown includes built-in animations for smooth streaming. Be careful not to override animation-related classes unless intentional.

The three styling approaches have the following priority (highest to lowest):

  1. Custom Components - Complete control over rendering
  2. CSS via data-streamdown selectors - Element-specific styling
  3. CSS Variables - Global theme tokens