TS-07Case study
Toggle Switchy: a full component API in 147 lines of CSS
A pure CSS toggle switch for form checkboxes. Seven colors, five sizes, three shapes, two text modes, and two label positions multiply into 420 switch combinations from one 147-line file. Zero JavaScript, and my most-starred repo.
01The idea
A switch is a checkbox wearing better clothes
Every toggle switch on the web is secretly a checkbox, or should be. The browser gives a checkbox its state, its keyboard handling, its form participation, and its screen reader announcement for free. Most switch components throw that away, rebuild it out of divs and JavaScript, and ship the rebuild as a dependency.
Toggle Switchy keeps the checkbox. It's a pure CSS toggle switch for form input checkboxes: a label wraps a real input, one stylesheet does the rest, and there is no JavaScript anywhere in the library. Not a build step's worth, not a polyfill's worth, none. It grew out of the same pure-CSS work I wrote up in CSS-only UI patterns that replaced my JavaScript.
It's the smallest thing I've published and the one with the widest reach. 46 stars and 12 forks make it my most-starred repo, which is a lesson in itself: the project other developers adopt isn't the clever one, it's the one that saves them an afternoon.
Three real checkboxes, zero JavaScript. Click them, or tab in and press space. Rebuilt here with this sheet's theme tokens; the library ships its own seven colors.
02The mechanism
Adjacent siblings do all the work
The integration is four elements: a label with the class, a real checkbox, a track, and a switch. The checkbox hides with position: absolute and opacity: 0, never display: none, so it stays focusable, keyboard-togglable, and present in the form.
Everything visual rides adjacent sibling selectors off that hidden input. The words ON and OFF never appear in your markup: they're CSS content on the track's pseudo-elements, cross-fading as the state flips. Track color, switch position, and text opacity all move on 200ms linear transitions.
<label for="demo" class="toggle-switchy">
<input checked type="checkbox" id="demo">
<span class="toggle">
<span class="switch"></span>
</span>
</label>
Copy, paste, done. Every option after this is a data-attribute on the label.
input:checked + .toggle- recolors the track and slides the switch to the ON side
input:not(:checked) + .toggle > .switch- parks the switch at OFF
.toggle:before / .toggle:after- paints the ON and OFF text as CSS content, no markup involved
input:focus + .toggle- draws a focus ring, so keyboard users can see the control
input[disabled] + .toggle- drops to half opacity with a not-allowed cursor
03The API
420 switches, zero stylesheet edits
Every option is a data-attribute on the label, not a class to memorize. The stylesheet reads the attributes; you never edit it.
-
data-colorred · orange · yellow · green · blue · purple · gray
Seven color schemes. Blue is the no-attribute default.
-
data-sizexs 45x20 · sm 55x25 · default 65x30 · lg 75x35 · xl 85x40
Five sizes, measured in px. Leave the attribute off for the 65x30 medium.
-
data-stylerounded · square
Default corners are 4px. rounded is a 50px pill; square is 0 radius.
-
data-text="false"removes ON / OFF
Drops the words and narrows every width to match.
-
data-label="left"label side · flexbox order
Puts the label text on the left of the switch with a flexbox order swap. Right is the default.
-
checked · disablednative attributes
State comes from the input itself. disabled renders at half opacity with a not-allowed cursor.
04Pack weight
The whole repo fits in your head
The published library is one file: toggle-switchy.css, 147 lines, 7,741 bytes. The repo around it is a LICENSE, a README, and a docs folder that doubles as the demo site. No build step, no preprocessor, no package.json, no dependencies.
The README promises it "doesn't dump a bunch of global styles that'll screw with your other CSS", and the file keeps that promise from the inside too: a literal comment fence separates the styles you're invited to customize from the mechanics you're meant to leave alone.
/* CORE STYLES BELOW - NO TOUCHY */
Customizable styles (colors, radii) sit above the line; core mechanics sit below it. Edit above, leave the rest alone.
- CSS only, no JavaScript
- Keyboard accessible, with focus styles
- Screen reader friendly
- Search engine friendly
- Fully responsive
- Fully self contained, no dependencies
05Reach
How a single file travels
Public under MIT since October 2018, with 46 stars and 12 forks. Distribution matches the engineering: no registry, no wrapper package, no install script. It also holds a spot in the open-source tier on the projects sheet, next to the bigger builds.
-
Install is one line
The README's installation section is a single stylesheet link. Download the file or point at it; there is nothing to configure and nothing to build.
-
CDN straight from GitHub
jsDelivr's GitHub CDN serves the file directly from the repo. The demo site itself loads the library that way, which makes every visit a small smoke test.
-
Its own front door
The demo lives at toggleswitchy.com, a real domain pointed at the repo's docs folder and served by GitHub Pages. Its sections walk the API: Default, Rounded, Square, No Text, Disabled, Colors, Labels.
-
Versioned like software
Four tagged releases, 1.11 through 1.14. The file header reads version 1.14, dated August 2020.
-
A sister project
Toggle Radios applies the same idea to radio inputs, and the two READMEs point at each other.
-
Old IE loses the glide
The known-issues section says it outright: "IE10 and below doesn't support the smooth slide." Support targets all modern browsers, and the README says so plainly.
-
Not on npm
There's no package.json, so there's no npm package. Install is a link tag, and jsDelivr covers the CDN case straight from GitHub.
-
Quiet since 2020
The last tagged release is 1.14, from August 2020. With no dependencies there is nothing to bump, so the quiet reads as finished rather than abandoned, but the commit dates are what they are.
Stack
- CSS · one file
- Checkbox hack
- data-attribute API
- GitHub Pages
- jsDelivr · GitHub CDN
- MIT license
By the numbers
- 147 lines of CSS, the whole library
- 420 switch combinations
- 0 lines of JavaScript
- ~7.6 KB unminified, no build step
- 46 stars on my most-starred repo
07Next traverse
Need UI other teams can just drop in?
Toggle Switchy is component API design at its smallest: sensible defaults, clear options, nothing to configure, nothing to break. I bring the same discipline to bigger surfaces, including a design system that covers 150+ commercial sites. If your product has UI that other developers build on, tell me about it.