Toggle Group
A copy-paste form states component in pure HTML, CSS & vanilla JS. Zero dependencies, framework-agnostic, MIT-licensed.
Form StatesHTMLCSSJavaScriptany framework
Copy into your project
HTML
<!-- Toggle Group — pill slides via translateX based on active index -->
<div class="nuda-toggleg" role="tablist">
<button class="nuda-toggleg__opt" type="button">Day</button>
<button class="nuda-toggleg__opt is-active" type="button">Week</button>
<button class="nuda-toggleg__opt" type="button">Month</button>
<span class="nuda-toggleg__pill"></span>
</div>CSS
/* Toggle Group
Segmented control: pill slides under the active option.
Customize: --toggle-accent, --toggle-text-active */
.nuda-toggleg {
--toggle-accent: #e4ff54;
--toggle-text-active: #09090b;
position: relative;
display: inline-flex;
background: rgba(255, 255, 255, 0.04);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: 10px;
padding: 4px;
}
.nuda-toggleg__opt {
position: relative;
z-index: 2;
padding: 7px 16px;
background: transparent;
border: none;
color: #a1a1aa;
font: 600 0.75rem ui-sans-serif, system-ui, sans-serif;
cursor: pointer;
border-radius: 6px;
transition: color 0.3s;
}
.nuda-toggleg__opt.is-active {
color: var(--toggle-text-active);
}
.nuda-toggleg__pill {
position: absolute;
z-index: 1;
top: 4px;
left: 4px;
width: calc(33.33% - 2.6px);
height: calc(100% - 8px);
background: var(--toggle-accent);
border-radius: 6px;
box-shadow: 0 0 8px rgba(228, 255, 84, 0.3);
transform: translateX(100%); /* second option active by default */
transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Move from JS by setting transform: translateX(0 / 100% / 200%) */JavaScript
/* Toggle Group — slides the pill to the clicked option. */
(function () {
var group = document.querySelector('.nuda-toggleg');
if (!group) return;
var opts = group.querySelectorAll('.nuda-toggleg__opt');
var pill = group.querySelector('.nuda-toggleg__pill');
opts.forEach(function (btn, i) {
btn.addEventListener('click', function () {
opts.forEach(function (o) { o.classList.remove('is-active'); });
btn.classList.add('is-active');
pill.style.transform = 'translateX(' + (i * 100) + '%)';
});
});
})();How to use Toggle Group
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.