DaisyUI 5 Masterclass Reference

Production-grade reference for Funday. Zero setup, zero bloat, 100% truth.


Component Class Formula

<element class="COMPONENT [STYLE] [COLOR] [SIZE] [MODIFIER] [BEHAVIOR] [PLACEMENT]">
  <child class="PART">content</child>
</element>
SlotExamplesRequired?
COMPONENTbtn, card, modal, input, dropdown, drawer, tabs, accordion, avatar, badge, alert, navbar, menu, tab, progress, loading, tooltip, swap, divider, stat, kbd, join, mask, indicator, radial-progress, countdown, diff, chat, carousel, collapse, fieldset, label, range, rating, select, textarea, toggle, checkbox, radio, file-input, filter, calendar, validator, breadcrumbs, dock, link, pagination, steps, hero, footer, stack, toast, table, timeline, hover-3d, hover-gallery, text-rotate, mockup-browser, mockup-code, mockup-phone, mockup-window, theme-controller, fab, glass, aura✅ YES
STYLEbtn-outline, btn-dash, btn-soft, btn-ghost, btn-link / card-border, card-dash / alert-outline, alert-dash, alert-soft / input-ghost, select-ghost / tabs-box, tabs-border, tabs-lift / badge-outline, badge-dash, badge-soft, badge-ghostNo
COLORprimary, secondary, accent, neutral, info, success, warning, error, base-100, base-200, base-300No
SIZExs, sm, md, lg, xl (prefixed: btn-, badge-, input-, select-, tab-, menu-, avatar-, kbd-, aura-, collapse-, divider-, stat-, loading-, progress-, radial-progress-, tooltip-, join-, indicator-, countdown-, diff-, carousel-, mockup-)No
MODIFIERbtn-wide, btn-block, btn-circle, btn-square / card-side, image-full / modal-top, modal-bottom, modal-middle, modal-start, modal-end / drawer-end / tabs-top, tabs-bottom / menu-horizontal / alert-vertical, alert-horizontal / collapse-arrow, collapse-plus / avatar-online, avatar-offline, avatar-placeholder / mask-squircle, mask-hexagon, mask-triangle / join-*No
BEHAVIORbtn-active, btn-disabled / tab-active, tab-disabled / menu-active / collapse-open, collapse-close / modal-open / drawer-open / swap-on, swap-off / checkbox-checked, radio-checked / toggle-on, toggle-off / input-checkedState only
PLACEMENTmodal-top, modal-middle, modal-bottom, modal-start, modal-end / drawer-end / tooltip-top, tooltip-bottom, tooltip-left, tooltip-rightComponent-specific

Color System — Only These Exist

SemanticBackgroundForegroundUse For
primarybg-primarytext-primary-contentMain CTA
secondarybg-secondarytext-secondary-contentSecondary brand
accentbg-accenttext-accent-contentHighlights
neutralbg-neutraltext-neutral-contentSubdued UI
base-100bg-base-100text-base-contentPage background
base-200bg-base-200text-base-contentElevated surface
base-300bg-base-300text-base-contentMore elevation
infobg-infotext-info-contentInfo messages
successbg-successtext-success-contentSuccess states
warningbg-warningtext-warning-contentCaution
errorbg-errortext-error-contentErrors, destructive

All work with every Tailwind utility: bg-, text-, border-, ring-, shadow-, fill-, stroke-, divide-, placeholder-, ring-offset-, from-, via-, to-, accent-, caret-, decoration-

<!-- ✅ Theme-adaptive -->
<button class="btn btn-primary">Primary</button>
<div class="bg-base-200 text-base-content/60">Muted text on elevated surface</div>
 
<!-- ❌ Never: hardcoded colors break dark mode -->
<div class="bg-blue-500 text-gray-800">Broken on dark theme</div>

Button — Complete Variants

<!-- Styles -->
<button class="btn">Default solid</button>
<button class="btn btn-outline">Outline</button>
<button class="btn btn-dash">Dashed</button>
<button class="btn btn-soft">Soft tint</button>
<button class="btn btn-ghost">Ghost (hover only)</button>
<button class="btn btn-link">Link look</button>
 
<!-- Colors -->
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-accent">Accent</button>
<button class="btn btn-neutral">Neutral</button>
<button class="btn btn-success">Success</button>
<button class="btn btn-warning">Warning</button>
<button class="btn btn-error">Error</button>
<button class="btn btn-info">Info</button>
 
<!-- Sizes -->
<button class="btn btn-xs">XS</button>
<button class="btn btn-sm">SM</button>
<button class="btn btn-md">MD (default)</button>
<button class="btn btn-lg">LG</button>
<button class="btn btn-xl">XL</button>
 
<!-- Shapes -->
<button class="btn btn-wide">Wide</button>
<button class="btn btn-block">Full width</button>
<button class="btn btn-circle">Circle</button>
<button class="btn btn-square">Square</button>
 
<!-- States -->
<button class="btn btn-active">Active</button>
<button class="btn btn-disabled">Disabled</button>
 
<!-- Responsive (v5+) -->
<button class="btn btn-sm lg:btn-lg">Responsive size</button>

Card

<div class="card bg-base-100 shadow-xl">
  <figure><img src="..." alt="..." /></figure>
  <div class="card-body">
    <h2 class="card-title">Title</h2>
    <p>Description</p>
    <div class="card-actions justify-end">
      <button class="btn btn-primary">Action</button>
    </div>
  </div>
</div>
 
<!-- Variants -->
<div class="card card-border">Border</div>
<div class="card card-dash">Dashed</div>
<div class="card card-side">Horizontal</div>
<div class="card image-full">Full image</div>
 
<!-- Sizes: card-xs, card-sm, card-md, card-lg, card-xl -->

<button onclick="my_modal.showModal()" class="btn">Open</button>
 
<dialog id="my_modal" class="modal">
  <div class="modal-box">
    <h3 class="text-lg font-bold">Title</h3>
    <p class="py-4">Content</p>
    <div class="modal-action">
      <form method="dialog"><button class="btn">Close</button></form>
    </div>
  </div>
  <form method="dialog" class="modal-backdrop"><button>Close</button></form>
</dialog>
 
<!-- Placements: modal-top, modal-middle (default), modal-bottom, modal-start, modal-end -->

Tabs (Radio-Based, No JS)

<div class="tabs tabs-lift">
  <input type="radio" name="tabs" class="tab" aria-label="Tab 1" checked />
  <div class="tab-content bg-base-100 border-base-300 p-6">Content 1</div>
  <input type="radio" name="tabs" class="tab" aria-label="Tab 2" />
  <div class="tab-content bg-base-100 border-base-300 p-6">Content 2</div>
  <input type="radio" name="tabs" class="tab" aria-label="Tab 3" disabled />
  <div class="tab-content bg-base-100 border-base-300 p-6">Disabled</div>
</div>
 
<!-- Styles: tabs-box, tabs-border, tabs-lift (default) -->
<!-- Placement: tabs-top (default), tabs-bottom -->

Drawer — FUNDAY CRITICAL FIX

<!-- ⚠️ BROKEN: DaisyUI default grid collapses to 0px on lg: -->
<div class="drawer lg:drawer-open">
  <input id="drawer" type="checkbox" class="drawer-toggle" />
  <div class="drawer-content">Main</div>
  <div class="drawer-side"><label for="drawer" class="drawer-overlay"></label>Sidebar</div>
</div>
 
<!-- ✅ FIX 1: CSS Override (add to app.css) -->
.drawer.lg\:drawer-open {
  grid-template-columns: max-content auto !important;
}
 
<!-- ✅ FIX 2: Flexbox Sidebar (RECOMMENDED - no grid fragility) -->
<div class="flex min-h-screen">
  <aside class="w-64 bg-base-200 lg:w-64 hidden lg:block">Sidebar</aside>
  <main class="flex-1">Main content</main>
</div>
 
<!-- Mobile drawer (works correctly) -->
<div class="drawer">
  <input id="mobile-drawer" type="checkbox" class="drawer-toggle" />
  <div class="drawer-content">
    <nav class="navbar bg-base-300">
      <label for="mobile-drawer" class="btn btn-square btn-ghost lg:hidden">☰</label>
      <div class="px-4">Title</div>
    </nav>
    <main class="p-4">Content</main>
  </div>
  <div class="drawer-side">
    <label for="mobile-drawer" class="drawer-overlay"></label>
    <ul class="menu min-h-full w-80 bg-base-200 p-4">
      <li><a>Item 1</a></li>
      <li><a>Item 2</a></li>
    </ul>
  </div>
</div>

Badge

<!-- Styles: badge, badge-outline, badge-dash, badge-soft, badge-ghost -->
<!-- Colors: badge-primary, badge-secondary, badge-accent, badge-neutral, badge-success, badge-warning, badge-error, badge-info -->
<!-- Sizes: badge-xs, badge-sm, badge-md, badge-lg, badge-xl -->
<span class="badge badge-primary badge-lg">Primary Large</span>

Alert

<div role="alert" class="alert">Default</div>
<div role="alert" class="alert alert-outline">Outline</div>
<div role="alert" class="alert alert-dash">Dashed</div>
<div role="alert" class="alert alert-soft">Soft</div>
 
<div role="alert" class="alert alert-info">Info</div>
<div role="alert" class="alert alert-success">Success</div>
<div role="alert" class="alert alert-warning">Warning</div>
<div role="alert" class="alert alert-error">Error</div>
 
<div role="alert" class="alert alert-vertical">Stacked</div>
<div role="alert" class="alert alert-horizontal sm:alert-horizontal">Responsive horizontal</div>

Input / Select / Textarea

<input type="text" class="input input-bordered w-full max-w-xs" placeholder="Text" />
<input type="text" class="input input-ghost w-full max-w-xs" placeholder="Ghost" />
<input type="text" class="input input-primary w-full max-w-xs" placeholder="Primary" />
<input type="text" class="input input-error w-full max-w-xs" placeholder="Error" />
<input type="text" class="input input-xs w-full max-w-xs" placeholder="XS" />
<input type="text" class="input input-sm w-full max-w-xs" placeholder="SM" />
<input type="text" class="input input-md w-full max-w-xs" placeholder="MD" />
<input type="text" class="input input-lg w-full max-w-xs" placeholder="LG" />
<input type="text" class="input input-xl w-full max-w-xs" placeholder="XL" />
<input type="text" class="input" disabled placeholder="Disabled" />
 
<select class="select select-bordered w-full max-w-xs">
  <option value="">Select...</option>
  <option value="1">Option 1</option>
</select>
<select class="select select-ghost w-full max-wxs">...</select>
<select class="select select-primary w-full max-w-xs">...</select>
 
<textarea class="textarea textarea-bordered h-24 w-full max-w-xs" placeholder="Textarea"></textarea>
<textarea class="textarea textarea-ghost h-24 w-full max-w-xs"></textarea>
<textarea class="textarea textarea-primary h-24 w-full max-w-xs"></textarea>

Loading / Progress / Radial Progress

<span class="loading loading-spinner loading-lg"></span>
<span class="loading loading-dots loading-lg"></span>
<span class="loading loading-ring loading-lg"></span>
<span class="loading loading-ball loading-lg"></span>
<span class="loading loading-bar loading-lg"></span>
<span class="loading loading-infinity loading-lg"></span>
 
<span class="loading loading-spinner text-primary"></span>
 
<progress class="progress progress-primary w-full" value="50" max="100"></progress>
<progress class="progress progress-secondary w-full" value="30" max="100"></progress>
 
<div class="radial-progress" style="--value: 50; --size: 80px;"></div>
<div class="radial-progress radial-progress-primary" style="--value: 75; --size: 100px;"></div>

<nav class="navbar bg-base-300">
  <div class="navbar-start">
    <div class="dropdown">
      <label tabindex="0" class="btn btn-ghost btn-circle">☰</label>
      <ul class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
        <li><a>Item 1</a></li>
        <li><a>Item 2</a></li>
      </ul>
    </div>
    <a class="btn btn-ghost text-xl">Funday</a>
  </div>
  <div class="navbar-center">
    <ul class="menu menu-horizontal px-1">
      <li><a>Games</a></li>
      <li><a>Leaderboard</a></li>
      <li><a>Profile</a></li>
    </ul>
  </div>
  <div class="navbar-end">
    <button class="btn btn-primary">Play</button>
  </div>
</nav>

Dock (Mobile Bottom Nav — Funday Play Shell)

<div class="dock">
  <label for="dock-game" class="dock-item">
    <input type="radio" name="dock" id="dock-game" class="dock-toggle" checked />
    <svg class="dock-icon"><use href="#icon-game"></use></svg>
    <span class="dock-label">Game</span>
  </label>
  <label for="dock-chat" class="dock-item">
    <input type="radio" name="dock" id="dock-chat" class="dock-toggle" />
    <svg class="dock-icon"><use href="#icon-chat"></use></svg>
    <span class="dock-label">Chat</span>
  </label>
  <label for="dock-profile" class="dock-item">
    <input type="radio" name="dock" id="dock-profile" class="dock-toggle" />
    <svg class="dock-icon"><use href="#icon-profile"></use></svg>
    <span class="dock-label">Profile</span>
  </label>
</div>

Theme Config (Funday Default)

/* src/app.css */
@import "tailwindcss";
@plugin "daisyui" {
  themes: light --default, dark --prefersdark;
}
 
/* Custom Funday theme (OKLCH) */
@plugin "daisyui/theme" {
  name: "funday";
  default: true;
  prefersdark: false;
  color-scheme: light;
  
  --color-base-100: oklch(98% 0.02 240);
  --color-base-200: oklch(95% 0.03 240);
  --color-base-300: oklch(92% 0.04 240);
  --color-base-content: oklch(20% 0.05 240);
  --color-primary: oklch(55% 0.3 240);
  --color-primary-content: oklch(98% 0.01 240);
  --color-secondary: oklch(70% 0.25 200);
  --color-secondary-content: oklch(98% 0.01 200);
  --color-accent: oklch(65% 0.25 160);
  --color-accent-content: oklch(98% 0.01 160);
  --color-neutral: oklch(50% 0.05 240);
  --color-neutral-content: oklch(98% 0.01 240);
  --color-info: oklch(70% 0.2 220);
  --color-info-content: oklch(98% 0.01 220);
  --color-success: oklch(65% 0.25 140);
  --color-success-content: oklch(98% 0.01 140);
  --color-warning: oklch(80% 0.25 80);
  --color-warning-content: oklch(20% 0.05 80);
  --color-error: oklch(65% 0.3 30);
  --color-error-content: oklch(98% 0.01 30);
  
  --radius-selector: 1rem;
  --radius-field: 0.25rem;
  --radius-box: 0.5rem;
  --size-selector: 0.25rem;
  --size-field: 0.25rem;
  --border: 1px;
  --depth: 1;
  --noise: 0;
}

Theme switching:

<div data-theme="dark">Dark section</div>
<div data-theme="cupcake">Cupcake section</div>
 
<input type="radio" name="theme" class="theme-controller" value="light" />
<input type="radio" name="theme" class="theme-controller" value="dark" />
<input type="radio" name="theme" class="theme-controller" value="cupcake" />

Join

<div class="join">
  <input type="text" class="join-item" placeholder="Username" />
  <button class="btn join-item">@</button>
</div>
 
<div class="join join-vertical">...</div>  <!-- stacked -->
<div class="join">...</div>  <!-- horizontal (default) -->
 
<div class="join">
  <input class="join-item join-item-start" />  <!-- rounded left/top -->
  <input class="join-item join-item-end" />    <!-- rounded right/bottom -->
</div>

FUNDAY AESTHETIC CONSTRAINT — PURE SOLID BEAUTY

✅ DO❌ DON’T
bg-base-100, bg-primary, bg-secondary (100% opaque)backdrop-blur, glass, bg-base-100/50
shadow-sm, shadow, shadow-lg, shadow-xl, shadow-2xlOpacity-based depth
ring-1 ring-base-content/10 for subtle bordersTranslucent overlays
rounded-box, rounded-field, rounded-selector (theme tokens)Hardcoded rounded-lg, rounded-xl

Mantra: Solid, high-performance, sharply readable. Elevate with clarity, not blur.


Svelte 5 Integration

<script>
  let drawerOpen = $state(false);
  let activeTab = $state('tab1');
  let accordionOpen = $state(false);
  let isOpen = $state(false);
  let dropdownOpen = $state(false);
  let userTheme = $state('light');
</script>
 
<!-- Drawer -->
<div class="drawer">
  <input type="checkbox" class="drawer-toggle" bind:checked={drawerOpen} />
  <div class="drawer-content">Main</div>
  <div class="drawer-side">Sidebar</div>
</div>
 
<!-- Modal -->
<dialog bind:open={isOpen} class="modal">
  <div class="modal-box">Content</div>
  <form method="dialog" class="modal-backdrop"></form>
</dialog>
 
<!-- Tabs -->
<div class="tabs tabs-lift">
  <input type="radio" name="tabs" class="tab" bind:group={activeTab} value="tab1" />
  <div class="tab-content">Tab 1</div>
  <input type="radio" name="tabs" class="tab" bind:group={activeTab} value="tab2" />
  <div class="tab-content">Tab 2</div>
</div>
 
<!-- Native events -->
<button onclick={handleClick} class="btn btn-primary">Click</button>
<input oninput={handleInput} class="input" />
 
<!-- ARIA from runes -->
<button aria-expanded={dropdownOpen} class="btn">Menu</button>
<div role="alert" class="alert alert-success">Saved!</div>
 
<!-- Dynamic theme -->
<div data-theme={userTheme}>...</div>

Common Pitfalls

❌ Mistake✅ Fix
dark:bg-gray-800 for themingbg-base-200 — auto-adapts
text-gray-800 on bg-base-100text-base-content
rounded-lg on cardsrounded-box (theme token)
Custom CSS for btn hoverbtn-ghost, btn-outline, btn-soft
Nesting component classesEach component is self-contained
@apply for everythingOnly for new custom variants
Forgetting data-theme for previewsAdd data-theme="x" on container
v4 syntax daisyui: { themes: [] }v5: @plugin "daisyui" { themes: }
Drawer grid = 0px widthFlexbox sidebar OR CSS override
<button aria-label="X">X</button>Remove aria-label if visible text exists

Size Scale

SizeMultiplierHeightUse
xs×624pxDense UIs, badges
sm×832pxCompact forms
md×1040pxDefault
lg×1248pxProminent CTAs
xl×1456pxHero actions

Component CSS Variables (Inline Override)

<div class="alert [--alert-color:blue]">Custom blue alert</div>
<button class="btn [--btn-color:oklch(50%_0.2_200)]">Custom color</button>
<div class="radial-progress" style="--value: 75; --size: 120px; --thickness: 8px;"></div>
ComponentKey Variables
Alert—alert-color
Badge—badge-color, —size
Button—btn-color, —btn-fg, —btn-shadow, —btn-p, —size
Card—card-p, —card-fs, —cardtitle-fs
Modal—modal-tl, —modal-tr, —modal-bl, —modal-br
Radial Progress—value, —size, —thickness
Tab—tabs-height, —tab-p, —tab-bg, —tab-border-color
Toast—toast-x, —toast-y
Tooltip—tt-bg, —tt-off, —tt-tailw
Glass—glass-blur, —glass-opacity, —glass-reflect-*
Join—join-ss, —join-se, —join-es, —join-ee

Verification Checklist (Pre-Ship)

  • All colors use semantic daisyUI names — no hardcoded Tailwind colors
  • No backdrop-blur, glass, or opacity backgrounds — Pure Solid Beauty
  • Border radius uses rounded-box / rounded-field / rounded-selector
  • Drawer sidebar uses flexbox or CSS grid override applied
  • Svelte 5 runes for all checkbox/radio state (no document.getElementById)
  • Native events (onclick, oninput) not on:click
  • ARIA attributes bound to runes (aria-expanded={isOpen})
  • Responsive modifiers work (lg:btn-lg, sm:alert-horizontal)
  • Theme test: toggle data-theme="dark" on <html> — nothing breaks
  • Build passes: bash ../scripts/build-atomic.sh --no-restart


Source: daisyUI 5 llms.txt + Funday production patterns. Triple-checked against live funday.gg codebase.

Ask Docs

AI assistant to help answer questions about the documentation. Answers are read-only and cite docs/source.

Hi! How can I help you with the documentation today? Answers are read-only and cite docs/source.

Ctrl+Enter to send