Front-End · Pure CSS
No-Script CSS Arcade
Eight playable browser games with zero lines of JavaScript. Every bit of game logic — navigation, scoring, win and fail states — is a CSS state machine built from pseudo-classes, the checkbox/radio hack, and modern selectors like :has().
- HTML5
- CSS3
- No JavaScript
- :target / :has()
- Radio & checkbox state
pattern+ :valid
Overview
This is a deliberate constraint project: can a game be interactive — with state, scoring and win conditions — using only HTML and CSS? The answer is yes, if you treat the page itself as a state machine. Radio buttons hold mutually-exclusive state, checkboxes latch toggles, :target tracks "where you are", and :has() lets a parent react to its children. No scripts means no framework, instant load, and nothing to block.
The games
🏰 The Locked Manor
A :target room-to-room escape room with a radio-button combination lock — find the code, and a wrong guess trips a :has() alarm.
🔌 The Wire
A :hover collision maze where the wall sits behind the path as a sibling, so grazing it ends the run; the win latches with a checkbox.
🔨 Mole Patrol
Whack-a-mole on @keyframes timing, with a live score counted purely by counter-increment on :checked — and a reset button to replay.
🔐 The Cryptex
A riddle lock that validates answers with the pattern attribute and :valid; solve every stage and :has() swings the vault open.
⚙ The Escapement
A reaction game where brass teeth sweep across a clock face; tap each one and the :checked latch freezes it — catch all eight to lock the mechanism.
🔔 The Belltower
A sequential puzzle: ring the tower bells in chord order. Each rung bell lights the next via a :has() chain — the seventh chime unlocks the win.
🔌 The Switchboard
A logic puzzle: flip five switches to light all nodes. Each switch affects its neighbours — :has() enumerates XOR parity states to detect the solution.
🎨 The Colorsmith
A colour puzzle: toggle pigment layers that blend with mix-blend-mode:screen over a black base. :has() fires when the exact target combination is active.
How it works
- State without scripts: radio buttons model exclusive choices (lock digits, current room); checkboxes latch toggles (win flags, maze completion).
- Navigation:
:target+ anchor links move between "screens" with no router and no JS. - Reactions:
:has()lets a container respond to a child's state — alarms, win screens, the opening vault. - Scoring: CSS counters (
counter-incrementon:checked) tally points; the 0×0 input trick keeps the counter alive (display:nonewould kill it). - Validation: the
patternattribute +:validturn the riddle lock into a self-checking form.