N
NJHTools

UI Component Library

58 free, copy-paste Tailwind UI components in 16 categories — navbars, hero sections, pricing tables, footers, tables, buttons, forms, modals, CSS loaders and more. Live preview, one-click copy of HTML, JSX, CSS, and JS. No signup, no attribution required, runs entirely in your browser.

Components

Primary Button

Buttons

<button class="px-4 py-2 rounded-xl bg-indigo-600 text-white text-sm font-semibold hover:bg-indigo-700 transition-colors shadow-sm">
  Primary Button
</button>

Outline Button

Buttons

<button class="px-4 py-2 rounded-xl border border-slate-300 text-slate-700 text-sm font-semibold hover:bg-slate-50 transition-colors">
  Outline Button
</button>

Icon Button

Buttons

<button class="w-10 h-10 flex items-center justify-center rounded-full bg-slate-100 text-slate-600 hover:bg-slate-200 transition-colors" aria-label="Settings">
  <svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="1.5">
    <path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.324.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 011.37.49l1.296 2.247a1.125 1.125 0 01-.26 1.431l-1.003.827c-.293.24-.438.613-.431.992a6.759 6.759 0 010 .255c-.007.378.138.75.43.99l1.005.828c.424.35.534.954.26 1.43l-1.298 2.247a1.125 1.125 0 01-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.57 6.57 0 01-.22.128c-.331.183-.581.495-.644.869l-.213 1.28c-.09.543-.56.941-1.11.941h-2.594c-.55 0-1.02-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 01-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 01-1.369-.49l-1.297-2.247a1.125 1.125 0 01.26-1.431l1.004-.827c.292-.24.437-.613.43-.992a6.932 6.932 0 010-.255c.007-.378-.138-.75-.43-.99l-1.004-.828a1.125 1.125 0 01-.26-1.43l1.297-2.247a1.125 1.125 0 011.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.087.22-.128.332-.183.582-.495.644-.869l.214-1.28z" />
    <path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
  </svg>
</button>

Gradient Button

Buttons

<button class="px-5 py-2.5 rounded-xl bg-gradient-to-r from-indigo-500 to-purple-500 text-white text-sm font-semibold hover:opacity-90 transition-opacity shadow-md">
  Get Started
</button>

Status Pill

Badges

Active
<span class="inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full bg-emerald-100 text-emerald-700 text-xs font-semibold">
  <span class="w-1.5 h-1.5 rounded-full bg-emerald-500"></span>
  Active
</span>

Notification Badge

Badges

🔔 3
<span class="relative inline-flex">
  <span class="inline-flex items-center justify-center w-9 h-9 rounded-full bg-slate-100 text-slate-500">🔔</span>
  <span class="absolute -top-1 -right-1 inline-flex items-center justify-center w-5 h-5 rounded-full bg-rose-500 text-white text-[10px] font-bold">3</span>
</span>

Basic Card

Cards

Card Title

A short description of this card's content goes here.

<div class="max-w-sm rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
  <h3 class="text-base font-bold text-slate-900 mb-1">Card Title</h3>
  <p class="text-sm text-slate-500">A short description of this card's content goes here.</p>
</div>

Profile Card

Cards

JD

Jane Doe

Product Designer

<div class="max-w-sm rounded-2xl border border-slate-200 bg-white p-5 shadow-sm flex items-center gap-4">
  <div class="w-12 h-12 rounded-full bg-gradient-to-br from-indigo-400 to-purple-400 flex items-center justify-center text-white font-bold">JD</div>
  <div>
    <p class="text-sm font-bold text-slate-900">Jane Doe</p>
    <p class="text-xs text-slate-500">Product Designer</p>
  </div>
</div>

Pricing Card

Cards

Pro

$19/mo

<div class="max-w-sm rounded-2xl border-2 border-indigo-500 bg-white p-6 shadow-md">
  <p class="text-xs font-bold text-indigo-600 uppercase tracking-wide mb-2">Pro</p>
  <p class="text-3xl font-extrabold text-slate-900 mb-4">$19<span class="text-sm font-medium text-slate-400">/mo</span></p>
  <button class="w-full px-4 py-2 rounded-xl bg-indigo-600 text-white text-sm font-semibold hover:bg-indigo-700 transition-colors">
    Choose Plan
  </button>
</div>

Info Alert

Alerts

ℹ️

This is an informational message for the user.

<div class="flex items-start gap-3 rounded-xl border border-sky-200 bg-sky-50 p-4">
  <span class="text-sky-500 text-lg leading-none">ℹ️</span>
  <p class="text-sm text-sky-800">This is an informational message for the user.</p>
</div>

Success Alert

Alerts

✅

Your changes have been saved successfully.

<div class="flex items-start gap-3 rounded-xl border border-emerald-200 bg-emerald-50 p-4">
  <span class="text-emerald-500 text-lg leading-none">✅</span>
  <p class="text-sm text-emerald-800">Your changes have been saved successfully.</p>
</div>

Warning Alert

Alerts

⚠️

This action may have unintended side effects.

<div class="flex items-start gap-3 rounded-xl border border-amber-200 bg-amber-50 p-4">
  <span class="text-amber-500 text-lg leading-none">⚠️</span>
  <p class="text-sm text-amber-800">This action may have unintended side effects.</p>
</div>

Error Alert

Alerts

⛔

Something went wrong. Please try again.

<div class="flex items-start gap-3 rounded-xl border border-rose-200 bg-rose-50 p-4">
  <span class="text-rose-500 text-lg leading-none">⛔</span>
  <p class="text-sm text-rose-800">Something went wrong. Please try again.</p>
</div>

Text Input

Forms

<div class="max-w-sm">
  <label class="block text-xs font-semibold text-slate-600 mb-1">Email address</label>
  <input type="email" placeholder="you@example.com" class="w-full px-3 py-2 rounded-xl border border-slate-300 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-400" />
</div>

Textarea

Forms

<div class="max-w-sm">
  <label class="block text-xs font-semibold text-slate-600 mb-1">Message</label>
  <textarea rows="3" placeholder="Type your message…" class="w-full px-3 py-2 rounded-xl border border-slate-300 text-sm text-slate-900 placeholder:text-slate-400 focus:outline-none focus:ring-2 focus:ring-indigo-400"></textarea>
</div>

Select Dropdown

Forms

<div class="max-w-sm">
  <label class="block text-xs font-semibold text-slate-600 mb-1">Country</label>
  <select class="w-full px-3 py-2 rounded-xl border border-slate-300 text-sm text-slate-900 focus:outline-none focus:ring-2 focus:ring-indigo-400">
    <option>United States</option>
    <option>South Korea</option>
    <option>Japan</option>
  </select>
</div>

Checkbox

Forms

<label class="inline-flex items-center gap-2 cursor-pointer">
  <input type="checkbox" class="w-4 h-4 rounded border-slate-300 text-indigo-600 focus:ring-indigo-400" />
  <span class="text-sm text-slate-700">I agree to the terms</span>
</label>

Toggle Switch

Forms

Uses Tailwind's peer/peer-checked variants — no JavaScript required.

<label class="inline-flex items-center cursor-pointer">
  <input type="checkbox" class="peer sr-only" />
  <div class="w-11 h-6 rounded-full bg-slate-200 peer-checked:bg-indigo-600 transition-colors relative">
    <div class="absolute top-0.5 left-0.5 w-5 h-5 rounded-full bg-white shadow-sm transition-transform peer-checked:translate-x-5"></div>
  </div>
</label>

Spinner

Feedback

Uses Tailwind's built-in animate-spin utility — no custom CSS required.

<div class="w-8 h-8 rounded-full border-4 border-slate-200 border-t-indigo-600 animate-spin"></div>

Progress Bar

Feedback

<div class="w-full max-w-sm h-2.5 rounded-full bg-slate-200 overflow-hidden">
  <div class="h-full w-2/3 rounded-full bg-indigo-600"></div>
</div>

Skeleton Loader

Feedback

Also copy the CSS tab — this component needs its custom @keyframes to animate.

<div class="max-w-sm space-y-2">
  <div class="h-4 w-3/4 rounded skeleton-shimmer"></div>
  <div class="h-4 w-1/2 rounded skeleton-shimmer"></div>
</div>

Toast Notification

Feedback

Vanilla JavaScript — no framework required.

<button id="toast-trigger" class="px-4 py-2 rounded-xl bg-slate-900 text-white text-sm font-semibold hover:bg-slate-800 transition-colors">
  Show Toast
</button>
<div id="toast" class="fixed bottom-5 right-5 hidden items-center gap-2 rounded-xl bg-slate-900 text-white text-sm font-medium px-4 py-3 shadow-lg">
  ✅ Saved successfully!
</div>

Accordion / FAQ Item

Overlays

What is your refund policy? ▾

We offer a 30-day money-back guarantee on all plans, no questions asked.

Uses the native <details>/<summary> elements — no JavaScript required.

<details class="max-w-md rounded-xl border border-slate-200 p-4 group">
  <summary class="cursor-pointer text-sm font-semibold text-slate-800 list-none flex items-center justify-between">
    What is your refund policy?
    <span class="text-slate-400 group-open:rotate-180 transition-transform">▾</span>
  </summary>
  <p class="text-sm text-slate-500 mt-2">
    We offer a 30-day money-back guarantee on all plans, no questions asked.
  </p>
</details>

Modal Dialog

Overlays

Confirm action

Are you sure you want to continue?

Uses the native <dialog> element — minimal JavaScript just toggles it open/closed.

<button id="modal-open" class="px-4 py-2 rounded-xl bg-indigo-600 text-white text-sm font-semibold hover:bg-indigo-700 transition-colors">
  Open Modal
</button>
<dialog id="modal" class="rounded-2xl p-6 w-full max-w-sm backdrop:bg-black/50">
  <h3 class="text-base font-bold text-slate-900 mb-2">Confirm action</h3>
  <p class="text-sm text-slate-500 mb-4">Are you sure you want to continue?</p>
  <div class="flex gap-2 justify-end">
    <button id="modal-close" class="px-3 py-1.5 rounded-lg text-sm font-semibold text-slate-600 hover:bg-slate-100">Cancel</button>
    <button class="px-3 py-1.5 rounded-lg text-sm font-semibold text-white bg-indigo-600 hover:bg-indigo-700">Confirm</button>
  </div>
</dialog>

Tooltip

Overlays

Uses Tailwind's group/group-hover variants — no JavaScript required.

<span class="relative inline-block group">
  <button class="w-8 h-8 flex items-center justify-center rounded-full bg-slate-100 text-slate-500 text-sm font-bold">?</button>
  <span class="absolute bottom-full left-1/2 -translate-x-1/2 mb-2 hidden group-hover:block whitespace-nowrap rounded-lg bg-slate-900 text-white text-xs px-2.5 py-1.5">
    Helpful tooltip text
  </span>
</span>

Circle Avatar

Avatars

AB
<div class="w-10 h-10 rounded-full bg-gradient-to-br from-sky-400 to-indigo-500 flex items-center justify-center text-white text-sm font-bold">
  AB
</div>

Avatar Group

Avatars

A
B
C
+5
<div class="flex -space-x-2">
  <div class="w-9 h-9 rounded-full bg-indigo-400 border-2 border-white flex items-center justify-center text-white text-xs font-bold">A</div>
  <div class="w-9 h-9 rounded-full bg-emerald-400 border-2 border-white flex items-center justify-center text-white text-xs font-bold">B</div>
  <div class="w-9 h-9 rounded-full bg-amber-400 border-2 border-white flex items-center justify-center text-white text-xs font-bold">C</div>
  <div class="w-9 h-9 rounded-full bg-slate-200 border-2 border-white flex items-center justify-center text-slate-500 text-xs font-bold">+5</div>
</div>

Avatar with Status

Avatars

JS
<div class="relative inline-block">
  <div class="w-10 h-10 rounded-full bg-gradient-to-br from-purple-400 to-pink-400 flex items-center justify-center text-white text-sm font-bold">JS</div>
  <span class="absolute bottom-0 right-0 w-3 h-3 rounded-full bg-emerald-500 border-2 border-white"></span>
</div>

Centered Hero

Hero Sections

Version 2.0 is live

Build beautiful pages in minutes

Copy-paste components, sensible defaults and zero lock-in. Go from idea to launch without fighting your CSS.

Change the <h2> to <h1> when the hero is the first heading on your page.

<section class="w-full bg-white px-4 py-16 sm:py-24">
  <div class="mx-auto max-w-3xl text-center">
    <p class="mb-5 inline-flex items-center gap-2 rounded-full bg-indigo-50 px-3 py-1 text-xs font-semibold text-indigo-700">
      <span class="h-1.5 w-1.5 rounded-full bg-indigo-500"></span>
      Version 2.0 is live
    </p>
    <h2 class="text-4xl font-extrabold tracking-tight text-slate-900 sm:text-5xl">
      Build beautiful pages
      <span class="bg-gradient-to-r from-indigo-600 to-purple-600 bg-clip-text text-transparent">in minutes</span>
    </h2>
    <p class="mx-auto mt-5 max-w-xl text-base text-slate-600 sm:text-lg">Copy-paste components, sensible defaults and zero lock-in. Go from idea to launch without fighting your CSS.</p>
    <div class="mt-8 flex flex-col justify-center gap-3 sm:flex-row">
      <a href="#" class="rounded-xl bg-indigo-600 px-6 py-3 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700">Get started free</a>
      <a href="#" class="rounded-xl border border-slate-300 px-6 py-3 text-sm font-semibold text-slate-700 transition-colors hover:bg-slate-50">View demo</a>
    </div>
  </div>
</section>

Split Hero with Image

Hero Sections

Analytics for small teams

Know what works. Drop what doesn't.

Privacy-friendly dashboards that answer real questions in seconds — no SQL and no sampling.

Free for 14 days · No credit card required

The chart panel is a decorative placeholder — swap it for an <img> with width, height and alt text. Change <h2> to <h1> if it opens the page.

<section class="w-full bg-slate-50 px-4 py-14">
  <div class="mx-auto grid max-w-6xl items-center gap-10 md:grid-cols-2">
    <div>
      <p class="text-sm font-semibold uppercase tracking-wide text-indigo-600">Analytics for small teams</p>
      <h2 class="mt-3 text-4xl font-extrabold tracking-tight text-slate-900">Know what works. Drop what doesn't.</h2>
      <p class="mt-4 text-base text-slate-600">Privacy-friendly dashboards that answer real questions in seconds — no SQL and no sampling.</p>
      <div class="mt-7 flex flex-wrap items-center gap-4">
        <a href="#" class="rounded-xl bg-slate-900 px-6 py-3 text-sm font-semibold text-white transition-colors hover:bg-slate-700">Start free trial</a>
        <a href="#" class="text-sm font-semibold text-slate-700 hover:text-indigo-600">See how it works →</a>
      </div>
      <p class="mt-6 text-xs text-slate-500">Free for 14 days · No credit card required</p>
    </div>
    <div aria-hidden="true" class="rounded-2xl border border-slate-200 bg-white p-5 shadow-xl">
      <div class="flex gap-1.5">
        <span class="h-2.5 w-2.5 rounded-full bg-rose-400"></span>
        <span class="h-2.5 w-2.5 rounded-full bg-amber-400"></span>
        <span class="h-2.5 w-2.5 rounded-full bg-emerald-400"></span>
      </div>
      <div class="mt-5 flex h-40 items-end gap-2">
        <div class="h-1/3 flex-1 rounded-t-md bg-indigo-200"></div>
        <div class="h-1/2 flex-1 rounded-t-md bg-indigo-300"></div>
        <div class="h-2/5 flex-1 rounded-t-md bg-indigo-200"></div>
        <div class="h-3/4 flex-1 rounded-t-md bg-indigo-400"></div>
        <div class="h-2/3 flex-1 rounded-t-md bg-indigo-300"></div>
        <div class="h-full flex-1 rounded-t-md bg-indigo-600"></div>
      </div>
    </div>
  </div>
</section>

Hero with Email Signup

Hero Sections

Ship your side project this weekend

Weekly tutorials, starter kits and launch checklists for indie developers.

Joined by 12,000+ developers

Change the <h2> to <h1> when the hero is the first heading on your page.

<section class="w-full bg-gradient-to-br from-slate-900 via-indigo-950 to-slate-900 px-4 py-16 sm:py-20">
  <div class="mx-auto max-w-2xl text-center">
    <h2 class="text-4xl font-extrabold tracking-tight text-white sm:text-5xl">Ship your side project this weekend</h2>
    <p class="mt-4 text-base text-indigo-100 sm:text-lg">Weekly tutorials, starter kits and launch checklists for indie developers.</p>
    <form action="#" class="mx-auto mt-8 flex max-w-md flex-col gap-3 sm:flex-row">
      <label for="hero-email" class="sr-only">Email address</label>
      <input id="hero-email" type="email" required placeholder="Enter your email" class="min-w-0 flex-1 rounded-xl border border-white/20 bg-white/10 px-4 py-3 text-sm text-white placeholder:text-indigo-200 focus:outline-none focus:ring-2 focus:ring-indigo-400" />
      <button type="submit" class="rounded-xl bg-indigo-500 px-6 py-3 text-sm font-semibold text-white transition-colors hover:bg-indigo-400">Join free</button>
    </form>
    <div class="mt-6 flex items-center justify-center gap-3">
      <div class="flex -space-x-2" aria-hidden="true">
        <span class="h-7 w-7 rounded-full border-2 border-slate-900 bg-amber-400"></span>
        <span class="h-7 w-7 rounded-full border-2 border-slate-900 bg-emerald-400"></span>
        <span class="h-7 w-7 rounded-full border-2 border-slate-900 bg-sky-400"></span>
      </div>
      <p class="text-sm text-indigo-100">Joined by 12,000+ developers</p>
    </div>
  </div>
</section>

Three-Tier Pricing

Pricing Tables

Simple, transparent pricing

Start free, upgrade when your team grows.

Starter

$0/month

  • 1 project
  • Community support
Get started

Most popular

Pro

$19/month

  • Unlimited projects
  • Custom domains
  • Priority email support
Start free trial

Team

$49/month

  • Everything in Pro
  • 10 team seats
  • SSO and audit log
Contact sales

The featured plan is marked by a label and a thicker border, not by color alone. Each card is a flex column with a flex-1 feature list, so the buttons line up.

<section class="w-full bg-white px-4 py-12">
  <div class="mx-auto max-w-2xl text-center">
    <h2 class="text-3xl font-extrabold tracking-tight text-slate-900">Simple, transparent pricing</h2>
    <p class="mt-3 text-slate-600">Start free, upgrade when your team grows.</p>
  </div>
  <div class="mx-auto mt-10 grid max-w-5xl gap-6 md:grid-cols-3">
    <div class="flex flex-col rounded-2xl border border-slate-200 p-6">
      <h3 class="text-sm font-semibold text-slate-900">Starter</h3>
      <p class="mt-4"><span class="text-4xl font-extrabold text-slate-900">$0</span><span class="text-sm text-slate-500">/month</span></p>
      <ul class="mt-6 flex-1 space-y-3 text-sm text-slate-600">
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>1 project</li>
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>Community support</li>
      </ul>
      <a href="#" class="mt-8 rounded-xl border border-slate-300 px-4 py-2.5 text-center text-sm font-semibold text-slate-700 transition-colors hover:bg-slate-50">Get started</a>
    </div>
    <div class="relative flex flex-col rounded-2xl border-2 border-indigo-600 p-6 shadow-xl">
      <p class="absolute -top-3 left-1/2 -translate-x-1/2 rounded-full bg-indigo-600 px-3 py-1 text-xs font-semibold text-white">Most popular</p>
      <h3 class="text-sm font-semibold text-indigo-600">Pro</h3>
      <p class="mt-4"><span class="text-4xl font-extrabold text-slate-900">$19</span><span class="text-sm text-slate-500">/month</span></p>
      <ul class="mt-6 flex-1 space-y-3 text-sm text-slate-600">
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>Unlimited projects</li>
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>Custom domains</li>
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>Priority email support</li>
      </ul>
      <a href="#" class="mt-8 rounded-xl bg-indigo-600 px-4 py-2.5 text-center text-sm font-semibold text-white shadow-sm transition-colors hover:bg-indigo-700">Start free trial</a>
    </div>
    <div class="flex flex-col rounded-2xl border border-slate-200 p-6">
      <h3 class="text-sm font-semibold text-slate-900">Team</h3>
      <p class="mt-4"><span class="text-4xl font-extrabold text-slate-900">$49</span><span class="text-sm text-slate-500">/month</span></p>
      <ul class="mt-6 flex-1 space-y-3 text-sm text-slate-600">
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>Everything in Pro</li>
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>10 team seats</li>
        <li class="flex gap-2"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg>SSO and audit log</li>
      </ul>
      <a href="#" class="mt-8 rounded-xl border border-slate-300 px-4 py-2.5 text-center text-sm font-semibold text-slate-700 transition-colors hover:bg-slate-50">Contact sales</a>
    </div>
  </div>
</section>

Pricing with Monthly/Yearly Toggle

Pricing Tables

Plans that grow with you

Personal

For solo makers and side projects.

$12/month

Choose Personal

Business

For growing teams that need more control.

$39/month

Choose Business

CSS-only billing switch: a hidden checkbox plus the named group-has-[:checked]/pricing variant swaps the prices — no JavaScript.

<section class="group/pricing w-full bg-slate-50 px-4 py-12">
  <div class="mx-auto max-w-2xl text-center">
    <h2 class="text-3xl font-extrabold tracking-tight text-slate-900">Plans that grow with you</h2>
    <label class="mt-6 inline-flex cursor-pointer items-center gap-3 text-sm font-medium text-slate-600">
      <span>Monthly</span>
      <input type="checkbox" aria-label="Bill yearly" class="peer sr-only" />
      <span class="relative h-6 w-11 rounded-full bg-slate-300 transition-colors after:absolute after:left-0.5 after:top-0.5 after:h-5 after:w-5 after:rounded-full after:bg-white after:shadow-sm after:transition-transform peer-checked:bg-indigo-600 peer-checked:after:translate-x-5 peer-focus-visible:ring-2 peer-focus-visible:ring-indigo-500 peer-focus-visible:ring-offset-2"></span>
      <span>Yearly <span class="ml-1 rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-semibold text-emerald-700">Save 20%</span></span>
    </label>
  </div>
  <div class="mx-auto mt-10 grid max-w-3xl gap-6 sm:grid-cols-2">
    <div class="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm">
      <h3 class="text-lg font-bold text-slate-900">Personal</h3>
      <p class="mt-1 text-sm text-slate-500">For solo makers and side projects.</p>
      <p class="mt-6 text-4xl font-extrabold text-slate-900">
        <span class="group-has-[:checked]/pricing:hidden">$12<span class="text-sm font-medium text-slate-500">/month</span></span>
        <span class="hidden group-has-[:checked]/pricing:inline">$115<span class="text-sm font-medium text-slate-500">/year</span></span>
      </p>
      <a href="#" class="mt-6 block rounded-xl border border-slate-300 px-4 py-2.5 text-center text-sm font-semibold text-slate-700 transition-colors hover:bg-slate-50">Choose Personal</a>
    </div>
    <div class="rounded-2xl bg-slate-900 p-6 text-white shadow-xl">
      <h3 class="text-lg font-bold">Business</h3>
      <p class="mt-1 text-sm text-slate-300">For growing teams that need more control.</p>
      <p class="mt-6 text-4xl font-extrabold">
        <span class="group-has-[:checked]/pricing:hidden">$39<span class="text-sm font-medium text-slate-300">/month</span></span>
        <span class="hidden group-has-[:checked]/pricing:inline">$374<span class="text-sm font-medium text-slate-300">/year</span></span>
      </p>
      <a href="#" class="mt-6 block rounded-xl bg-indigo-500 px-4 py-2.5 text-center text-sm font-semibold text-white transition-colors hover:bg-indigo-400">Choose Business</a>
    </div>
  </div>
</section>

Pricing Comparison Table

Pricing Tables

Plan feature comparison
Features Free$0/mo Pro$19/mo EnterpriseCustom
Projects 3 Unlimited Unlimited
Custom domain Not included Included Included
SSO / SAML Not included Not included Included
Support Community Priority email Dedicated manager

A real <table> with row and column headers, so screen readers announce each feature against its plan. Scrolls sideways on small screens.

<div class="w-full overflow-x-auto rounded-2xl border border-slate-200 bg-white">
  <table class="w-full min-w-[36rem] text-sm">
    <caption class="sr-only">Plan feature comparison</caption>
    <thead>
      <tr class="border-b border-slate-200">
        <th scope="col" class="px-5 py-4 text-left font-semibold text-slate-900">Features</th>
        <th scope="col" class="px-5 py-4 text-center font-semibold text-slate-900">Free<span class="block text-xs font-normal text-slate-500">$0/mo</span></th>
        <th scope="col" class="bg-indigo-50 px-5 py-4 text-center font-semibold text-indigo-700">Pro<span class="block text-xs font-normal text-indigo-600">$19/mo</span></th>
        <th scope="col" class="px-5 py-4 text-center font-semibold text-slate-900">Enterprise<span class="block text-xs font-normal text-slate-500">Custom</span></th>
      </tr>
    </thead>
    <tbody class="divide-y divide-slate-100 text-slate-600">
      <tr>
        <th scope="row" class="px-5 py-3 text-left font-medium text-slate-700">Projects</th>
        <td class="px-5 py-3 text-center">3</td>
        <td class="bg-indigo-50 px-5 py-3 text-center">Unlimited</td>
        <td class="px-5 py-3 text-center">Unlimited</td>
      </tr>
      <tr>
        <th scope="row" class="px-5 py-3 text-left font-medium text-slate-700">Custom domain</th>
        <td class="px-5 py-3 text-center"><span aria-hidden="true" class="text-slate-300">—</span><span class="sr-only">Not included</span></td>
        <td class="bg-indigo-50 px-5 py-3"><span class="flex justify-center"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg></span><span class="sr-only">Included</span></td>
        <td class="px-5 py-3"><span class="flex justify-center"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg></span><span class="sr-only">Included</span></td>
      </tr>
      <tr>
        <th scope="row" class="px-5 py-3 text-left font-medium text-slate-700">SSO / SAML</th>
        <td class="px-5 py-3 text-center"><span aria-hidden="true" class="text-slate-300">—</span><span class="sr-only">Not included</span></td>
        <td class="bg-indigo-50 px-5 py-3 text-center"><span aria-hidden="true" class="text-slate-300">—</span><span class="sr-only">Not included</span></td>
        <td class="px-5 py-3"><span class="flex justify-center"><svg class="h-5 w-5 shrink-0 text-indigo-600" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M16.704 4.153a.75.75 0 01.143 1.052l-8 10.5a.75.75 0 01-1.127.075l-4.5-4.5a.75.75 0 011.06-1.06l3.894 3.893 7.48-9.817a.75.75 0 011.05-.143z" clip-rule="evenodd" /></svg></span><span class="sr-only">Included</span></td>
      </tr>
      <tr>
        <th scope="row" class="px-5 py-3 text-left font-medium text-slate-700">Support</th>
        <td class="px-5 py-3 text-center">Community</td>
        <td class="bg-indigo-50 px-5 py-3 text-center">Priority email</td>
        <td class="px-5 py-3 text-center">Dedicated manager</td>
      </tr>
    </tbody>
  </table>
</div>

Underline Tabs

Tabs

Update your name, photo and public bio.

Accessible ARIA tabs: click or use the arrow, Home and End keys. Tailwind's aria-selected: variant styles the active tab, so the JS only flips attributes.

<div class="w-full max-w-md">
  <div role="tablist" aria-label="Account settings" class="flex gap-6 border-b border-slate-200">
    <button type="button" role="tab" id="tab-profile" aria-controls="panel-profile" aria-selected="true" class="-mb-px border-b-2 border-transparent px-1 pb-3 text-sm font-semibold text-slate-500 transition-colors hover:text-slate-700 aria-selected:border-indigo-600 aria-selected:text-indigo-600">Profile</button>
    <button type="button" role="tab" id="tab-security" aria-controls="panel-security" aria-selected="false" tabindex="-1" class="-mb-px border-b-2 border-transparent px-1 pb-3 text-sm font-semibold text-slate-500 transition-colors hover:text-slate-700 aria-selected:border-indigo-600 aria-selected:text-indigo-600">Security</button>
    <button type="button" role="tab" id="tab-billing" aria-controls="panel-billing" aria-selected="false" tabindex="-1" class="-mb-px border-b-2 border-transparent px-1 pb-3 text-sm font-semibold text-slate-500 transition-colors hover:text-slate-700 aria-selected:border-indigo-600 aria-selected:text-indigo-600">Billing</button>
  </div>
  <div role="tabpanel" id="panel-profile" aria-labelledby="tab-profile" tabindex="0" class="pt-4 text-sm text-slate-600">Update your name, photo and public bio.</div>
  <div role="tabpanel" id="panel-security" aria-labelledby="tab-security" tabindex="0" class="pt-4 text-sm text-slate-600" hidden>Change your password and turn on two-factor authentication.</div>
  <div role="tabpanel" id="panel-billing" aria-labelledby="tab-billing" tabindex="0" class="pt-4 text-sm text-slate-600" hidden>Manage your plan, payment method and invoices.</div>
</div>

Pill Tabs

Tabs

1,284 visits this week

Same tab script as the Underline Tabs — one copy handles every tablist on the page.

<div class="w-full max-w-md">
  <div role="tablist" aria-label="Report period" class="inline-flex gap-1 rounded-full bg-slate-100 p-1">
    <button type="button" role="tab" id="tab-week" aria-controls="panel-week" aria-selected="true" class="rounded-full px-4 py-1.5 text-sm font-semibold text-slate-600 transition-colors hover:text-slate-900 aria-selected:bg-indigo-600 aria-selected:text-white aria-selected:shadow-sm">Week</button>
    <button type="button" role="tab" id="tab-month" aria-controls="panel-month" aria-selected="false" tabindex="-1" class="rounded-full px-4 py-1.5 text-sm font-semibold text-slate-600 transition-colors hover:text-slate-900 aria-selected:bg-indigo-600 aria-selected:text-white aria-selected:shadow-sm">Month</button>
    <button type="button" role="tab" id="tab-year" aria-controls="panel-year" aria-selected="false" tabindex="-1" class="rounded-full px-4 py-1.5 text-sm font-semibold text-slate-600 transition-colors hover:text-slate-900 aria-selected:bg-indigo-600 aria-selected:text-white aria-selected:shadow-sm">Year</button>
  </div>
  <div role="tabpanel" id="panel-week" aria-labelledby="tab-week" tabindex="0" class="mt-4 rounded-xl border border-slate-200 bg-white p-4 text-sm text-slate-600"><span class="text-2xl font-bold text-slate-900">1,284</span> visits this week</div>
  <div role="tabpanel" id="panel-month" aria-labelledby="tab-month" tabindex="0" class="mt-4 rounded-xl border border-slate-200 bg-white p-4 text-sm text-slate-600" hidden><span class="text-2xl font-bold text-slate-900">5,902</span> visits this month</div>
  <div role="tabpanel" id="panel-year" aria-labelledby="tab-year" tabindex="0" class="mt-4 rounded-xl border border-slate-200 bg-white p-4 text-sm text-slate-600" hidden><span class="text-2xl font-bold text-slate-900">61,340</span> visits this year</div>
</div>

Vertical Tabs

Tabs

Create a workspace, invite your team and connect your first data source.

A side list on wider screens, a scrollable row on mobile. Arrow keys move between tabs in both layouts.

<div class="flex w-full max-w-lg flex-col gap-4 sm:flex-row">
  <div role="tablist" aria-label="Help topics" class="flex shrink-0 gap-1 overflow-x-auto sm:w-40 sm:flex-col">
    <button type="button" role="tab" id="tab-start" aria-controls="panel-start" aria-selected="true" class="whitespace-nowrap rounded-lg px-3 py-2 text-left text-sm font-medium text-slate-600 transition-colors hover:bg-slate-100 aria-selected:bg-indigo-50 aria-selected:text-indigo-700">Getting started</button>
    <button type="button" role="tab" id="tab-account" aria-controls="panel-account" aria-selected="false" tabindex="-1" class="whitespace-nowrap rounded-lg px-3 py-2 text-left text-sm font-medium text-slate-600 transition-colors hover:bg-slate-100 aria-selected:bg-indigo-50 aria-selected:text-indigo-700">Account</button>
    <button type="button" role="tab" id="tab-api" aria-controls="panel-api" aria-selected="false" tabindex="-1" class="whitespace-nowrap rounded-lg px-3 py-2 text-left text-sm font-medium text-slate-600 transition-colors hover:bg-slate-100 aria-selected:bg-indigo-50 aria-selected:text-indigo-700">API access</button>
  </div>
  <div role="tabpanel" id="panel-start" aria-labelledby="tab-start" tabindex="0" class="flex-1 rounded-xl border border-slate-200 bg-white p-4 text-sm text-slate-600">Create a workspace, invite your team and connect your first data source.</div>
  <div role="tabpanel" id="panel-account" aria-labelledby="tab-account" tabindex="0" class="flex-1 rounded-xl border border-slate-200 bg-white p-4 text-sm text-slate-600" hidden>Edit your profile, notification settings and connected apps.</div>
  <div role="tabpanel" id="panel-api" aria-labelledby="tab-api" tabindex="0" class="flex-1 rounded-xl border border-slate-200 bg-white p-4 text-sm text-slate-600" hidden>Generate API keys and read the rate-limit guidelines.</div>
</div>

Segmented Control

Tabs

Calendar view

CSS-only: a radio group styled with peer-checked:, so it submits with a form and works with the keyboard out of the box.

<fieldset class="inline-flex rounded-xl bg-slate-100 p-1">
  <legend class="sr-only">Calendar view</legend>
  <label class="cursor-pointer">
    <input type="radio" name="calendar-view" value="day" class="peer sr-only" />
    <span class="block rounded-lg px-4 py-1.5 text-sm font-semibold text-slate-500 transition-colors peer-checked:bg-white peer-checked:text-slate-900 peer-checked:shadow-sm peer-focus-visible:ring-2 peer-focus-visible:ring-indigo-500">Day</span>
  </label>
  <label class="cursor-pointer">
    <input type="radio" name="calendar-view" value="week" class="peer sr-only" checked />
    <span class="block rounded-lg px-4 py-1.5 text-sm font-semibold text-slate-500 transition-colors peer-checked:bg-white peer-checked:text-slate-900 peer-checked:shadow-sm peer-focus-visible:ring-2 peer-focus-visible:ring-indigo-500">Week</span>
  </label>
  <label class="cursor-pointer">
    <input type="radio" name="calendar-view" value="month" class="peer sr-only" />
    <span class="block rounded-lg px-4 py-1.5 text-sm font-semibold text-slate-500 transition-colors peer-checked:bg-white peer-checked:text-slate-900 peer-checked:shadow-sm peer-focus-visible:ring-2 peer-focus-visible:ring-indigo-500">Month</span>
  </label>
</fieldset>

Simple Table

Tables

Team members
Name Email Role
Jane Cooper jane@example.com Admin
Devon Lane devon@example.com Editor
Kim Seo-yeon seoyeon@example.com Viewer

The overflow-x-auto wrapper plus a min-width lets the table scroll sideways on phones instead of squashing columns.

<div class="w-full overflow-x-auto rounded-xl border border-slate-200 bg-white">
  <table class="w-full min-w-[32rem] text-left text-sm">
    <caption class="sr-only">Team members</caption>
    <thead class="bg-slate-50 text-xs font-semibold uppercase tracking-wide text-slate-500">
      <tr>
        <th scope="col" class="px-4 py-3">Name</th>
        <th scope="col" class="px-4 py-3">Email</th>
        <th scope="col" class="px-4 py-3">Role</th>
      </tr>
    </thead>
    <tbody class="divide-y divide-slate-100 text-slate-600">
      <tr class="hover:bg-slate-50">
        <td class="px-4 py-3 font-medium text-slate-900">Jane Cooper</td>
        <td class="px-4 py-3">jane@example.com</td>
        <td class="px-4 py-3">Admin</td>
      </tr>
      <tr class="hover:bg-slate-50">
        <td class="px-4 py-3 font-medium text-slate-900">Devon Lane</td>
        <td class="px-4 py-3">devon@example.com</td>
        <td class="px-4 py-3">Editor</td>
      </tr>
      <tr class="hover:bg-slate-50">
        <td class="px-4 py-3 font-medium text-slate-900">Kim Seo-yeon</td>
        <td class="px-4 py-3">seoyeon@example.com</td>
        <td class="px-4 py-3">Viewer</td>
      </tr>
    </tbody>
  </table>
</div>

Striped Table with Status Badges

Tables

Recent invoices
Invoice Customer Status Amount
INV-1042 Northwind Ltd. Paid $1,250.00
INV-1043 Blue Harbor Pending $740.50
INV-1044 Pinecone Co. Overdue $3,100.00
INV-1045 Atlas Studio Paid $480.00

Zebra stripes come from odd:/even: variants; tabular-nums keeps right-aligned amounts lined up.

<div class="w-full overflow-x-auto rounded-xl border border-slate-200 bg-white">
  <table class="w-full min-w-[36rem] text-left text-sm">
    <caption class="sr-only">Recent invoices</caption>
    <thead class="border-b border-slate-200 text-slate-900">
      <tr>
        <th scope="col" class="px-4 py-3 font-semibold">Invoice</th>
        <th scope="col" class="px-4 py-3 font-semibold">Customer</th>
        <th scope="col" class="px-4 py-3 font-semibold">Status</th>
        <th scope="col" class="px-4 py-3 text-right font-semibold">Amount</th>
      </tr>
    </thead>
    <tbody class="text-slate-600">
      <tr class="odd:bg-white even:bg-slate-50">
        <td class="px-4 py-3 font-mono text-xs text-slate-500">INV-1042</td>
        <td class="px-4 py-3 font-medium text-slate-900">Northwind Ltd.</td>
        <td class="px-4 py-3"><span class="rounded-full bg-emerald-100 px-2.5 py-0.5 text-xs font-semibold text-emerald-700">Paid</span></td>
        <td class="px-4 py-3 text-right tabular-nums">$1,250.00</td>
      </tr>
      <tr class="odd:bg-white even:bg-slate-50">
        <td class="px-4 py-3 font-mono text-xs text-slate-500">INV-1043</td>
        <td class="px-4 py-3 font-medium text-slate-900">Blue Harbor</td>
        <td class="px-4 py-3"><span class="rounded-full bg-amber-100 px-2.5 py-0.5 text-xs font-semibold text-amber-800">Pending</span></td>
        <td class="px-4 py-3 text-right tabular-nums">$740.50</td>
      </tr>
      <tr class="odd:bg-white even:bg-slate-50">
        <td class="px-4 py-3 font-mono text-xs text-slate-500">INV-1044</td>
        <td class="px-4 py-3 font-medium text-slate-900">Pinecone Co.</td>
        <td class="px-4 py-3"><span class="rounded-full bg-rose-100 px-2.5 py-0.5 text-xs font-semibold text-rose-700">Overdue</span></td>
        <td class="px-4 py-3 text-right tabular-nums">$3,100.00</td>
      </tr>
      <tr class="odd:bg-white even:bg-slate-50">
        <td class="px-4 py-3 font-mono text-xs text-slate-500">INV-1045</td>
        <td class="px-4 py-3 font-medium text-slate-900">Atlas Studio</td>
        <td class="px-4 py-3"><span class="rounded-full bg-emerald-100 px-2.5 py-0.5 text-xs font-semibold text-emerald-700">Paid</span></td>
        <td class="px-4 py-3 text-right tabular-nums">$480.00</td>
      </tr>
    </tbody>
  </table>
</div>

Table with Avatars & Actions

Tables

Users

Manage who can access this workspace.

Workspace users
User Role Status Actions
LA

Leslie Alexander

leslie@example.com

Owner Active Edit, Leslie Alexander
MF

Michael Foster

michael@example.com

Member Invited Edit, Michael Foster

Each row checkbox and Edit link names its user for screen readers, so repeated controls are not ambiguous.

<div class="w-full rounded-2xl border border-slate-200 bg-white shadow-sm">
  <div class="flex flex-wrap items-center justify-between gap-3 border-b border-slate-200 px-5 py-4">
    <div>
      <h2 class="text-base font-bold text-slate-900">Users</h2>
      <p class="text-sm text-slate-500">Manage who can access this workspace.</p>
    </div>
    <button type="button" class="rounded-lg bg-indigo-600 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-indigo-700">Add user</button>
  </div>
  <div class="overflow-x-auto">
    <table class="w-full min-w-[40rem] text-left text-sm">
      <caption class="sr-only">Workspace users</caption>
      <thead class="bg-slate-50 text-xs font-semibold uppercase tracking-wide text-slate-500">
        <tr>
          <th scope="col" class="w-10 px-5 py-3"><input type="checkbox" aria-label="Select all users" class="h-4 w-4 rounded border-slate-300 accent-indigo-600" /></th>
          <th scope="col" class="px-5 py-3">User</th>
          <th scope="col" class="px-5 py-3">Role</th>
          <th scope="col" class="px-5 py-3">Status</th>
          <th scope="col" class="px-5 py-3"><span class="sr-only">Actions</span></th>
        </tr>
      </thead>
      <tbody class="divide-y divide-slate-100 text-slate-600">
        <tr class="hover:bg-slate-50">
          <td class="px-5 py-3"><input type="checkbox" aria-label="Select Leslie Alexander" class="h-4 w-4 rounded border-slate-300 accent-indigo-600" /></td>
          <td class="px-5 py-3">
            <div class="flex items-center gap-3">
              <span class="flex h-9 w-9 items-center justify-center rounded-full bg-gradient-to-br from-indigo-400 to-purple-400 text-xs font-bold text-white">LA</span>
              <div><p class="font-medium text-slate-900">Leslie Alexander</p><p class="text-xs text-slate-500">leslie@example.com</p></div>
            </div>
          </td>
          <td class="px-5 py-3">Owner</td>
          <td class="px-5 py-3"><span class="inline-flex items-center gap-1.5 text-xs font-semibold text-emerald-700"><span class="h-1.5 w-1.5 rounded-full bg-emerald-500"></span>Active</span></td>
          <td class="px-5 py-3 text-right"><a href="#" class="font-semibold text-indigo-600 hover:text-indigo-800">Edit<span class="sr-only">, Leslie Alexander</span></a></td>
        </tr>
        <tr class="hover:bg-slate-50">
          <td class="px-5 py-3"><input type="checkbox" aria-label="Select Michael Foster" class="h-4 w-4 rounded border-slate-300 accent-indigo-600" /></td>
          <td class="px-5 py-3">
            <div class="flex items-center gap-3">
              <span class="flex h-9 w-9 items-center justify-center rounded-full bg-gradient-to-br from-emerald-400 to-teal-500 text-xs font-bold text-white">MF</span>
              <div><p class="font-medium text-slate-900">Michael Foster</p><p class="text-xs text-slate-500">michael@example.com</p></div>
            </div>
          </td>
          <td class="px-5 py-3">Member</td>
          <td class="px-5 py-3"><span class="inline-flex items-center gap-1.5 text-xs font-semibold text-slate-500"><span class="h-1.5 w-1.5 rounded-full bg-slate-400"></span>Invited</span></td>
          <td class="px-5 py-3 text-right"><a href="#" class="font-semibold text-indigo-600 hover:text-indigo-800">Edit<span class="sr-only">, Michael Foster</span></a></td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

Numbered Pagination

Pagination

aria-current="page" marks the current page for screen readers; the ellipsis is hidden from them.

<nav aria-label="Pagination">
  <ul class="flex items-center gap-1 text-sm font-medium">
    <li><a href="#" class="flex h-9 items-center gap-1 rounded-lg px-3 text-slate-600 transition-colors hover:bg-slate-100"><span aria-hidden="true">‹</span> Prev</a></li>
    <li><a href="#" class="flex h-9 w-9 items-center justify-center rounded-lg text-slate-600 transition-colors hover:bg-slate-100">1</a></li>
    <li><a href="#" aria-current="page" class="flex h-9 w-9 items-center justify-center rounded-lg bg-indigo-600 text-white">2</a></li>
    <li><a href="#" class="flex h-9 w-9 items-center justify-center rounded-lg text-slate-600 transition-colors hover:bg-slate-100">3</a></li>
    <li aria-hidden="true" class="flex h-9 w-9 items-center justify-center text-slate-400">…</li>
    <li><a href="#" class="flex h-9 w-9 items-center justify-center rounded-lg text-slate-600 transition-colors hover:bg-slate-100">10</a></li>
    <li><a href="#" class="flex h-9 items-center gap-1 rounded-lg px-3 text-slate-600 transition-colors hover:bg-slate-100">Next <span aria-hidden="true">›</span></a></li>
  </ul>
</nav>

Pagination with Results Count

Pagination

Showing 21 to 30 of 97 results

Joined button group (-space-x-px) — neighbouring page numbers hide on phones to save space.

<div class="flex w-full max-w-2xl flex-col items-center justify-between gap-3 sm:flex-row">
  <p class="text-sm text-slate-600">Showing <span class="font-semibold text-slate-900">21</span> to <span class="font-semibold text-slate-900">30</span> of <span class="font-semibold text-slate-900">97</span> results</p>
  <nav aria-label="Pagination">
    <ul class="flex -space-x-px text-sm font-medium">
      <li><a href="#" class="flex h-9 items-center rounded-l-lg border border-slate-300 bg-white px-3 text-slate-600 hover:bg-slate-50">Previous</a></li>
      <li><a href="#" class="hidden h-9 w-10 items-center justify-center border border-slate-300 bg-white text-slate-600 hover:bg-slate-50 sm:flex">2</a></li>
      <li><a href="#" aria-current="page" class="relative z-10 flex h-9 w-10 items-center justify-center border border-indigo-600 bg-indigo-600 text-white">3</a></li>
      <li><a href="#" class="hidden h-9 w-10 items-center justify-center border border-slate-300 bg-white text-slate-600 hover:bg-slate-50 sm:flex">4</a></li>
      <li><a href="#" class="flex h-9 items-center rounded-r-lg border border-slate-300 bg-white px-3 text-slate-600 hover:bg-slate-50">Next</a></li>
    </ul>
  </nav>
</div>

Previous / Next Pagination

Pagination

On the first page, Previous is a plain span with aria-disabled rather than a dead link.

<nav aria-label="Pagination" class="flex w-full max-w-md items-center justify-between gap-3">
  <span aria-disabled="true" class="inline-flex cursor-not-allowed items-center gap-2 rounded-xl border border-slate-200 px-4 py-2 text-sm font-semibold text-slate-400">
    <span aria-hidden="true">←</span> Previous
  </span>
  <p class="text-sm text-slate-500">Page <span class="font-semibold text-slate-900">1</span> of 12</p>
  <a href="#" class="inline-flex items-center gap-2 rounded-xl border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-700 shadow-sm transition-colors hover:bg-slate-50">
    Next <span aria-hidden="true">→</span>
  </a>
</nav>

Spinner with Label

CSS Loaders

Loading…

Pure Tailwind (animate-spin). role="status" lets screen readers announce the visible label.

<div role="status" class="inline-flex items-center gap-3 text-sm font-medium text-slate-600">
  <span class="h-5 w-5 animate-spin rounded-full border-2 border-indigo-200 border-t-indigo-600"></span>
  Loading…
</div>

Dual Ring Spinner

CSS Loaders

Loading…

Pure Tailwind: two opposite colored borders on a spinning circle.

<div role="status">
  <span class="block h-10 w-10 animate-spin rounded-full border-4 border-x-transparent border-y-indigo-600"></span>
  <span class="sr-only">Loading…</span>
</div>

Bouncing Dots

CSS Loaders

Loading…

Tailwind animate-bounce with staggered [animation-delay] values. Stops for users who prefer reduced motion.

<div role="status" class="flex items-center gap-1.5">
  <span class="h-2.5 w-2.5 animate-bounce rounded-full bg-indigo-600 [animation-delay:-0.3s] motion-reduce:animate-none"></span>
  <span class="h-2.5 w-2.5 animate-bounce rounded-full bg-indigo-600 [animation-delay:-0.15s] motion-reduce:animate-none"></span>
  <span class="h-2.5 w-2.5 animate-bounce rounded-full bg-indigo-600 motion-reduce:animate-none"></span>
  <span class="sr-only">Loading…</span>
</div>

Pulse Ping

CSS Loaders

Loading…

Pure Tailwind (animate-ping) — a radar-style pulse that also works as a live indicator.

<div role="status" class="relative flex h-10 w-10 items-center justify-center">
  <span class="absolute inline-flex h-full w-full animate-ping rounded-full bg-indigo-400 opacity-75 motion-reduce:animate-none"></span>
  <span class="relative inline-flex h-4 w-4 rounded-full bg-indigo-600"></span>
  <span class="sr-only">Loading…</span>
</div>

Equalizer Bars

CSS Loaders

Loading…

Also copy the CSS tab — this component needs its custom @keyframes to animate.

<div role="status" class="ldr-bars flex h-8 items-center gap-1">
  <div class="h-full w-1.5 rounded-full bg-indigo-600"></div>
  <div class="h-full w-1.5 rounded-full bg-indigo-600"></div>
  <div class="h-full w-1.5 rounded-full bg-indigo-600"></div>
  <div class="h-full w-1.5 rounded-full bg-indigo-600"></div>
  <div class="h-full w-1.5 rounded-full bg-indigo-600"></div>
  <span class="sr-only">Loading…</span>
</div>

SVG Ring Spinner

CSS Loaders

Loading…

A Material-style growing arc: the SVG rotates while the stroke-dasharray stretches and shrinks. Color follows text-* via currentColor.

Also copy the CSS tab — this component needs its custom @keyframes to animate.

<div role="status" class="inline-flex">
  <svg class="ldr-ring h-10 w-10 text-indigo-600" viewBox="0 0 50 50" aria-hidden="true">
    <circle cx="25" cy="25" r="20" fill="none" stroke="currentColor" stroke-width="5" opacity="0.15" />
    <circle class="ldr-ring-arc" cx="25" cy="25" r="20" fill="none" stroke="currentColor" stroke-width="5" stroke-linecap="round" />
  </svg>
  <span class="sr-only">Loading…</span>
</div>

Indeterminate Progress Bar

CSS Loaders

role="progressbar" without aria-valuenow tells assistive tech the progress is indeterminate.

Also copy the CSS tab — this component needs its custom @keyframes to animate.

<div role="progressbar" aria-label="Loading" class="relative h-1.5 w-full max-w-sm overflow-hidden rounded-full bg-indigo-100">
  <div class="ldr-indeterminate absolute inset-y-0 left-0 w-1/3 rounded-full bg-indigo-600"></div>
</div>

Skeleton Card

CSS Loaders

Loading…

Pure Tailwind (animate-pulse). Match the skeleton to your real card's layout to avoid layout shift.

<div role="status" class="w-full max-w-sm animate-pulse rounded-2xl border border-slate-200 bg-white p-5">
  <div class="flex items-center gap-3">
    <div class="h-10 w-10 rounded-full bg-slate-200"></div>
    <div class="flex-1 space-y-2">
      <div class="h-3 w-1/2 rounded bg-slate-200"></div>
      <div class="h-3 w-1/3 rounded bg-slate-200"></div>
    </div>
  </div>
  <div class="mt-5 space-y-2">
    <div class="h-3 rounded bg-slate-200"></div>
    <div class="h-3 w-5/6 rounded bg-slate-200"></div>
  </div>
  <span class="sr-only">Loading…</span>
</div>

Frequently Asked Questions

Is the UI component library free to use?↓

Yes, all components are completely free to copy and use in personal or commercial projects, with no attribution required.

Do these components require Tailwind CSS?↓

The HTML snippets use Tailwind CSS utility classes, so you'll need Tailwind CSS set up in your project for them to render as shown. A few components, such as some of the CSS loaders, also include a small custom CSS block with @keyframes for animations not covered by Tailwind's defaults; copy it from the CSS tab.

Do any components require JavaScript?↓

Most components are pure HTML and CSS. A few interactive ones (toast notifications, modal dialogs and accessible tabs) include a short vanilla JavaScript snippet, shown in a separate JS tab. The responsive navbar's mobile menu and the pricing billing toggle work with no JavaScript at all.

How do I copy a component's code?↓

Click the HTML, JSX, CSS, or JS tab on any component card, then click the Copy button to copy that code to your clipboard. The JSX tab converts the markup for React (className, self-closing tags). Use the link icon to copy a direct link to a single component.

Last updated: