Exhibit 13 of 17
The stockroom maze
Find the lamp glass in the stockroom behind the showroom. Each room is a section of this page; going through a door is following a link to the next one.
The exhibit
Loading bay
Pallets, a roll-cage and a sign that says DELIVERIES 9–5. It is neither.
Returns desk
A bell, a pen on a chain, and a queue of chairs waiting to be returned to themselves.
Aisle of chairs
Every chair faces the wall. You don’t check whether they turn round when you leave.
Pallet of lamps
Forty lamps, none of them on. Not the lamp you want, and none of them have glass.
Aisle of mirrors
You, forty times, slightly behind schedule.
Staff room
A kettle, a rota nobody follows, and a staff vest on a hook. The vest is empty. Probably.
Boxes of nothing
Boxes labelled NOTHING, stacked to the ceiling. One of them is lighter than nothing.
The glass shelf
One lamp glass, on display. You take it anyway. Found it: the lamp can go back on.
The stockroom door
The door from the showroom swings shut behind you. Somewhere in here is a lamp glass. Everything is on display; nothing is in stock.
How it works
Every room is a <section> with an id, and only .room:target is shown. The way in is the last room in the HTML, so .room:target ~ #room-door hides it whenever another room is the target, without :has(). The little map does use :has() to find which room is the target, and just isn’t drawn without it.
The key CSS
Cut from this exhibit’s stylesheet as it is served.
/* only the room the URL names is shown */
.x-maze .room { display: none; }
.x-maze .room:target { display: block; }
/* the way in is the last room in the document: shown until any other room becomes the target */
.x-maze #room-door { display: block; }
.x-maze .room:target ~ #room-door { display: none; }
/* the map: where the target is (needs :has(); without it, there's no map) */
@supports selector(:has(*)) {
.x-maze .map { display: grid; }
.x-maze .maze:not(:has(.room:target)) .m-door { background: var(--ink); }
.x-maze .maze:has(#room-door:target) .m-door,
.x-maze .maze:has(#room-loading:target) .m-loading,
.x-maze .maze:has(#room-returns:target) .m-returns,
.x-maze .maze:has(#room-chairs:target) .m-chairs,
.x-maze .maze:has(#room-lamps:target) .m-lamps,
.x-maze .maze:has(#room-mirrors:target) .m-mirrors,
.x-maze .maze:has(#room-staff:target) .m-staff,
.x-maze .maze:has(#room-boxes:target) .m-boxes,
.x-maze .maze:has(#room-glass:target) .m-glass { background: var(--ink); }
}
Accessibility
Quite good: rooms are headed sections and exits are links, so it is ordinary navigation. Following a fragment link moves keyboard focus to the room. The URL and history change with every step (Back goes back a room, which is arguably a feature), and the page may scroll to the room.
Browser support
:targetWorks in this browser.Not in this browser: Universal. Checked 2026-10-14: Chromium 149 yes, Firefox 141 yes.:has()Works in this browser.Not in this browser: Without :has() it can’t work; the page says so instead of half-working. Checked 2026-10-14: Chromium 149 yes, Firefox 141 yes.
