AtmosphereFree

Toggle Switch Sound

Pure CSS toggle switch with a spring-eased knob animation — cubic-bezier(0.34, 1.56, 0.64, 1) overshoot gives a physical feel with zero JavaScript.

Web AudioToggleUI
OFF
Hover or click the scene to interact

This effect is free — the Atmosphere category contains 57 effects total, including 10 free. Effect.Labs has 811 vanilla effects. Explore the category →

Usage examples

① Hero / Landing — Sound activation in a music or podcast app

WhenA user lands on a streaming or podcast player page: the 'Enable sound' toggle is the hero's primary action.
WhyThe spring knob draws the eye and communicates interactivity without decorative animation overhead — 100% CSS, zero impact on Time-to-Interactive.
SettingsON color: rgb(99,102,241) (indigo-500); knob transition 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) default. Toggle centred in the hero scene, OFF/ON label below.

② Product component — Settings panel row

WhenA 'Notifications' or 'Sound alerts' card in a SaaS dashboard or mobile app — each row exposes an independent toggle.
WhyThe understated style (semi-transparent track in OFF state) fits natively in a dark panel without overpowering other controls. The spring gives physical tactile feedback with no global animation.
SettingsON color matched to brand (.snd-toggle.on { background: rgb(16,185,129); } for green). Smaller size possible: track 48 × 26 px, knob 20 × 20 px, translateX(22px).

③ Settings screen — Dark mode, notifications and privacy

WhenA column of toggles in a mobile or web app's Settings screen — dark mode, push alerts, private mode: each row exposes an independent toggle.
WhyThis is the natural home of the toggle switch: a list of quiet controls where the spring knob (cubic-bezier 0.34, 1.56, 0.64, 1) gives satisfying physical feedback on each tap without overwhelming the screen.
SettingsToggles at standard 60 × 32 px size. ON color varies per row: rgb(139,92,246) (violet) for dark mode, rgb(20,184,166) (teal) for private mode. OFF-state semi-transparent track (rgba(255,255,255,0.1)) fades behind the label.

How it works

The component is built from two nested elements: the track (.snd-toggle, 60 × 32 px, border-radius 16 px) and the knob (.snd-toggle-knob, 26 × 26 px, absolutely positioned 3 px from each edge). Toggling state means adding or removing the .on class on the track — all else is CSS.

The knob animation uses transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1). This is an overshoot easing: the Y coordinate of the second control point (1.56) exceeds 1.0, causing the knob to slide slightly past its target (translateX(28px)) before settling back — that mechanical bounce is what makes this toggle feel physical rather than just sliding. The track background (rgba(255,255,255,0.1)rgb(99,102,241)) transitions independently with its own 0.3s.

The 28 px knob travel is derived from: track width − knob size − 2 × padding = 60 − 26 − 6 = 28. If you resize the component, recalculate this value or the knob will overshoot or fall short. The label (#sndToggleLabel) and click handling are not included in the provided code: the JS field holds an empty comment indicating a pure-CSS component — click wiring and label updates are the developer's responsibility.

For differentiated sounds (as the effect name implies), the recommended approach is the Web Audio API: create an AudioContext, generate two short OscillatorNodes (high frequency ~880 Hz for ON, low ~220 Hz for OFF) with a fast gain envelope (attack + release in ~40 ms). The IDs sndToggle and sndToggleLabel are the intended entry points for that wiring.

Accessibility

  • prefers-reduced-motion not handled: the CSS contains no @media (prefers-reduced-motion: reduce) block. Both transitions (background 0.3s, spring transform 0.3s) run unconditionally. Add @media (prefers-reduced-motion: reduce) { .snd-toggle, .snd-toggle-knob { transition: none; } } to honour OS preferences.
  • No ARIA role: .snd-toggle is a <div> with no role="switch", no aria-checked, and no tabindex. Screen readers do not identify it as an interactive switch. Add role="switch", tabindex="0", and toggle aria-checked="false" / "true" in your click handler.
  • Keyboard not wired: no keydown listener for Space or Enter in the provided code. Keyboard-only users cannot toggle the switch without additional JS.
  • Label contrast is conditional: var(--text-secondary) depends on the host page theme. WCAG AA (≥ 4.5:1) is not guaranteed by the code as-is — verify in your deployment context.
  • The track carries cursor: pointer, a correct signal for a clickable area; the 60 × 32 px hit area meets WCAG 2.5.5 minimum target size for touch.

Browser compatibility

Pure CSS component: transitions, transform, and cubic-bezier have been supported in all modern browsers since 2015. No JavaScript provided, no external dependencies.

Chrome 49+✓ Full
Firefox 44+✓ Full
Safari 10+✓ Full
Edge 79+✓ Full
Mobile iOS✓ Touch OK
Android Chrome✓ Full

Without CSS transition support (very old browsers), the knob jumps instantly to position and the background changes without animation — fully functional, no JS errors.

The code

Copy the three blocks into your page. No dependencies.

HTML
<div class="snd-toggle-container">
  <div class="snd-toggle" id="sndToggle">
    <div class="snd-toggle-knob">
    </div>
  </div>
  <div class="snd-toggle-label" id="sndToggleLabel">OFF</div>
</div>
CSS
.snd-toggle-container  {
   display: flex;
   flex-direction: column;
   align-items: center;
   gap: 16px;
   }

.snd-toggle  {
   width: 60px;
   height: 32px;
   border-radius: 16px;
   background: rgba(255, 255, 255, 0.1);
   position: relative;
   cursor: pointer;
   transition: background 0.3s;
   }

.snd-toggle.on  {
   background: rgb(99, 102, 241);
   }

.snd-toggle-knob  {
   width: 26px;
   height: 26px;
   border-radius: 50%;
   background: rgb(255, 255, 255);
   position: absolute;
   top: 3px;
   left: 3px;
   transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
   }

.snd-toggle.on .snd-toggle-knob  {
   transform: translateX(28px);
   }

.snd-toggle-label  {
   font-size: 0.8rem;
   color: var(--text-secondary);
   }
JavaScript (fx-0530)
// Effet CSS pur — pas de JavaScript nécessaire

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
.snd-toggle.on { background } rgb(99,102,241) Indigo-500 track color in ON state — swap for your primary brand color.
.snd-toggle { background } rgba(255,255,255,0.1) Semi-transparent track in OFF state. Raise opacity (e.g. 0.25) if contrast is insufficient on a dark background.
.snd-toggle { width / height } 60px / 32px Track dimensions. Keep ~2:1 ratio; update border-radius (= height/2) and translateX accordingly.
.snd-toggle-knob { width / height } 26px / 26px Circular knob size. Must remain ≤ height − 6px to stay within the 3 px margin on each side.
.snd-toggle.on .snd-toggle-knob { transform } translateX(28px) Knob travel in ON state = width − knob − 2 × 3px. Recalculate if you change the dimensions.
.snd-toggle-knob { transition: … cubic-bezier } cubic-bezier(0.34, 1.56, 0.64, 1) Spring easing with overshoot (1.56 > 1.0). Lower the third parameter toward 1.0 for a linear slide with no bounce.
.snd-toggle-knob { transition-duration } 0.3s Knob animation duration. 0.15s = fast and snappy, 0.5s = slow and deliberate (update the track transition too).

FAQ

Why does the code contain no JavaScript if the effect is called 'Toggle Switch Sound'?

The provided code is the CSS foundation: track, knob, and spring animation. Click handling, label updates, and sounds (Web Audio API) are left to the developer to fit any framework. Copy the CSS, add document.getElementById('sndToggle').addEventListener('click', fn), toggle the .on class in fn, and fire your oscillators.

How do I add differentiated sounds for ON and OFF?

Use the Web Audio API (zero dependencies): create an AudioContext, in the click handler spawn an OscillatorNode at 880 Hz (ON) or 220 Hz (OFF), pipe it through a GainNode with a short envelope (gain 0 → 0.3 in 5 ms, → 0 in 40 ms), then call osc.start() / osc.stop(ctx.currentTime + 0.06). Around 15 lines of JS, fully compatible with autoplay policies since it fires on a user gesture.

How do I make this toggle accessible to screen readers and keyboard users?

Add to the .snd-toggle div: role="switch", tabindex="0", aria-label="Enable sound", and aria-checked="false". In your handler, toggle aria-checked between "true" and "false" alongside the .on class. For keyboard, listen for keydown on Space and Enter to trigger the same handler as the click.