05 / 47
All 47 in 47 CSS Toggles & Switches
- 01Minimal iOS-Style Toggle Switch
- 02Dark Mode Sun / Moon Theme Switcher
- 033D Neumorphic Pill Toggle
- 04Gooey Liquid Morphing Switch
- 05Bouncy Elastic Physics Toggle
- 06Inner Text ON / OFF Switch
- 07SaaS Pricing Segmented Pill Toggle
- 08Haptic Mechanical Keycap Toggles
- 09Waveform Mute Toggle
- 10Timed Auto-Off Toggle
- 11Biometric Hold-to-Confirm Scan Toggle
- 12Split-Flap Departure Board Toggle
- 13Permission Stack with Live Status
- 14Material Design 3 Switch
- 15Skeuomorphic Wall Light Switch
- 16Neon Cyberpunk Toggle
- 17Brutalist Snap Toggle
- 18Day / Night Landscape Scene Switch
- 193D Flip Card Toggle
- 20Sliding Pill with Traveling Label
- 21Glassmorphism Frosted Toggle
- 22Skeuomorphic Rotary Knob Toggle
- 23iOS Light Mode Settings List
- 24Outline Minimal currentColor Toggle
- 25Bouncy Pebble Organic Toggle
- 26Industrial Rocker I/O Switch
- 27Accessible ARIA role=switch Toggle
- 28Haptic Keys
- 29Waveform Toggle
- 30Timed Toggle
- 31Biometric Scan
- 32Split-Flap Board
- 33Permission Stack
- 34iOS
- 35Material Design
- 36Skeuomorphic Light Switch
- 37Neon Cyber
- 38Brutalist
- 39Day / Night
- 40Flip Card
- 41Sliding Pill with Label
- 42Glassmorphism
- 43Skeuomorphic Knob
- 44iOS Light Mode
- 45Outline
- 46Bouncy Pebble
- 47Industrial Rocker
Bouncy Elastic Physics Toggle
Premium landing-page motion in one line of CSS: an overshooting cubic-bezier makes the thumb wind up backwards, shoot across the track, and bounce gently off the far wall — playful, physics-driven, and still just a checkbox with a transition.
Build interactive UI like this from scratch: 20 HTML, CSS & JavaScript projects
ZTM · JavaScript Web Projects · 30‑day money-back guarantee · Affiliate link
The code
<section class="tgl-05" aria-label="Bouncy elastic physics toggle">
<label class="tgl-05__row" for="tgl-05-sw">
<span class="tgl-05__lbl">Confetti on publish</span>
<input type="checkbox" id="tgl-05-sw" class="tgl-05__sw" role="switch">
</label>
<p class="tgl-05__cap">cubic-bezier(0.4, −0.3, 0.6, 1.3)</p>
</section><section class="tgl-05" aria-label="Bouncy elastic physics toggle">
<label class="tgl-05__row" for="tgl-05-sw">
<span class="tgl-05__lbl">Confetti on publish</span>
<input type="checkbox" id="tgl-05-sw" class="tgl-05__sw" role="switch">
</label>
<p class="tgl-05__cap">cubic-bezier(0.4, −0.3, 0.6, 1.3)</p>
</section>.tgl-05,
.tgl-05 *,
.tgl-05 *::before,
.tgl-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.tgl-05 {
--on: oklch(0.7 0.17 150);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
padding: 60px 20px;
background: #fdf8ef;
}
.tgl-05__row {
display: flex;
align-items: center;
gap: 34px;
cursor: pointer;
background: #fff;
border: 1px solid #eee3cf;
border-radius: 18px;
padding: 20px 26px;
box-shadow: 0 10px 26px -18px rgba(120,90,20,.35);
}
.tgl-05__lbl {
font-size: 16px;
font-weight: 600;
color: #4a4132;
}
.tgl-05__sw {
appearance: none;
-webkit-appearance: none;
flex: none;
width: 76px;
height: 40px;
border-radius: 22px;
background: #e8e0d0;
position: relative;
cursor: pointer;
transition: background-color .45s ease;
}
.tgl-05__sw:checked {
background: var(--on);
}
.tgl-05__sw::before {
content: "";
position: absolute;
top: 4px;
left: 4px;
width: 32px;
height: 32px;
border-radius: 50%;
background: #fff;
box-shadow: 0 3px 7px rgba(80,60,20,.3);
transition: transform .55s cubic-bezier(0.4,-0.3,0.6,1.3);
}
.tgl-05__sw:checked::before {
transform: translateX(36px);
}
.tgl-05__sw:active::before {
transform: scale(.92);
}
.tgl-05__sw:checked:active::before {
transform: translateX(36px) scale(.92);
}
.tgl-05__sw:focus-visible {
outline: 3px solid var(--on);
outline-offset: 4px;
}
.tgl-05__cap {
font-family: ui-monospace,Menlo,monospace;
font-size: 12px;
color: #b0a58d;
}
@media (prefers-reduced-motion: reduce) {
.tgl-05__sw::before {
transition: transform .2s ease;
}
}.tgl-05,
.tgl-05 *,
.tgl-05 *::before,
.tgl-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.tgl-05 {
--on: oklch(0.7 0.17 150);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
padding: 60px 20px;
background: #fdf8ef;
}
.tgl-05__row {
display: flex;
align-items: center;
gap: 34px;
cursor: pointer;
background: #fff;
border: 1px solid #eee3cf;
border-radius: 18px;
padding: 20px 26px;
box-shadow: 0 10px 26px -18px rgba(120,90,20,.35);
}
.tgl-05__lbl {
font-size: 16px;
font-weight: 600;
color: #4a4132;
}
.tgl-05__sw {
appearance: none;
-webkit-appearance: none;
flex: none;
width: 76px;
height: 40px;
border-radius: 22px;
background: #e8e0d0;
position: relative;
cursor: pointer;
transition: background-color .45s ease;
}
.tgl-05__sw:checked {
background: var(--on);
}
.tgl-05__sw::before {
content: "";
position: absolute;
top: 4px;
left: 4px;
width: 32px;
height: 32px;
border-radius: 50%;
background: #fff;
box-shadow: 0 3px 7px rgba(80,60,20,.3);
transition: transform .55s cubic-bezier(0.4,-0.3,0.6,1.3);
}
.tgl-05__sw:checked::before {
transform: translateX(36px);
}
.tgl-05__sw:active::before {
transform: scale(.92);
}
.tgl-05__sw:checked:active::before {
transform: translateX(36px) scale(.92);
}
.tgl-05__sw:focus-visible {
outline: 3px solid var(--on);
outline-offset: 4px;
}
.tgl-05__cap {
font-family: ui-monospace,Menlo,monospace;
font-size: 12px;
color: #b0a58d;
}
@media (prefers-reduced-motion: reduce) {
.tgl-05__sw::before {
transition: transform .2s ease;
}
}/* No JavaScript — a single overshooting cubic-bezier on the thumb's transform creates the wind-up, launch and wall-bounce. */
/* No JavaScript — a single overshooting cubic-bezier on the thumb's transform creates the wind-up, launch and wall-bounce. */Here's a working CSS Toggles & Switche from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Bouncy Elastic Physics Toggle
Source: https://codefronts.com/components/css-toggles-switches/bouncy-elastic-physics-toggle/
Premium landing-page motion in one line of CSS: an overshooting cubic-bezier makes the thumb wind up backwards, shoot across the track, and bounce gently off the far wall — playful, physics-driven, and still just a checkbox with a transition.
## HTML
```html
<section class="tgl-05" aria-label="Bouncy elastic physics toggle">
<label class="tgl-05__row" for="tgl-05-sw">
<span class="tgl-05__lbl">Confetti on publish</span>
<input type="checkbox" id="tgl-05-sw" class="tgl-05__sw" role="switch">
</label>
<p class="tgl-05__cap">cubic-bezier(0.4, −0.3, 0.6, 1.3)</p>
</section>
```
## CSS
```css
.tgl-05,
.tgl-05 *,
.tgl-05 *::before,
.tgl-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.tgl-05 {
--on: oklch(0.7 0.17 150);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
padding: 60px 20px;
background: #fdf8ef;
}
.tgl-05__row {
display: flex;
align-items: center;
gap: 34px;
cursor: pointer;
background: #fff;
border: 1px solid #eee3cf;
border-radius: 18px;
padding: 20px 26px;
box-shadow: 0 10px 26px -18px rgba(120,90,20,.35);
}
.tgl-05__lbl {
font-size: 16px;
font-weight: 600;
color: #4a4132;
}
.tgl-05__sw {
appearance: none;
-webkit-appearance: none;
flex: none;
width: 76px;
height: 40px;
border-radius: 22px;
background: #e8e0d0;
position: relative;
cursor: pointer;
transition: background-color .45s ease;
}
.tgl-05__sw:checked {
background: var(--on);
}
.tgl-05__sw::before {
content: "";
position: absolute;
top: 4px;
left: 4px;
width: 32px;
height: 32px;
border-radius: 50%;
background: #fff;
box-shadow: 0 3px 7px rgba(80,60,20,.3);
transition: transform .55s cubic-bezier(0.4,-0.3,0.6,1.3);
}
.tgl-05__sw:checked::before {
transform: translateX(36px);
}
.tgl-05__sw:active::before {
transform: scale(.92);
}
.tgl-05__sw:checked:active::before {
transform: translateX(36px) scale(.92);
}
.tgl-05__sw:focus-visible {
outline: 3px solid var(--on);
outline-offset: 4px;
}
.tgl-05__cap {
font-family: ui-monospace,Menlo,monospace;
font-size: 12px;
color: #b0a58d;
}
@media (prefers-reduced-motion: reduce) {
.tgl-05__sw::before {
transition: transform .2s ease;
}
}
```
## JavaScript
```js
/* No JavaScript — a single overshooting cubic-bezier on the thumb's transform creates the wind-up, launch and wall-bounce. */
```Here's a working CSS Toggles & Switche from CodeFronts. Use it as-is or adapt to your framework. All classes are scoped under a unique prefix so the code won't collide with your existing styles. MIT licensed.
Demo: Bouncy Elastic Physics Toggle
Source: https://codefronts.com/components/css-toggles-switches/bouncy-elastic-physics-toggle/
Premium landing-page motion in one line of CSS: an overshooting cubic-bezier makes the thumb wind up backwards, shoot across the track, and bounce gently off the far wall — playful, physics-driven, and still just a checkbox with a transition.
## HTML
```html
<section class="tgl-05" aria-label="Bouncy elastic physics toggle">
<label class="tgl-05__row" for="tgl-05-sw">
<span class="tgl-05__lbl">Confetti on publish</span>
<input type="checkbox" id="tgl-05-sw" class="tgl-05__sw" role="switch">
</label>
<p class="tgl-05__cap">cubic-bezier(0.4, −0.3, 0.6, 1.3)</p>
</section>
```
## CSS
```css
.tgl-05,
.tgl-05 *,
.tgl-05 *::before,
.tgl-05 *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.tgl-05 {
--on: oklch(0.7 0.17 150);
font-family: 'Segoe UI',system-ui,sans-serif;
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 24px;
padding: 60px 20px;
background: #fdf8ef;
}
.tgl-05__row {
display: flex;
align-items: center;
gap: 34px;
cursor: pointer;
background: #fff;
border: 1px solid #eee3cf;
border-radius: 18px;
padding: 20px 26px;
box-shadow: 0 10px 26px -18px rgba(120,90,20,.35);
}
.tgl-05__lbl {
font-size: 16px;
font-weight: 600;
color: #4a4132;
}
.tgl-05__sw {
appearance: none;
-webkit-appearance: none;
flex: none;
width: 76px;
height: 40px;
border-radius: 22px;
background: #e8e0d0;
position: relative;
cursor: pointer;
transition: background-color .45s ease;
}
.tgl-05__sw:checked {
background: var(--on);
}
.tgl-05__sw::before {
content: "";
position: absolute;
top: 4px;
left: 4px;
width: 32px;
height: 32px;
border-radius: 50%;
background: #fff;
box-shadow: 0 3px 7px rgba(80,60,20,.3);
transition: transform .55s cubic-bezier(0.4,-0.3,0.6,1.3);
}
.tgl-05__sw:checked::before {
transform: translateX(36px);
}
.tgl-05__sw:active::before {
transform: scale(.92);
}
.tgl-05__sw:checked:active::before {
transform: translateX(36px) scale(.92);
}
.tgl-05__sw:focus-visible {
outline: 3px solid var(--on);
outline-offset: 4px;
}
.tgl-05__cap {
font-family: ui-monospace,Menlo,monospace;
font-size: 12px;
color: #b0a58d;
}
@media (prefers-reduced-motion: reduce) {
.tgl-05__sw::before {
transition: transform .2s ease;
}
}
```
## JavaScript
```js
/* No JavaScript — a single overshooting cubic-bezier on the thumb's transform creates the wind-up, launch and wall-bounce. */
```How this works
The entire effect is the timing function cubic-bezier(0.4, -0.3, 0.6, 1.3) applied to the thumb's transform. The negative first y-value pulls progress below 0 — the anticipation wind-up — and the 1.3 end overshoots the target before settling, reading as an elastic bounce against the track wall.
Because the tween is a single compositor-driven transform transition, it costs nothing on the main thread: no keyframes, no spring library, perfect INP. The track color fades on a plain ease so the color change doesn't wobble with the thumb.
Make it yours
- More drama: push the bezier to
(0.4, -0.6, 0.5, 1.6)— anticipation and bounce both grow. - Stiffer spring: shorten the duration to .35s.
- Apply the same bezier to the :active squash for a squishier press.
- Tune travel distance by resizing the track (thumb travel = width − thumb − 2×inset).
Gotchas — read before shipping
- Overshoot beziers need travel headroom — the thumb overshoots ~15% past its target, so keep the track inset ≥ 4px or it visually clips.
- Don't reuse the bouncy bezier on the background-color fade; overshooting a color looks like flicker.
- One transition, one property: chaining bounces with keyframes here would fight the reverse (uncheck) direction.
Browser support
| Chrome | Safari | Firefox | Edge |
|---|---|---|---|
| 111+ | 15.4+ | 113+ | 111+ |
Floor set by oklch() as this demo is written. The core technique itself goes back further — Chrome 16+.
Custom cubic-bezier() timing with y-values outside [0,1] is supported everywhere; this is among the most portable demos in the collection.