Switch
An iOS-style switch control for toggling between on and off states.
Default
Basic on and off switch states.
html
Off
On
<div class="vt-text-center">
<button role="switch" aria-checked="false" class="vt-switch vt-bg-surface-moderate" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Off</p>
</div>
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-brand-fill" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">On</p>
</div>
Sizes
Small, default, and large switch sizes.
html
Small
Default
Large
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-switch-sm vt-active vt-bg-brand-fill" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Small</p>
</div>
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-brand-fill" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Default</p>
</div>
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-switch-lg vt-active vt-bg-brand-fill" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Large</p>
</div>
With Label
Switch paired with a text label.
html
Airplane Mode
Wi-Fi
Bluetooth
<div class="vt-w-64 vt-space-y-4">
<div class="vt-flex vt-items-center vt-justify-between">
<span class="vt-text-sm vt-font-medium">Airplane Mode</span>
<button role="switch" aria-checked="false" class="vt-switch vt-bg-surface-moderate" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
</div>
<div class="vt-flex vt-items-center vt-justify-between">
<span class="vt-text-sm vt-font-medium">Wi-Fi</span>
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-brand-fill" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
</div>
<div class="vt-flex vt-items-center vt-justify-between">
<span class="vt-text-sm vt-font-medium">Bluetooth</span>
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-brand-fill" onclick="this.classList.toggle('vt-active'); this.classList.toggle('vt-bg-surface-moderate'); this.classList.toggle('vt-bg-brand-fill'); this.setAttribute('aria-checked', this.classList.contains('vt-active'))">
<span class="vt-switch-thumb"></span>
</button>
</div>
</div>
Disabled
Switches in disabled state cannot be interacted with.
html
Off (disabled)
On (disabled)
<div class="vt-text-center">
<button role="switch" aria-checked="false" disabled="" class="vt-switch vt-bg-surface-moderate vt-opacity-50 vt-cursor-not-allowed">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Off (disabled)</p>
</div>
<div class="vt-text-center">
<button role="switch" aria-checked="true" disabled="" class="vt-switch vt-active vt-bg-brand-fill vt-opacity-50 vt-cursor-not-allowed">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">On (disabled)</p>
</div>
Colors
Switch with different active track colors.
html
Primary
Success
Danger
Warning
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-brand-fill" onclick="this.classList.toggle('vt-active'); this.setAttribute('aria-checked', this.classList.contains('vt-active')); this.style.backgroundColor = this.classList.contains('vt-active') ? '' : 'hsl(var(--surface-moderate))'; if(this.classList.contains('vt-active')) this.style.backgroundColor = '';">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Primary</p>
</div>
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-success-fill" onclick="this.classList.toggle('vt-active'); this.setAttribute('aria-checked', this.classList.contains('vt-active')); this.style.backgroundColor = this.classList.contains('vt-active') ? 'hsl(var(--success-fill))' : 'hsl(var(--surface-moderate))';">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Success</p>
</div>
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-error-fill" onclick="this.classList.toggle('vt-active'); this.setAttribute('aria-checked', this.classList.contains('vt-active')); this.style.backgroundColor = this.classList.contains('vt-active') ? 'hsl(var(--error-fill))' : 'hsl(var(--surface-moderate))';">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Danger</p>
</div>
<div class="vt-text-center">
<button role="switch" aria-checked="true" class="vt-switch vt-active vt-bg-warning-fill" onclick="this.classList.toggle('vt-active'); this.setAttribute('aria-checked', this.classList.contains('vt-active')); this.style.backgroundColor = this.classList.contains('vt-active') ? 'hsl(var(--warning-fill))' : 'hsl(var(--surface-moderate))';">
<span class="vt-switch-thumb"></span>
</button>
<p class="vt-text-xs vt-text-foreground-muted vt-mt-2">Warning</p>
</div>
In Card
Switch rows inside a card container, similar to iOS Settings.
Guidelines
Instant on/off setting that applies immediately (no submit). If applied on save → checkbox.
Wi-Fi
Do
Don't
API Reference
All CSS classes available for the Switch component.
| Class | Type | Description |
|---|---|---|
vt-switch |
Base | Base switch track styles -- rounded pill shape, transition |
vt-switch-thumb |
Base | Sliding thumb knob inside the switch track |
vt-active |
State | Active/on state -- translates thumb to the right |
vt-switch-sm |
Size | Small switch variant |
vt-switch-lg |
Size | Large switch variant |
vt-bg-surface-moderate |
Color | Off-state track background |
vt-bg-brand-fill |
Color | Primary on-state track color (brand) |
vt-bg-info-fill |
Color | Blue on-state track color |
vt-bg-success-fill |
Color | Success on-state track color |
vt-bg-error-fill |
Color | Danger on-state track color |
vt-bg-warning-fill |
Color | Warning on-state track color |
vt-opacity-50 vt-cursor-not-allowed |
State | Disabled switch appearance |
Accessibility
Keyboard and screen reader support.
| Feature | Details |
|---|---|
| Role | Use input[type="checkbox"] with role="switch" for toggle semantics |
| Label | Always provide a visible label linked via for/id |
| Keyboard | Space toggles the switch, Tab moves focus |
| State | aria-checked="true/false" announces the toggle state |