Core Primitives Tailwind v4 Pure HTML5 Zero-JS

Button

Interactive button primitives with rich visual variants, loading spinners, icons, and keyboard accessibility.

Interactive Preview

Live Edit & Viewport Resizer
Variants:

Installation

Add the Button component to your project via CLI:

terminal bash
npx plain-ui add button

Features

  • Semantic HTML <button> and <a> support
  • 6 visual styles: Primary, Secondary, Outline, Ghost, Destructive, Link
  • 4 size presets: sm, md, lg, icon
  • Accessible focus rings, active scaling, disabled states
  • Loading state with animated inline SVG spinner

Variants & Examples

Standard Styles

All core visual styles and hierarchy presets.

button-standard-styles.html html
<div class="flex flex-wrap items-center justify-center gap-4">
  <button class="px-4 py-2 text-sm font-medium text-white bg-zinc-900 dark:bg-zinc-100 dark:text-zinc-900 rounded-lg hover:bg-zinc-800 dark:hover:bg-zinc-200 active:scale-95 transition-all shadow-sm cursor-pointer">Primary</button>
  <button class="px-4 py-2 text-sm font-medium text-zinc-800 bg-zinc-100 dark:bg-zinc-800 dark:text-zinc-200 rounded-lg hover:bg-zinc-200 dark:hover:bg-zinc-700 active:scale-95 transition-all cursor-pointer">Secondary</button>
  <button class="px-4 py-2 text-sm font-medium text-zinc-800 dark:text-zinc-200 border border-zinc-300 dark:border-zinc-700 rounded-lg hover:bg-zinc-100 dark:hover:bg-zinc-800 active:scale-95 transition-all cursor-pointer">Outline</button>
  <button class="px-4 py-2 text-sm font-medium text-zinc-600 dark:text-zinc-400 hover:text-zinc-900 dark:hover:text-zinc-100 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg transition-all cursor-pointer">Ghost</button>
  <button class="px-4 py-2 text-sm font-medium text-red-600 bg-red-50 hover:bg-red-100 dark:bg-red-950/40 dark:hover:bg-red-900/40 dark:text-red-400 rounded-lg active:scale-95 transition-all cursor-pointer">Soft Destructive</button>
  <button class="text-sm font-medium text-blue-600 dark:text-blue-400 underline-offset-4 hover:underline cursor-pointer">Link Button</button>
</div>

Sizes & Loading

Compact small, medium, large sizes, plus loading spinner and disabled state.

button-sizes-&-loading.html html
<div class="flex flex-wrap items-center justify-center gap-4">
  <!-- Small -->
  <button class="px-2.5 py-1.5 text-xs font-medium bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900 rounded-md cursor-pointer">Small</button>
  
  <!-- Medium -->
  <button class="px-4 py-2 text-sm font-medium bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900 rounded-lg cursor-pointer">Medium</button>
  
  <!-- Large -->
  <button class="px-6 py-3 text-base font-semibold bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900 rounded-xl cursor-pointer">Large</button>

  <!-- Loading State -->
  <button disabled class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900 rounded-lg opacity-75 cursor-wait">
    <svg class="w-4 h-4 animate-spin" viewBox="0 0 24 24" fill="none">
      <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
      <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z"></path>
    </svg>
    Processing...
  </button>

  <!-- Disabled -->
  <button disabled class="px-4 py-2 text-sm font-medium bg-zinc-200 text-zinc-400 dark:bg-zinc-800 dark:text-zinc-600 rounded-lg cursor-not-allowed">Disabled</button>
</div>

With Icons

Buttons with leading icons, trailing arrows, and icon-only floating buttons.

button-with-icons.html html
<div class="flex flex-wrap items-center justify-center gap-4">
  <button class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium bg-zinc-900 text-white dark:bg-zinc-100 dark:text-zinc-900 rounded-lg hover:bg-zinc-800 shadow-sm cursor-pointer">
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/></svg>
    New Project
  </button>

  <button class="inline-flex items-center gap-2 px-4 py-2 text-sm font-medium bg-blue-600 text-white hover:bg-blue-700 rounded-lg shadow-sm transition-all cursor-pointer">
    Continue
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14 5l7 7m0 0l-7 7m7-7H3"/></svg>
  </button>

  <button aria-label="Bookmark" class="p-2.5 text-zinc-700 dark:text-zinc-300 hover:bg-zinc-100 dark:hover:bg-zinc-800 rounded-lg border border-zinc-200 dark:border-zinc-700 transition-all cursor-pointer">
    <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z"/></svg>
  </button>
</div>

Attributes & Classes

Attribute / Prop Type Default Description
type button | submit | reset button Semantic HTML button type.
disabled boolean false Disables button interactions and reduces opacity.
aria-label string - Required for icon-only buttons for screen reader access.

Accessibility & Keyboard Navigation

  • Uses native <button> elements with full keyboard activation via Space and Enter.
  • Always provide an aria-label when rendering icon-only buttons.
  • Focus rings use focus-visible:ring-2 to preserve keyboard navigation clarity without mouse clutter.
Components
#
Button
Interactive button primitives with rich visual variants, loading spinners, icons, and keyboard accessibility.
Core Primitives
#
Dialog
Native HTML <dialog> modal with backdrop blur, @starting-style entry animations, and accessible focus trapping.
Overlays & Modals
#
Popover
Native HTML Popover API (popover='auto') with zero JavaScript, CSS anchor positioning, and automatic light dismiss.
Overlays & Modals
#
Floating Label Input
Modern animated floating label form controls utilizing HTML5 placeholder-shown pseudo-class and Tailwind peer selectors.
Forms & Inputs
#
Border Beam
Dynamic glowing animated border beam gradient traveling continuously around cards and containers using pure CSS animations.
Motion & Effects
#
Shimmer Button
High-performance glowing shimmer button with animated radial light sweep across the surface.
Motion & Effects
#
Dock
macOS-inspired interactive dock with smooth pointer proximity magnification physics, hover tooltips, and app status dots.
Layout & Navigation
#
Bento Grid
Modern modular 12-column asymmetric bento box layout with spotlight card glow, metric widgets, and responsive auto-fitting.
Layout & Surfaces
#
Accordion
Pure HTML <details> and <summary> accordion with smooth height expansion animation and animated rotating chevrons.
Core Primitives
#
Tabs
Accessible, keyboard-navigable tab system with animated indicator slider and light-DOM panels.
Layout & Navigation
Getting Started
📖
Getting Started & Tailwind v4 Setup
Quick start guide and architecture overview
Navigate Select
Plain UI Search