Empty State Examples

An empty state is what a screen shows when there is nothing to list yet: a new account, a search with no matches, a cleared inbox or a failed load. Each needs a plain explanation and a way forward. The ten designs below cover every common case with editable HTML and CSS, plus a builder that writes accessible markup.

The five kinds of empty and what each should offer
KindWhy it is emptyPrimary action
First useNothing has been created yetCreate the first item, or import
No resultsA search or filter matched nothingClear filters or change the search
All doneThe user finished everythingNone needed; confirm the good news
ErrorData failed to loadTry again, with a short reason
No accessThe user lacks permissionRequest access or switch account

Updated

Empty screens are the first thing new users meet and the place people land after a search goes wrong, yet they are often a grey box saying No data. These examples treat each kind of empty differently, because the right message after a typo is not the right message on day one. Every snippet is self-contained and uses plain shapes rather than stock illustrations.

Empty state builder

Write the heading, sentence and button, pick the kind, and copy accessible HTML and CSS. Starting output:

<div class="empty" role="status">
  <div class="empty-art" aria-hidden="true"></div>
  <h2>No invoices yet</h2>
  <p>Invoices you send will appear here, with their status and due date.</p>
  <button type="button">Create an invoice</button>
</div>
.empty { max-width: 360px; margin: 0 auto; padding: 32px 20px; text-align: center; }
.empty-art { width: 56px; height: 56px; margin: 0 auto 12px; border-radius: 14px; border: 2px dashed #2563eb; }
.empty h2 { margin: 0 0 6px; font-size: 18px; }
.empty p { margin: 0 0 16px; color: #4b5563; }
.empty button { padding: 9px 16px; border: 0; border-radius: 8px; background: #2563eb; color: #fff; font-weight: 600; }

First use

1. Create your first item

A dashed outline hints at where the item will appear. The button is inside the empty area so nobody hunts for it.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  .box { padding: 28px 16px; border: 2px dashed #93c5fd; border-radius: 14px }
  .btn { background: #2563eb; color: #fff }
</style>
<div class="es box"><h2>No projects yet</h2><p>Projects hold your pages, images and settings.</p><button class="btn">New project</button></div>

2. Two ways to start

Offering create or import respects people who already have data elsewhere.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  .row { display: flex; gap: 8px; justify-content: center; flex-wrap: wrap }
  .a { background: #111827; color: #fff } .b { background: #fff; color: #111827; border: 1px solid #d1d5db }
</style>
<div class="es"><h2>Your contact list is empty</h2><p>Add people one at a time or bring in a CSV from another tool.</p><div class="row"><button class="btn a">Add contact</button><button class="btn b">Import CSV</button></div></div>

3. Setup checklist

A short list with the first step marked turns an empty dashboard into a plan.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  ol { text-align: left; margin: 0 auto 14px; padding-left: 20px; max-width: 260px }
  li.done { color: #9ca3af; text-decoration: line-through }
</style>
<div class="es"><h2>Let's get your shop ready</h2><ol><li class="done">Create account</li><li><strong>Add your first product</strong></li><li>Connect payments</li></ol><button class="btn" style="background:#059669;color:#fff">Add product</button></div>

4. Labelled sample content

A clearly marked example row shows what the screen will look like once it is full.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  table { width: 100%; border-collapse: collapse; font-size: 14px; margin-bottom: 12px }
  td { padding: 8px; border: 1px dashed #cbd5e1; color: #64748b }
  .tag { font-size: 11px; padding: 2px 6px; border-radius: 6px; background: #fef3c7; color: #92400e }
</style>
<div class="es"><table><tr><td>Example: Website redesign</td><td>Due 30 Oct</td><td><span class="tag">Sample</span></td></tr></table><p>Tasks you add will replace this example.</p><button class="btn" style="background:#4f46e5;color:#fff">Add a task</button></div>

No results and filters

5. No search results

Repeat the term, suggest fixes, and keep a way back to everything.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  q { font-weight: 600 } ul { text-align: left; max-width: 240px; margin: 0 auto 12px; color: #4b5563 }
</style>
<div class="es"><h2>No matches for <q>blue tshirt</q></h2><ul><li>Check the spelling</li><li>Try a shorter word, such as shirt</li></ul><a href="#">Browse all clothing</a></div>

6. Filters hide everything

Showing the active filters as removable chips points straight at the cause.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  .chips { display: flex; gap: 6px; justify-content: center; flex-wrap: wrap; margin-bottom: 12px }
  .chips span { padding: 4px 10px; border-radius: 999px; background: #e0e7ff; font-size: 13px }
  .btn { background: #fff; border: 1px solid #6366f1; color: #4338ca }
</style>
<div class="es" role="status"><h2>No orders match these filters</h2><div class="chips"><span>Status: Refunded</span><span>Last 7 days</span></div><button class="btn">Clear filters</button></div>

All done, errors and access

7. Inbox zero

Some empty screens are good news. A calm confirmation is enough; no button needed.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  .tick { width: 48px; height: 48px; margin: 0 auto 10px; border-radius: 50%; background: #dcfce7; color: #15803d; font-size: 26px; line-height: 48px }
</style>
<div class="es"><div class="tick" aria-hidden="true">&#10003;</div><h2>You're all caught up</h2><p>New messages will show up here.</p></div>

8. Failed to load

Name the problem honestly, say the data is safe if it is, and offer a retry.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  .box { padding: 20px; border-radius: 12px; background: #fef2f2 }
  .btn { background: #b91c1c; color: #fff }
</style>
<div class="es box"><h2>We couldn't load your invoices</h2><p>Your data is safe. Check your connection and try again.</p><button class="btn">Try again</button></div>

9. No permission

Tell people who to ask, and give them a button that does the asking.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  .lock { width: 40px; height: 34px; margin: 0 auto 12px; border: 3px solid #64748b; border-radius: 6px; position: relative }
  .lock::before { content: ""; position: absolute; left: 7px; top: -18px; width: 20px; height: 16px; border: 3px solid #64748b; border-bottom: 0; border-radius: 12px 12px 0 0 }
  .btn { background: #334155; color: #fff }
</style>
<div class="es"><div class="lock" aria-hidden="true"></div><h2>You need access to this report</h2><p>Reports are shared by workspace admins. Your admin is Dana Price.</p><button class="btn">Request access</button></div>

10. Empty table that keeps its headers

Keeping the column headers shows what will appear, and a single row spans them with the message.

<style>
  .es { max-width: 380px; margin: 0 auto; text-align: center; font-family: system-ui, sans-serif; color: #111827 }
  .es h2 { margin: 0 0 6px; font-size: 18px } .es p { margin: 0 0 14px; color: #4b5563 }
  .es .btn { padding: 9px 16px; border: 0; border-radius: 8px; font-weight: 600 }
  table { width: 100%; border-collapse: collapse; font-size: 14px }
  th { text-align: left; padding: 8px; border-bottom: 2px solid #e5e7eb }
  td { padding: 24px 8px; text-align: center; color: #6b7280 }
</style>
<table class="es" style="max-width:none"><thead><tr><th>Client</th><th>Amount</th><th>Due</th></tr></thead><tbody><tr><td colspan="3">No unpaid invoices. <a href="#">See paid invoices</a></td></tr></tbody></table>

Three parts of every empty state

A heading that names the situation, one sentence that explains it or what will appear here, and one action. Everything else, such as artwork, tips or links to help, is optional and should not push the action off screen on a phone.

Write the heading from the user's side. Your project list is empty reads as blame; No projects yet reads as a starting point.

Plan empty states with the feature

Every list, table, chart and search in a product needs at least two empty versions: before anything exists and when a filter hides everything. Designing them alongside the full state is cheaper than patching them after users complain about blank screens.

How it works

  1. Use the table to name which kind of empty your screen is in. The message and the button depend on it.
  2. Fill in the builder with a heading, a sentence and a button label to get matching HTML and CSS.
  3. Browse the ten designs, edit any of them live, and copy the one that fits your product.
  4. Test the state with a screen reader if the content changes without a page load, and check the button is reachable by keyboard.

Tips

Frequently asked questions

What is an empty state in UI design?

It is the screen or panel shown when a list, table, dashboard or search has nothing to display. Good ones explain why and give the next action; poor ones show blank space or a bare No data.

How do I make an empty state accessible?

Use a real heading and text, not just an image. Mark decorative artwork with empty alt text. If the empty message appears after a filter or search without a page load, place it inside an element with role="status", which has an implicit polite live setting, and do not move focus to it.

Should an empty state show sample data?

It can help on first use, for example a demo project the user can open and delete. Label it clearly as an example so nobody mistakes it for their own data.

What should a no search results page say?

Repeat the term, say nothing matched, and suggest fixes: check spelling, remove a filter, or browse a category. A one-click Clear filters button is the most useful single action.

How is an error state different from an empty state?

An empty state means there is genuinely nothing to show. An error means there might be data but it could not be loaded. Say which one it is, because telling someone they have no orders when the server failed is alarming.

Related: 404 page examples, Thank you page examples, Website accessibility checklist, CSS button states, shadcn/ui examples.

Start for free or see all free tools. We.Inc is free to start, with no card needed. AI building is on paid plans from $20 a month.

More in Guides

We.Inc is an AI-powered website builder you can resell under your own brand. Launch a branded client dashboard, bill on Stripe Connect, and deliver AI-generated websites in minutes. White-label plans start at $99 a month for 25 client sites, with a 7-day free trial and no per-site fees.

Product

Who It's For

Features

Resources

Company

View Sitemap