Segmented Control
A copy-paste navigation component in pure HTML & CSS. Zero dependencies, framework-agnostic, MIT-licensed.
NavigationHTMLCSSany framework
Copy into your project
HTML
<div class="nuda-navx-seg" role="group" aria-label="View mode">
<div class="nuda-navx-seg__track">
<div class="nuda-navx-seg__thumb"></div>
<button class="nuda-navx-seg__btn nuda-navx-seg__btn--active" aria-pressed="true">
<svg class="nuda-navx-seg__icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="6" height="6" rx="1" fill="currentColor"/>
<rect x="9" y="1" width="6" height="6" rx="1" fill="currentColor"/>
<rect x="1" y="9" width="6" height="6" rx="1" fill="currentColor"/>
<rect x="9" y="9" width="6" height="6" rx="1" fill="currentColor"/>
</svg>
Grid
</button>
<button class="nuda-navx-seg__btn" aria-pressed="false">
<svg class="nuda-navx-seg__icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="2" width="14" height="2" rx="1" fill="currentColor"/>
<rect x="1" y="7" width="14" height="2" rx="1" fill="currentColor"/>
<rect x="1" y="12" width="14" height="2" rx="1" fill="currentColor"/>
</svg>
List
</button>
<button class="nuda-navx-seg__btn" aria-pressed="false">
<svg class="nuda-navx-seg__icon" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="1" y="1" width="14" height="9" rx="1.5" fill="currentColor"/>
<rect x="1" y="12" width="6" height="3" rx="1" fill="currentColor"/>
<rect x="9" y="12" width="6" height="3" rx="1" fill="currentColor"/>
</svg>
Card
</button>
</div>
</div>CSS
.nuda-navx-seg {
display: inline-flex;
}
.nuda-navx-seg__track {
display: flex;
align-items: center;
position: relative;
background: #141414;
border: 1px solid rgba(255,255,255,.1);
border-radius: 10px;
padding: 3px;
gap: 2px;
}
.nuda-navx-seg__thumb {
position: absolute;
top: 3px;
left: 3px;
width: calc(33.33% - 3px);
height: calc(100% - 6px);
background: #e4ff54;
border-radius: 7px;
transition: transform .22s cubic-bezier(.4,0,.2,1);
pointer-events: none;
z-index: 0;
}
.nuda-navx-seg__btn {
position: relative;
z-index: 1;
display: flex;
align-items: center;
gap: 5px;
background: none;
border: none;
color: #777;
font-size: .75rem;
font-weight: 500;
padding: .4rem .75rem;
border-radius: 7px;
cursor: pointer;
transition: color .2s;
white-space: nowrap;
}
.nuda-navx-seg__btn--active {
color: #0a0a0a;
font-weight: 700;
}
.nuda-navx-seg__btn:not(.nuda-navx-seg__btn--active):hover {
color: #cfcfcf;
}
.nuda-navx-seg__icon {
width: 14px;
height: 14px;
flex-shrink: 0;
}
.nuda-navx-seg__btn:nth-child(3) ~ .nuda-navx-seg__thumb,.nuda-navx-seg__btn:nth-child(3).nuda-navx-seg__btn--active~* {
transform: translateX(100%);
}
.nuda-navx-seg__btn:nth-child(4).nuda-navx-seg__btn--active~* {
transform: translateX(200%);
}
@media (prefers-reduced-motion:reduce) {
.nuda-navx-seg__thumb,.nuda-navx-seg__btn {
transition: none;
}
}
How to use Segmented Control
Paste the HTML where you need it and the CSS into a global stylesheet (or a <style> tag). Every class is prefixed nuda- so it never collides with Tailwind or your own styles. Tweak the CSS custom properties to match your design system.
Works in React, Vue, Svelte, Astro, Next.js, Nuxt, Laravel Blade, Django, Rails — or a single .html file. No npm install, no build step.