~/css/tailwind-empty-states
6 Tailwind Empty States
5 Tailwind 1 with JS Published 2026-10-05 Free · no sign-up
Six empty states that help instead of shrugging: an empty inbox with a next step, a no-results message with suggestions, an upload area, an empty table that keeps its headers, a getting-started checklist and an offline message with a retry.
Filter demos
01. Tailwind Empty Inbox State
Tailwind Empty state
An empty state that explains what will appear here and offers the next step. The line illustration is an aria-hidden SVG in a soft brand tint, so it adds warmth without being read aloud.
Copy HTML Open in editor →
View code
HTML
<div class="grid w-full max-w-xs justify-items-center rounded-2xl bg-white p-6 text-center shadow-sm ring-1 ring-slate-200">
<svg aria-hidden="true" viewBox="0 0 64 64" fill="none" stroke="currentColor" stroke-width="3" stroke-linejoin="round" class="size-16 text-indigo-300"><path d="M8 36l8-22h32l8 22v14H8z"/><path d="M8 36h14l4 6h12l4-6h14"/></svg>
<h3 class="mt-3 font-bold text-slate-900">Inbox zero</h3>
<p class="mt-1 text-sm text-slate-600">New messages from customers will show up here.</p>
<a href="#compose" class="mt-4 rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white hover:bg-indigo-700 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Write a message</a>
</div>
02. Tailwind No Search Results State
Tailwind Empty state Search
When a search finds nothing, repeat the query, suggest fixes and offer a way out such as clearing filters. Suggestions are links so they are one tap away.
Copy HTML Open in editor →
View code
HTML
<div class="w-full max-w-xs rounded-2xl bg-white p-6 shadow-sm ring-1 ring-slate-200">
<h3 class="font-bold text-slate-900">No results for “blu linnen”</h3>
<p class="mt-1 text-sm text-slate-600">Check the spelling or try one of these:</p>
<ul class="mt-3 flex flex-wrap gap-2 text-sm"><li><a href="#blue-linen" class="rounded-full bg-slate-100 px-3 py-1 text-slate-800 hover:bg-slate-200">blue linen</a></li><li><a href="#linen" class="rounded-full bg-slate-100 px-3 py-1 text-slate-800 hover:bg-slate-200">linen shirts</a></li></ul>
<button type="button" class="mt-4 text-sm font-semibold text-indigo-700 hover:underline focus-visible:outline focus-visible:outline-2 focus-visible:outline-indigo-600">Clear all filters</button>
</div>
03. Tailwind Empty Upload Area
Tailwind Empty state Upload
A dashed drop area that doubles as the empty state of a file list. The whole area is a label for a visually hidden file input, so a click anywhere opens the picker, and has-[:focus-visible] draws the focus ring on the area.
Copy HTML Open in editor →
View code
HTML
<label class="grid w-full max-w-xs cursor-pointer justify-items-center rounded-2xl border-2 border-dashed border-slate-300 bg-white p-6 text-center hover:border-indigo-500 hover:bg-indigo-50/40 has-[:focus-visible]:outline has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-indigo-600">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" class="size-10 text-slate-400"><path d="M12 16V4M7 9l5-5 5 5M4 16v3a1 1 0 0 0 1 1h14a1 1 0 0 0 1-1v-3"/></svg>
<span class="mt-2 font-semibold text-slate-900">No files yet</span>
<span class="text-sm text-slate-600">Choose files or drop them here</span>
<input type="file" multiple class="sr-only">
</label>
04. Tailwind Empty Table State
Tailwind Empty state Table
Keep the table's headers and put the empty message in one cell that spans every column with colSpan. Users still see what the table will hold, and the call to action sits right where the data will appear.
Copy HTML Open in editor →
View code
HTML
<table class="w-full max-w-xs overflow-hidden rounded-2xl bg-white text-left text-sm shadow-sm ring-1 ring-slate-200">
<thead class="bg-slate-50 text-xs uppercase tracking-wide text-slate-600"><tr><th scope="col" class="px-3 py-2">Invoice</th><th scope="col" class="px-3 py-2">Client</th><th scope="col" class="px-3 py-2">Amount</th></tr></thead>
<tbody><tr><td colspan="3" class="px-3 py-10 text-center text-slate-600">No invoices yet. <a href="#new" class="font-semibold text-indigo-700 hover:underline">Create your first one</a></td></tr></tbody>
</table>
05. Tailwind Getting-Started Checklist
Tailwind Empty state Onboarding
A new account's empty dashboard turned into a short checklist. Done steps are struck through with a tick and the word Done for screen readers, and the next step is the one that stands out.
Copy HTML Open in editor →
View code
HTML
<section class="w-full max-w-xs rounded-2xl bg-white p-5 shadow-sm ring-1 ring-slate-200">
<h3 class="font-bold text-slate-900">Get your store ready</h3>
<ol class="mt-3 grid gap-2 text-sm">
<li class="flex items-center gap-3 text-slate-500"><span aria-hidden="true" class="grid size-6 place-items-center rounded-full bg-emerald-700 text-xs text-white">✓</span><span class="line-through">Create your account</span><span class="sr-only"> (done)</span></li>
<li><a href="#product" class="flex items-center gap-3 rounded-lg bg-indigo-50 px-2 py-2 font-semibold text-indigo-800 ring-1 ring-indigo-200 hover:bg-indigo-100"><span aria-hidden="true" class="grid size-6 place-items-center rounded-full bg-indigo-600 text-xs text-white">2</span>Add your first product →</a></li>
<li class="flex items-center gap-3 text-slate-700"><span aria-hidden="true" class="grid size-6 place-items-center rounded-full bg-slate-200 text-xs text-slate-700">3</span>Connect payments</li>
</ol>
</section>
06. Tailwind Offline Error State
Tailwind Empty state Error
An error state for lost connections with a plain explanation and a Try again button. The button checks navigator.onLine and reports the result in a status message, rather than failing silently.
Copy HTML Copy JS Open in editor →
View code
HTML JS
<div class="grid w-full max-w-xs justify-items-center rounded-2xl bg-slate-800 p-6 text-center">
<svg aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" class="size-12 text-amber-300"><path d="M2 8.5a15 15 0 0 1 20 0M5 12a10 10 0 0 1 14 0M8.5 15.5a5 5 0 0 1 7 0M12 19h.01M3 3l18 18"/></svg>
<h3 class="mt-3 font-bold text-white">You’re offline</h3>
<p class="mt-1 text-sm text-slate-300">Your changes are saved on this device and will sync when you reconnect.</p>
<button id="twes6" type="button" class="mt-4 rounded-lg bg-amber-300 px-4 py-2 text-sm font-bold text-slate-900 hover:bg-amber-200 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-amber-300">Try again</button>
<p id="twes6s" role="status" class="mt-2 min-h-5 text-xs text-slate-300"></p>
</div>document.getElementById('twes6').onclick = function () { document.getElementById('twes6s').textContent = navigator.onLine ? 'Connected again. Syncing…' : 'Still offline. We will keep trying.'; };
About these Tailwind Empty States
Explain and invite
Say what will appear here and offer the single most useful action. An empty screen is often a new user's first impression.
Keep the structure
An empty table keeps its headers, with the message in one cell that spans all columns, so people learn what will fill it.
Decorative art is hidden
Illustrations are aria-hidden; the heading and text carry the message.
Errors need a way forward
Offline or failed states should say what was kept and offer a retry, with the result announced in a status region.
Frequently asked questions
Should empty states have illustrations? A small one adds warmth; the words and the action matter more.
Does the upload area upload anything? No. It opens the file picker only; there is no upload in the demo.
Is there a CSS version? Yes, see the CSS empty states collection.