Split Button
Button with an attached dropdown toggle for secondary actions. The main button performs the primary action, while the arrow toggle reveals a dropdown menu with alternatives.
Default Split Button
Preview
<div class="split-button">
<button class="btn color-primary split-button-main">Save</button>
<button class="split-button-toggle color-primary" aria-label="More options">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg>
</button>
</div> Requires: ux.min.css
<div class="inline-flex relative align-middle">
<button class="btn color-primary rounded-r-none border-r-0">Save</button>
<button class="flex items-center justify-center w-10 p-0 border-none cursor-pointer bg-primary text-primary-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11); position: relative;" aria-label="More options">
<span style="position: absolute; left: 0; top: 25%; height: 50%; width: 1px; background-color: rgba(255,255,255,0.25);"></span>
<svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div> Requires: tw.min.css
// Toggle dropdown:
const toggle = document.querySelector('.split-button-toggle');
const container = toggle.closest('.split-button');
toggle.addEventListener('click', () => {
container.classList.toggle('split-button-open');
});
// Close on click outside:
document.addEventListener('click', (e) => {
document.querySelectorAll('.split-button-open').forEach(sb => {
if (!sb.contains(e.target)) sb.classList.remove('split-button-open');
});
}); With Dropdown Open
Preview
<div class="split-button split-button-open">
<button class="btn color-primary split-button-main">Save</button>
<button class="split-button-toggle color-primary" aria-label="More options" aria-expanded="true">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
</svg>
</button>
<div class="split-button-dropdown">
<button class="split-button-item">Save as Draft</button>
<button class="split-button-item">Save and Continue</button>
<div class="split-button-divider"></div>
<button class="split-button-item split-button-item-danger">Discard Changes</button>
</div>
</div> Requires: ux.min.css
<div class="inline-flex relative align-middle">
<button class="btn color-primary rounded-r-none border-r-0">Save</button>
<button class="flex items-center justify-center w-10 p-0 border-none cursor-pointer bg-primary text-primary-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11); position: relative;" aria-label="More options" aria-expanded="true">
<span style="position: absolute; left: 0; top: 25%; height: 50%; width: 1px; background-color: rgba(255,255,255,0.25);"></span>
<svg class="size-4" style="transform: rotate(180deg);" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
<div class="absolute right-0 min-w-40 py-1 bg-base-100 border border-base-300 rounded-box shadow-lg z-100" style="top: calc(100% + 4px);">
<button class="flex items-center gap-2 w-full px-4 py-2 bg-transparent border-none cursor-pointer text-left hover:bg-base-200" style="font-size: 0.9375rem; color: var(--color-base-content);">Save as Draft</button>
<button class="flex items-center gap-2 w-full px-4 py-2 bg-transparent border-none cursor-pointer text-left hover:bg-base-200" style="font-size: 0.9375rem; color: var(--color-base-content);">Save and Continue</button>
<div class="h-px my-1 bg-base-300"></div>
<button class="flex items-center gap-2 w-full px-4 py-2 bg-transparent border-none cursor-pointer text-left text-error hover:bg-error/10" style="font-size: 0.9375rem;">Discard Changes</button>
</div>
</div> Requires: tw.min.css
// Toggle dropdown:
const toggle = document.querySelector('.split-button-toggle');
const container = toggle.closest('.split-button');
toggle.addEventListener('click', () => {
container.classList.toggle('split-button-open');
}); Outline & Sizes
Preview
<div class="flex items-start gap-4 flex-wrap">
<!-- Outline -->
<div class="split-button split-button-outline">
<button class="btn btn-outline color-primary split-button-main">Outline</button>
<button class="split-button-toggle" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<!-- Small -->
<div class="split-button split-button-sm">
<button class="btn color-primary split-button-main">Small</button>
<button class="split-button-toggle color-primary" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<!-- Large -->
<div class="split-button split-button-lg">
<button class="btn color-primary split-button-main">Large</button>
<button class="split-button-toggle color-primary" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<!-- Full width -->
<div class="split-button split-button-block">
<button class="btn color-primary split-button-main">Full Width</button>
<button class="split-button-toggle color-primary" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
</div> Requires: ux.min.css
<div class="flex items-start gap-4 flex-wrap">
<!-- Outline -->
<div class="inline-flex relative align-middle">
<button class="btn btn-outline color-primary rounded-r-none border-r-0">Outline</button>
<button class="flex items-center justify-center w-10 p-0 bg-transparent cursor-pointer text-primary" style="border: 2px solid var(--color-primary); border-left: none; border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11);" aria-label="More">
<svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<!-- Small -->
<div class="inline-flex relative align-middle">
<button class="btn btn-sm color-primary rounded-r-none border-r-0">Small</button>
<button class="flex items-center justify-center w-8 p-0 border-none cursor-pointer bg-primary text-primary-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 9);" aria-label="More">
<svg class="size-3.5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<!-- Large -->
<div class="inline-flex relative align-middle">
<button class="btn btn-lg color-primary rounded-r-none border-r-0">Large</button>
<button class="flex items-center justify-center w-12 p-0 border-none cursor-pointer bg-primary text-primary-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 13);" aria-label="More">
<svg class="size-5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<!-- Full width -->
<div class="flex w-full relative align-middle">
<button class="btn color-primary rounded-r-none border-r-0 flex-1">Full Width</button>
<button class="flex items-center justify-center w-10 p-0 border-none cursor-pointer bg-primary text-primary-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11);" aria-label="More">
<svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
</div> Requires: tw.min.css
// No JavaScript required for styling — toggle open state with JS as shown above Colors
Preview
<div class="flex items-center gap-4 flex-wrap">
<div class="split-button">
<button class="btn color-primary split-button-main">Primary</button>
<button class="split-button-toggle color-primary" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<div class="split-button">
<button class="btn color-success split-button-main">Success</button>
<button class="split-button-toggle color-success" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<div class="split-button">
<button class="btn color-error split-button-main">Danger</button>
<button class="split-button-toggle color-error" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
<div class="split-button split-button-disabled">
<button class="btn color-primary split-button-main">Disabled</button>
<button class="split-button-toggle color-primary" aria-label="More">
<svg class="split-button-toggle-icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg>
</button>
</div>
</div> Requires: ux.min.css
<div class="flex items-center gap-4 flex-wrap">
<div class="inline-flex relative align-middle">
<button class="btn color-primary rounded-r-none border-r-0">Primary</button>
<button class="flex items-center justify-center w-10 p-0 border-none cursor-pointer bg-primary text-primary-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11);" aria-label="More"><svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg></button>
</div>
<div class="inline-flex relative align-middle">
<button class="btn color-success rounded-r-none border-r-0">Success</button>
<button class="flex items-center justify-center w-10 p-0 border-none cursor-pointer bg-success text-success-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11);" aria-label="More"><svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg></button>
</div>
<div class="inline-flex relative align-middle">
<button class="btn color-error rounded-r-none border-r-0">Danger</button>
<button class="flex items-center justify-center w-10 p-0 border-none cursor-pointer bg-error text-error-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11);" aria-label="More"><svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg></button>
</div>
<div class="inline-flex relative align-middle opacity-50 pointer-events-none">
<button class="btn color-primary rounded-r-none border-r-0">Disabled</button>
<button class="flex items-center justify-center w-10 p-0 border-none cursor-pointer bg-primary text-primary-content" style="border-radius: 0 var(--radius-field) var(--radius-field) 0; min-height: calc(var(--size-field) * 11);" aria-label="More"><svg class="size-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" /></svg></button>
</div>
</div> Requires: tw.min.css
// No JavaScript required for color styling Classes Reference
| Class | Description |
|---|---|
| .split-button | Container wrapper |
| .split-button-main | Main action button (add to .btn) |
| .split-button-toggle | Dropdown toggle arrow button |
| .split-button-toggle-icon | Chevron icon (rotates when open) |
| .split-button-open | Open state (shows dropdown) |
| .split-button-dropdown | Dropdown menu panel |
| .split-button-item | Dropdown item |
| .split-button-item-icon | Item leading icon |
| .split-button-item-danger | Red destructive item |
| .split-button-item-disabled | Disabled item |
| .split-button-divider | Horizontal separator |
| .split-button-outline | Outline style variant |
| .split-button-sm | Small size |
| .split-button-lg | Large size |
| .split-button-block | Full-width variant |
| .split-button-disabled | Disabled state |
| .split-button-dropdown-left | Align dropdown to left |
| .split-button-dropdown-up | Open dropdown upward |