Toggle Switch
A modern toggle switch with a smooth sliding animation, clear active state, and dark UI styling for settings and forms.
<label class="toggle-switch">
<input type="checkbox">
<span class="toggle-track">
<span class="toggle-thumb"></span>
</span>
<span class="toggle-text">
Enable dark mode
</span>
</label>
.toggle-switch{
position:relative;
display:inline-flex;
align-items:center;
gap:12px;
color:#c7d2e5;
font-size:15px;
cursor:pointer;
user-select:none;
}
.toggle-switch input{
position:absolute;
opacity:0;
pointer-events:none;
}
.toggle-track{
width:50px;
height:28px;
position:relative;
flex:0 0 50px;
border:1px solid #33445f;
border-radius:999px;
background:#0b1423;
transition:.25s ease;
}
.toggle-thumb{
position:absolute;
top:3px;
left:3px;
width:20px;
height:20px;
border-radius:50%;
background:#8190a5;
transition:.25s ease;
}
.toggle-switch input:checked + .toggle-track{
border-color:#22d3ee;
background:#0f3b46;
box-shadow:
0 0 16px rgba(34,211,238,.2);
}
.toggle-switch input:checked + .toggle-track .toggle-thumb{
transform:translateX(22px);
background:#22d3ee;
}
.toggle-switch:hover .toggle-track{
border-color:#22d3ee;
}
How This Toggle Switch Works
This Toggle Switch is a CSS-driven form control built around a native checkbox. The HTML uses a <label> as the outer .toggle-switch wrapper, so the visible switch and its “Enable dark mode” text belong to the same clickable control. Clicking anywhere within the label changes the checkbox state without requiring JavaScript.
Inside the label, the component contains a checkbox input, a .toggle-track element, a nested .toggle-thumb, and the text label. The native checkbox remains responsible for maintaining the checked or unchecked state, while CSS replaces its normal visual appearance with the custom track and circular thumb.
The checkbox is visually hidden using position: absolute and opacity: 0. It also has pointer-events: none, so users interact with the surrounding label rather than directly clicking the hidden control. The input remains in the markup and supplies the state that the CSS selectors use.
The .toggle-track creates the main switch body. It is 50px wide and 28px high with border-radius: 999px, producing the pill shape. Its default background is #0b1423, and a #33445f border separates it from the surrounding interface. flex: 0 0 50px prevents the track from shrinking inside the inline-flex wrapper.
The .toggle-thumb is a 20 Ă— 20px circle positioned 3px from the top and left edges of the track. In the default unchecked state, it uses the muted #8190a5 background. Both the track and thumb use .25s ease transitions, which smooth the change between states.
The checked appearance is controlled entirely with CSS selectors. input:checked + .toggle-track targets the track immediately following the checked checkbox. Its border changes to cyan #22d3ee, its background becomes #0f3b46, and a subtle cyan glow is added with box-shadow.
A second checked-state selector reaches the nested thumb. It applies transform: translateX(22px), moving the circle from the left side of the track to the right, and changes its background to #22d3ee. For more detail on styling controls according to their checked state, see the MDN :checked documentation.
There is also a simple hover state. When the pointer is anywhere over .toggle-switch, the track’s border changes to cyan. Because the track already uses the .25s ease transition, this hover feedback changes smoothly.
No JavaScript is included in this component. The switch visually changes between checked and unchecked states through the checkbox and CSS alone. Although its text says “Enable dark mode,” the current code does not actually change a page theme or trigger any other application behavior.
Customizing the Toggle Switch
The component’s size, movement, colors, timing, and accompanying text can all be adjusted through the existing HTML and CSS values.
- Change the track’s 50px width and 28px height to create a larger or smaller switch.
- Adjust the 20 Ă— 20px
.toggle-thumbdimensions to resize the circular control. - Change the thumb’s
top: 3pxandleft: 3pxvalues to modify its spacing inside the track. - Adjust
translateX(22px)if you change the track or thumb dimensions. - Replace
#22d3eeto customize the active thumb, border, hover, and glow color. - Edit
#0b1423and#0f3b46to change the inactive and active track backgrounds. - Modify
.25s easeto make the thumb movement and state transitions faster or slower. - Change “Enable dark mode” inside
.toggle-textto describe the setting controlled by the switch.
Where to Use This Toggle Switch
A toggle is most appropriate for settings that can naturally be represented by an immediate on/off state.
- Dark mode and light mode settings
- Notification preferences
- Sound or vibration controls
- Privacy settings
- Automatic update options
- Dashboard feature controls
- Application preference panels
For settings that require choosing one option from a group rather than switching one setting on or off, the Custom Radio Buttons component is a more suitable related control. This Toggle Switch provides the visual checked state only, so any real dark-mode or application-setting behavior would need to be connected separately.
Frequently Asked Questions
Does this Toggle Switch require JavaScript?
No. The retrieved component contains no JavaScript. Its visual state is controlled entirely by the native checkbox and CSS :checked selectors.
Does the switch actually enable dark mode?
No. “Enable dark mode” is the visible label text, but the component does not contain logic that changes page colors, classes, themes, or application settings.
How does the thumb move to the right?
When the checkbox becomes checked, CSS targets .toggle-thumb through the checked input and adjacent track. It applies transform: translateX(22px), moving the 20px circular thumb across the 50px track.
Can users click the text to toggle the switch?
Yes. The checkbox, custom track, and text are all contained within the same <label>. Clicking the label content changes the associated checkbox state.
This Toggle Switch keeps the implementation small by letting the native checkbox manage state while CSS handles the custom track, moving thumb, active colors, hover feedback, and transition.
