Icon Button
Square or circular button containing only an icon — for toolbar actions, floating controls, and compact UIs.
Shapes
Square (radius-sm) · Rounded (radius-md) · Circle (btn-circle)
<!-- Square -->
<button class="btn btn-primary" style="border-radius:var(--radius-sm); width:2.5rem; height:2.5rem; padding:0;" aria-label="Add">
<i data-lucide="plus" style="width:16px;height:16px;"></i>
</button>
<!-- Circle (DaisyUI built-in) -->
<button class="btn btn-primary btn-circle" aria-label="Add">
<i data-lucide="plus" style="width:16px;height:16px;"></i>
</button>
Sizes
xs · sm · md (default) · lg
<button class="btn btn-primary btn-xs btn-circle" aria-label="...">...</button>
<button class="btn btn-primary btn-sm btn-circle" aria-label="...">...</button>
<button class="btn btn-primary btn-circle" aria-label="...">...</button>
<button class="btn btn-primary btn-lg btn-circle" aria-label="...">...</button>
Variants
primary · secondary · outline · ghost · error
<button class="btn btn-primary btn-circle" aria-label="Edit">...</button>
<button class="btn btn-secondary btn-circle" aria-label="Edit">...</button>
<button class="btn btn-outline btn-circle" aria-label="Edit">...</button>
<button class="btn btn-ghost btn-circle" aria-label="Edit">...</button>
<button class="btn btn-error btn-circle" aria-label="Delete">...</button>
States
Default
Hover
loading = false, 2000)">
Loading
Disabled
Click the Toggle button to see active state · Click Loading to trigger spinner
<!-- Toggle active state -->
<button class="btn btn-circle"
:class="active ? 'btn-primary' : 'btn-outline'"
@click="active = !active"
:aria-pressed="active"
x-data="{ active: false }"
aria-label="Toggle favourite">
<i data-lucide="heart" style="width:16px;height:16px;"
:style="active ? 'fill:currentColor' : ''"></i>
</button>
<!-- Loading state -->
<button class="btn btn-primary btn-circle"
:disabled="loading"
x-data="{ loading: false }"
@click="loading = true; setTimeout(() => loading = false, 2000)"
aria-label="Upload">
<span x-show="loading" class="loading loading-spinner loading-xs"></span>
<i data-lucide="upload" style="width:16px;height:16px;" x-show="!loading"></i>
</button>
<!-- Disabled -->
<button class="btn btn-outline btn-circle" disabled aria-label="...">...</button>
With Tooltip
Use DaisyUI's tooltip wrapper — no JS or Floating UI needed for simple labels.
Hover each button to see the tooltip
<div class="tooltip" data-tip="New file">
<button class="btn btn-ghost btn-circle" aria-label="New file">
<i data-lucide="file-plus" style="width:16px;height:16px;"></i>
</button>
</div>
<!-- tooltip-right / tooltip-bottom / tooltip-left also available -->
Toolbar Group
Use the DaisyUI join utility to group related icon buttons without gaps.
Alignment group is interactive — click to toggle active state
<!-- Static group -->
<div class="join" role="group" aria-label="Text formatting">
<button class="btn btn-outline join-item" style="padding:0; width:2.5rem;" aria-label="Bold">
<i data-lucide="bold" style="width:15px;height:15px;"></i>
</button>
<button class="btn btn-outline join-item" style="padding:0; width:2.5rem;" aria-label="Italic">
<i data-lucide="italic" style="width:15px;height:15px;"></i>
</button>
</div>
<!-- Toggle group (Alpine.js) -->
<div class="join" role="group" aria-label="Text alignment"
x-data="{ align: 'left' }">
<button class="btn join-item" style="padding:0; width:2.5rem;"
:class="align === 'left' ? 'btn-primary' : 'btn-outline'"
@click="align = 'left'" aria-label="Align left">
<i data-lucide="align-left" style="width:15px;height:15px;"></i>
</button>
<!-- repeat for center / right -->
</div>
Usage Notes
- Always provide
aria-label— icon-only buttons have no visible text label for screen readers. - Use
btn-circlefor standalone floating actions; use square orjoin-itemfor toolbar groups where consistent alignment matters more than shape. - Prefer
btn-ghostinside toolbars and sidebars to keep visual weight low; reservebtn-primaryfor the single most important action in a set. - Use DaisyUI's
tooltipwrapper for hover labels — no JS needed unless you need programmatic positioning (then reach for Floating UI).