Segment
iOS-style segmented control with sliding indicator, squish animation, and multiple variants.
Basic Segment
Preview
<div class="segment">
<div class="segment-indicator" style="left: 3px; width: calc(33.33% - 2px);"></div>
<button class="segment-btn segment-btn-selected">Day</button>
<button class="segment-btn">Week</button>
<button class="segment-btn">Month</button>
</div> Requires: ux.min.css
<div class="inline-flex items-stretch relative rounded-field p-0.75" style="background-color: color-mix(in oklch, var(--color-base-content) 8%, transparent)">
<div class="absolute top-0.75 bottom-0.75 bg-base-100 rounded-[calc(var(--radius-field)-3px)] shadow-sm transition-all duration-300" style="left: 3px; width: calc(33.33% - 2px);"></div>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content z-1 cursor-pointer">Day</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content/60 z-1 cursor-pointer">Week</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content/60 z-1 cursor-pointer">Month</button>
</div> Requires: tw.min.css
// Move the indicator by updating its left & width via JS
// Example:
// const indicator = segment.querySelector('.segment-indicator');
// const btn = segment.querySelectorAll('.segment-btn')[index];
// indicator.style.left = btn.offsetLeft + 'px';
// indicator.style.width = btn.offsetWidth + 'px';
// Toggle segment-btn-selected class on buttons Variants
Preview
<!-- Primary (colored indicator) -->
<div class="segment segment-primary mb-4">
<div class="segment-indicator" style="left: 3px; width: calc(50% - 2px);"></div>
<button class="segment-btn segment-btn-selected">Active</button>
<button class="segment-btn">Inactive</button>
</div>
<!-- Outline -->
<div class="segment segment-outline mb-4">
<button class="segment-btn segment-btn-selected">List</button>
<button class="segment-btn">Grid</button>
<button class="segment-btn">Map</button>
</div>
<!-- Rounded Pill -->
<div class="segment segment-rounded">
<div class="segment-indicator" style="left: 3px; width: calc(50% - 2px);"></div>
<button class="segment-btn segment-btn-selected">On</button>
<button class="segment-btn">Off</button>
</div> Requires: ux.min.css
<!-- Primary (colored indicator) -->
<div class="inline-flex items-stretch relative rounded-field p-0.75 mb-4" style="background-color: color-mix(in oklch, var(--color-primary) 15%, transparent);">
<div class="absolute top-0.75 bottom-0.75 bg-primary rounded-[calc(var(--radius-field)-3px)] shadow-sm transition-all duration-300" style="left: 3px; width: calc(50% - 2px);"></div>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-primary-content z-1 cursor-pointer">Active</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content/60 z-1 cursor-pointer">Inactive</button>
</div>
<!-- Outline -->
<div class="inline-flex items-stretch relative rounded-field border border-base-300 mb-4">
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-primary border-none text-sm font-medium text-primary-content z-1 cursor-pointer rounded-l-[calc(var(--radius-field)-1px)]">List</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-r border-base-300 text-sm font-medium text-base-content/60 z-1 cursor-pointer">Grid</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content/60 z-1 cursor-pointer rounded-r-[calc(var(--radius-field)-1px)]">Map</button>
</div>
<!-- Rounded Pill -->
<div class="inline-flex items-stretch relative rounded-full p-0.75" style="background-color: color-mix(in oklch, var(--color-base-content) 8%, transparent);">
<div class="absolute top-0.75 bottom-0.75 bg-base-100 rounded-full shadow-sm transition-all duration-300" style="left: 3px; width: calc(50% - 2px);"></div>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content z-1 cursor-pointer rounded-full">On</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content/60 z-1 cursor-pointer rounded-full">Off</button>
</div> Requires: tw.min.css
// Same JS pattern for all variants
// Toggle segment-btn-selected and move indicator Sizes
Preview
<!-- Small -->
<div class="segment segment-sm mb-4">
<div class="segment-indicator" style="left: 2px; width: calc(33.33% - 1px);"></div>
<button class="segment-btn segment-btn-selected">S</button>
<button class="segment-btn">M</button>
<button class="segment-btn">L</button>
</div>
<!-- Default -->
<div class="segment mb-4">
<div class="segment-indicator" style="left: 3px; width: calc(33.33% - 2px);"></div>
<button class="segment-btn segment-btn-selected">Small</button>
<button class="segment-btn">Medium</button>
<button class="segment-btn">Large</button>
</div>
<!-- Large -->
<div class="segment segment-lg">
<div class="segment-indicator" style="left: 3px; width: calc(33.33% - 2px);"></div>
<button class="segment-btn segment-btn-selected">Day</button>
<button class="segment-btn">Week</button>
<button class="segment-btn">Month</button>
</div> Requires: ux.min.css
<!-- Small -->
<div class="inline-flex items-stretch relative rounded-field p-0.5 mb-4" style="background-color: color-mix(in oklch, var(--color-base-content) 8%, transparent);">
<div class="absolute top-0.5 bottom-0.5 bg-base-100 rounded-[calc(var(--radius-field)-2px)] shadow-sm transition-all duration-300" style="left: 2px; width: calc(33.33% - 1px);"></div>
<button class="relative flex items-center justify-center flex-1 px-2 py-1 bg-transparent border-none text-xs font-medium text-base-content z-1 cursor-pointer" style="min-height: 28px;">S</button>
<button class="relative flex items-center justify-center flex-1 px-2 py-1 bg-transparent border-none text-xs font-medium text-base-content/60 z-1 cursor-pointer" style="min-height: 28px;">M</button>
<button class="relative flex items-center justify-center flex-1 px-2 py-1 bg-transparent border-none text-xs font-medium text-base-content/60 z-1 cursor-pointer" style="min-height: 28px;">L</button>
</div>
<!-- Default -->
<div class="inline-flex items-stretch relative rounded-field p-0.75 mb-4" style="background-color: color-mix(in oklch, var(--color-base-content) 8%, transparent);">
<div class="absolute top-0.75 bottom-0.75 bg-base-100 rounded-[calc(var(--radius-field)-3px)] shadow-sm transition-all duration-300" style="left: 3px; width: calc(33.33% - 2px);"></div>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content z-1 cursor-pointer" style="min-height: 36px;">Small</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content/60 z-1 cursor-pointer" style="min-height: 36px;">Medium</button>
<button class="relative flex items-center justify-center flex-1 px-4 py-2 bg-transparent border-none text-sm font-medium text-base-content/60 z-1 cursor-pointer" style="min-height: 36px;">Large</button>
</div>
<!-- Large -->
<div class="inline-flex items-stretch relative rounded-field p-0.75" style="background-color: color-mix(in oklch, var(--color-base-content) 8%, transparent);">
<div class="absolute top-0.75 bottom-0.75 bg-base-100 rounded-[calc(var(--radius-field)-3px)] shadow-sm transition-all duration-300" style="left: 3px; width: calc(33.33% - 2px);"></div>
<button class="relative flex items-center justify-center flex-1 px-6 py-3 bg-transparent border-none text-base font-medium text-base-content z-1 cursor-pointer" style="min-height: 44px;">Day</button>
<button class="relative flex items-center justify-center flex-1 px-6 py-3 bg-transparent border-none text-base font-medium text-base-content/60 z-1 cursor-pointer" style="min-height: 44px;">Week</button>
<button class="relative flex items-center justify-center flex-1 px-6 py-3 bg-transparent border-none text-base font-medium text-base-content/60 z-1 cursor-pointer" style="min-height: 44px;">Month</button>
</div> Requires: tw.min.css
// No JavaScript required for sizing | Class | Description |
|---|---|
.segment | Container |
.segment-indicator | Sliding background indicator |
.segment-btn | Segment button |
.segment-btn-selected | Active button |
.segment-btn-disabled | Disabled button |
.segment-btn-icon | Icon inside button |
.segment-btn-label | Label text |
.segment-btn-icon-only | Icon-only button (no label) |
.segment-block | Full-width segment |
.segment-primary | Colored indicator variant |
.segment-outline | Bordered variant |
.segment-rounded | Pill-shaped variant |
.segment-success/error/warning | Color variants |
.segment-sm | Small size |
.segment-lg | Large size |
.segment-scrollable | Horizontally scrollable |
.segment.glass | Glass morphism variant |