Designing Empty States with Tailwind: Beyond 'No Data'
AI generated
tw
Tailwind CSS · UX Patterns · Empty States
Designing Empty States with Tailwind
Why an empty screen needs more than 'No data'

An empty search results list, a freshly created inbox, or a dashboard with no activity yet are all moments where many applications leave their users stranded. A good empty state doesn't just explain why there's nothing to see, it immediately points to a concrete next action, and that takes more than a gray line of text centered on the screen.

15 min read Illustration · call-to-action Never had data · no results · zero inbox

1. Why an empty state needs more than 'No data'

An empty screen is often a new user's very first impression of a feature, before any real data exists at all. Showing nothing but a bare line like 'No entries' wastes the chance to actively guide the user, and instead risks making the feature look broken or unfinished.

A well-designed empty state answers three questions at once: why is there nothing here, is that normal or a problem, and what can I do next. With Tailwind, those three answers map cleanly onto a visual hierarchy of icon, heading, explanatory text, and action button, without needing a dedicated illustration library.

2. The three kinds of empty states: never had data, no results, and all done

Not every empty state is the same. The very first time a feature is opened, say a brand-new project list, there was simply never any data, and the focus here is on explanation plus an invitation to create the first entry. A search with no matches is different: data does exist, only the current filter or search term returns nothing, so the priority is guidance on adjusting the search rather than a prompt to create something new.

The third kind is the positive zero state, an empty task list because everything got done, or an empty inbox after clearing every message. This state should be celebrated as a success rather than treated neutrally like an error case, because it actually represents the outcome the user was working toward.

3. Building a reusable empty state component with Tailwind

A reusable component needs slots for an icon or illustration, a heading, a description, and an optional action button, so it can be filled with different content for all three kinds of empty state. Centering via flexbox with flex flex-col items-center justify-center keeps the layout balanced regardless of the surrounding container's height.

Generous vertical spacing between elements through space-y-4 or similar utility classes keeps the state from feeling cramped, and a max text width via max-w-sm stops long descriptions from stretching across the full screen width and becoming hard to read.


<div class="flex flex-col items-center justify-center px-6 py-16 text-center">
  <svg class="mb-4 h-16 w-16 text-gray-300" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"
      d="M9 13h6m-3-3v6m-7 4h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v11a2 2 0 002 2z" />
  </svg>
  <h3 class="text-lg font-semibold text-gray-900">No projects yet</h3>
  <p class="mt-2 max-w-sm text-sm text-gray-500">
    Create your first project to start collecting tasks and share them with your team.
  </p>
  <button type="button"
    class="mt-6 rounded-md bg-indigo-600 px-4 py-2 text-sm font-medium text-white hover:bg-indigo-500">
    Create first project
  </button>
</div>

4. Illustration or icon: when each one fits

A simple outline icon from an icon library is usually enough in dense interfaces like admin tables or sidebar lists, and it adapts easily to dark mode through Tailwind color classes. A more elaborate illustration suits prominent, less frequently visited screens better, like an empty onboarding landing page, where it can also carry personality and brand identity.

On sizing: an icon should never look bigger than it needs to be, common sizes range between h-12 w-12 and h-16 w-16, while an illustration can reasonably take up the full available width of a container. Oversized icons quickly read as a placeholder error, undersized ones get lost in the surrounding whitespace.

5. Action-oriented calls-to-action instead of plain description

A call-to-action button in an empty state should always carry a concrete verb in its label, like 'Create first project' instead of a vague 'Get started', so it's immediately obvious what clicking it will trigger. The button should also be styled as the primary action, with a filled background instead of a pale text link, so it stands out against the otherwise quiet, empty surface.

For no-search-results states, the creation button is usually swapped for secondary actions like 'Clear filters' or 'Change search term', since prompting the user to create something new would be factually wrong there. This context-aware adjustment of the call-to-action is the core difference between a generic and a genuinely helpful empty state.

6. Designing empty search results: typo hints and clearing filters

For a search with no matches, it helps to echo the actual search term back in the text, like 'No results for "sneakr"', so the user can immediately spot a possible typo. A hint about common causes, like overly specific filter combinations or spelling mistakes, can speed up the user's troubleshooting considerably.

A button to clear all active filters should always be available here, since the most common cause of zero results is a combination of filters the user set themselves that turned out too narrow. A secondary, muted button style via border border-gray-300 text-gray-700 visually distinguishes this action clearly from a primary creation action.

7. Communicating an empty inbox as a success state ('All done')

An empty task list or an empty inbox after fully clearing it out is not an error, it's a goal reached, and the design should convey exactly that. A friendly icon like a checkmark inside a green circle instead of a neutral folder icon, along with a positively worded heading like 'All done' instead of 'No entries found', underline this difference clearly.

Color-wise, it's worth deliberately deviating from the neutral gray of other empty states toward a soft green tone via text-emerald-500, to reinforce the positive connotation further. A call-to-action is often unnecessary here altogether, since the user has already reached their goal and isn't expecting a further action.

8. Dark mode and color contrast in empty states

Icons in light gray like text-gray-300 look subtle in light mode but nearly vanish on a dark background in dark mode if no dedicated dark-mode class is added. Through dark:text-gray-600, an icon can be adjusted to keep a similarly muted but still clearly visible contrast against a dark background.

The description text likewise needs a deliberately lighter gray in dark mode, like dark:text-gray-400, instead of the text-gray-500 used in light mode, because darker grays on a black background quickly fall below the WCAG minimum contrast for body text and become hard to read.

9. Common mistakes in empty states and how to avoid them

A frequent mistake is using the same generic empty state for all three kinds of situations, even though 'never had data', 'no results', and 'all done' are functionally completely different scenarios that call for different user reactions. Another mistake is an empty state with no action at all, leaving the user in a dead end instead of offering a next step.

Equally problematic is an empty state that takes longer to read than the actual task behind it, like a novel-length explanation for a simple empty table. Short, clear sentences and a single, unambiguous call-to-action almost always outperform several competing buttons or sprawling explanations in practice.

State type Trigger Message Primary action
Never had data First time opening the feature Explanation plus invitation Create first entry
Search with no results Filter or search term too narrow Guidance on adjusting Clear filters
All done (zero inbox) All tasks completed Positive confirmation Usually no action needed
Error loading data API or network failure Transparent error message Retry

Mironsoft

Tailwind CSS architecture, design systems, and performance

Tailwind frontends that stay maintainable despite thousands of utility classes?

We review existing Tailwind projects for bloated class lists, inconsistent design tokens, and unused CSS remnants, then build a design system that scales cleanly instead of getting messier with every component.

Design System Review

Checking tokens, spacing scale, and component consistency for maintainability.

Performance Optimization

Systematically reducing CSS bundle size, purge configuration, and load times.

Component Architecture

Building reusable, well-structured components instead of sprawling class lists.

10. Summary

Empty States with Tailwind: Key Takeaways

Three state types

Never had data, no results, and all done each need their own message and action.

Icon vs. illustration

Icons for dense interfaces, richer illustrations for prominent onboarding screens.

Call-to-action

A concrete verb in the button label beats a vague phrase like 'Get started'.

Dark mode

Light icon and text colors need their own dark: classes or they vanish on dark backgrounds.

11. FAQ: Empty States with Tailwind: Key Takeaways

1What's the difference between an empty state and an error page?
An empty state describes an expected, normal state with no data, like a fresh list. An error page communicates that something didn't work as expected; both need different language and icons.
2Should every empty state have a call-to-action button?
Not necessarily. Positive zero states like a completed task list often need no further action, while 'never had data' almost always benefits from a clear button.
3How do you distinguish an empty search from a first-time-use state in code?
Usually a simple check for whether any records exist in the database at all, independent of the current filter, is enough. If records exist but the filtered query returns nothing, it's an empty search.
4Does every empty state need a custom illustration?
No, a simple outline icon is enough in most cases, especially in dense admin interfaces. Elaborate illustrations pay off mainly for prominent, less frequently visited screens.
5How long should an empty state's description text be?
One or two short sentences are almost always enough. Longer explanations quickly feel overloaded and, in practice, users rarely read them in full.
6How do you test empty states automatically?
The simplest approach is targeted test-data states, like a database with no rows or a mock that returns an empty response, combined with a visual snapshot test of the component.
7Should mobile and desktop use the same empty state?
The message and structure usually stay the same, but icon size and vertical spacing should be adjusted through responsive Tailwind classes like sm: for smaller screens to save space.
8How do you handle empty states in dark mode?
Light gray tones for icon and text need dedicated dark: variants, otherwise they nearly disappear on a dark background. A quick manual dark-mode check should always be part of the review.
9What about an empty state after an error rather than missing data?
Here you should clearly distinguish 'not an error, just empty' from 'error while loading', for example with a red warning icon instead of the neutral icon and a retry button instead of a creation button.
10Is a reusable empty state component worth building?
Yes, as soon as more than two or three places in the app show empty states. A central component with slots for icon, text, and action saves time and keeps the look consistent.