Empty States

Empty states communicate when there’s no content to display. A good empty state guides users toward their next action instead of leaving them confused.


Basic Empty State

A centered message with optional icon and action.

No items yet

Get started by creating your first item.

<div class="EmptyState">
<div class="EmptyState-icon">
<i class="ph ph-package"></i>
</div>
<h3 class="EmptyState-title">No items yet</h3>
<p class="EmptyState-description">Get started by creating your first item.</p>
<button class="Button Button--primary">Create Item</button>
</div>
<div class="EmptyState">
    <div class="EmptyState-icon">
        <i class="ph ph-package"></i>
    </div>
    <h3 class="EmptyState-title">No items yet</h3>
    <p class="EmptyState-description">Get started by creating your first item.</p>
    <button class="Button Button--primary">Create Item</button>
</div>

With Illustration

Replace the icon with a custom illustration for more personality.

Your inbox is empty

When you receive messages, they'll appear here.

<div class="EmptyState">
<div class="EmptyState-illustration">
<svg width="120" height="120" viewBox="0 0 120 120" fill="none">
<circle cx="60" cy="60" r="50" fill="var(--bg-s)" stroke="var(--bd)" stroke-width="2"/>
<path d="M40 55 L60 75 L80 55" stroke="var(--accent)" stroke-width="4" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
<circle cx="60" cy="40" r="6" fill="var(--accent)"/>
</svg>
</div>
<h3 class="EmptyState-title">Your inbox is empty</h3>
<p class="EmptyState-description">When you receive messages, they'll appear here.</p>
</div>
<div class="EmptyState">
    <div class="EmptyState-illustration">
        <img src="empty-inbox.svg" alt="">
    </div>
    <h3 class="EmptyState-title">Your inbox is empty</h3>
    <p class="EmptyState-description">When you receive messages, they'll appear here.</p>
</div>

Compact Variant

For smaller containers like sidebars or cards.

No documents

<div style="max-width: 280px; border: 1px solid var(--bd); border-radius: var(--r-m); padding: var(--space-4);">
<div class="EmptyState EmptyState--compact">
<div class="EmptyState-icon">
<i class="ph ph-file-text"></i>
</div>
<p class="EmptyState-description">No documents</p>
<button class="Button Button--primary" style="font-size: 0.85rem; padding: var(--space-1) var(--space-3);">Upload</button>
</div>
</div>
<div class="EmptyState EmptyState--compact">
    <div class="EmptyState-icon">
        <i class="ph ph-file-text"></i>
    </div>
    <p class="EmptyState-description">No documents</p>
    <button class="Button Button--primary">Upload</button>
</div>

Search Results

When a search or filter returns no matches.

No results found

We couldn't find anything matching "quantum flux capacitor". Try different keywords or check for typos.

<div class="EmptyState">
<div class="EmptyState-icon">
<i class="ph ph-magnifying-glass"></i>
</div>
<h3 class="EmptyState-title">No results found</h3>
<p class="EmptyState-description">We couldn't find anything matching "quantum flux capacitor". Try different keywords or check for typos.</p>
<div class="Layout-cluster" style="justify-content: center;">
<button class="Button">Clear Search</button>
<button class="Button Button--primary">Browse All</button>
</div>
</div>
<div class="EmptyState">
    <div class="EmptyState-icon">
        <i class="ph ph-magnifying-glass"></i>
    </div>
    <h3 class="EmptyState-title">No results found</h3>
    <p class="EmptyState-description">Try different keywords or check for typos.</p>
    <div class="Layout-cluster">
        <button class="Button">Clear Search</button>
        <button class="Button Button--primary">Browse All</button>
    </div>
</div>

Error State

When something goes wrong loading content.

Unable to load data

Something went wrong on our end. Please try again or contact support if the problem persists.

<div class="EmptyState EmptyState--error">
<div class="EmptyState-icon">
<i class="ph ph-warning-circle"></i>
</div>
<h3 class="EmptyState-title">Unable to load data</h3>
<p class="EmptyState-description">Something went wrong on our end. Please try again or contact support if the problem persists.</p>
<div class="Layout-cluster" style="justify-content: center;">
<button class="Button Button--primary">
<i class="ph ph-arrow-clockwise"></i>
Retry
</button>
<button class="Button">Contact Support</button>
</div>
</div>
<div class="EmptyState EmptyState--error">
    <div class="EmptyState-icon">
        <i class="ph ph-warning-circle"></i>
    </div>
    <h3 class="EmptyState-title">Unable to load data</h3>
    <p class="EmptyState-description">Something went wrong...</p>
    <button class="Button Button--primary">Retry</button>
</div>

First-Time User

Onboarding empty states that guide new users.

Welcome to your dashboard!

You're all set up. Here's how to get started:

1 Create your first project
2 Invite team members
3 Start collaborating
<div class="EmptyState">
<div class="EmptyState-icon" style="background: oklch(55% 0.15 150 / 0.1); color: oklch(55% 0.15 150);">
<i class="ph ph-rocket-launch"></i>
</div>
<h3 class="EmptyState-title">Welcome to your dashboard!</h3>
<p class="EmptyState-description">You're all set up. Here's how to get started:</p>
<div class="Layout-stack Layout-stack--tight" style="text-align: left; max-width: 300px; margin: var(--space-4) auto 0;">
<div style="display: flex; gap: var(--space-3); align-items: flex-start;">
<span class="Badge Badge--primary" style="border-radius: 50%; min-width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;">1</span>
<span>Create your first project</span>
</div>
<div style="display: flex; gap: var(--space-3); align-items: flex-start;">
<span class="Badge" style="border-radius: 50%; min-width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;">2</span>
<span style="color: var(--fg-3);">Invite team members</span>
</div>
<div style="display: flex; gap: var(--space-3); align-items: flex-start;">
<span class="Badge" style="border-radius: 50%; min-width: 24px; height: 24px; display: flex; align-items: center; justify-content: center;">3</span>
<span style="color: var(--fg-3);">Start collaborating</span>
</div>
</div>
<button class="Button Button--primary" style="margin-top: var(--space-4);">Create Project</button>
</div>

In Cards

Empty states within card components.

No data to display

No team members

Invite people
<div class="Layout-grid" style="width: 100%;">
<div class="Layout-col-12">
<div class="Card" style="height: 200px;">
<div class="Card-body" style="height: 100%; display: flex; align-items: center; justify-content: center;">
<div class="EmptyState EmptyState--compact">
<i class="ph ph-chart-line" style="font-size: 2rem; color: var(--fg-3);"></i>
<p class="EmptyState-description">No data to display</p>
</div>
</div>
</div>
</div>
<div class="Layout-col-12">
<div class="Card" style="height: 200px;">
<div class="Card-body" style="height: 100%; display: flex; align-items: center; justify-content: center;">
<div class="EmptyState EmptyState--compact">
<i class="ph ph-users" style="font-size: 2rem; color: var(--fg-3);"></i>
<p class="EmptyState-description">No team members</p>
<a href="#" class="Link" style="font-size: 0.85rem;">Invite people</a>
</div>
</div>
</div>
</div>
</div>

In Tables

Empty state for table components.

Name Status Date Actions

No records found

Create a new record to get started.

<div style="border: 1px solid var(--bd); border-radius: var(--r-m); overflow: hidden;">
<table class="Table" style="margin: 0;">
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Date</th>
<th>Actions</th>
</tr>
</thead>
</table>
<div class="EmptyState" style="padding: var(--space-8);">
<div class="EmptyState-icon">
<i class="ph ph-clipboard-text"></i>
</div>
<h3 class="EmptyState-title">No records found</h3>
<p class="EmptyState-description">Create a new record to get started.</p>
<button class="Button Button--primary">Add Record</button>
</div>
</div>

Best Practices

Content Guidelines

Element Guideline
Title Clear, concise — what’s missing
Description Why it’s empty + what to do next
Action Primary CTA to resolve the state
Tone Helpful, not apologetic

Do

  • Explain the situation — Tell users why there’s no content
  • Provide a clear action — Give them something to do
  • Use appropriate visuals — Icons or illustrations that match context
  • Keep it simple — One primary action, maybe a secondary
  • Match the context — Use compact variant in small containers like cards or sidebars
  • Differentiate error from empty — Use the error variant when content failed to load vs. simply not existing yet

Don’t

  • Leave it blank — An empty container is confusing
  • Be overly verbose — Keep copy short and scannable
  • Use generic messages — “No data” doesn’t help anyone
  • Hide the state — Make it visible so users understand
  • Stack multiple empty states — If a page has several empty sections, consolidate into one page-level message
  • Blame the user — Say “No results found” not “You didn’t search correctly”

CSS Reference

/* Base */
.EmptyState {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-8);
  min-height: 200px;
}

.EmptyState-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background-color: var(--bg-s);
  color: var(--fg-3);
  font-size: 2rem;
  margin-bottom: var(--space-4);
}

.EmptyState-illustration {
  margin-bottom: var(--space-4);
}

.EmptyState-illustration img,
.EmptyState-illustration svg {
  max-width: 160px;
  height: auto;
}

.EmptyState-title {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--fg);
  margin: 0 0 var(--space-2);
}

.EmptyState-description {
  font-size: 0.9rem;
  color: var(--fg-3);
  max-width: 320px;
  margin: 0 0 var(--space-4);
}

/* Compact variant */
.EmptyState--compact {
  padding: var(--space-4);
  min-height: auto;
}

.EmptyState--compact .EmptyState-icon {
  width: 48px;
  height: 48px;
  font-size: 1.5rem;
  margin-bottom: var(--space-3);
}

.EmptyState--compact .EmptyState-title {
  font-size: 1rem;
}

.EmptyState--compact .EmptyState-description {
  font-size: 0.85rem;
  margin-bottom: var(--space-3);
}

/* Error variant */
.EmptyState--error .EmptyState-icon {
  background-color: oklch(55% 0.2 25 / 0.1);
  color: oklch(55% 0.2 25);
}