In 2018, tracking a website visitor looked like a JavaScript problem: a script fires a beacon on page load or on a click, and if scripting is blocked, disabled or filtered, the whole channel goes dark. Crooked Style Sheets, a proof of concept by the developer jbtronics, showed that a page can be tracked with no JavaScript at all, using only the browser's own CSS engine.

The obvious approaches all leaned on scripts or pixels: a tracking snippet that phones home, an image tag, a third-party analytics SDK. Every one of them is a visible request class that script blockers and ad filters were built to catch, and none of them fire on a page where scripting never runs.

The trick was in when browsers fetch CSS url() resources: only when a selector matches. A link's :active style with content: url(track.php?action=link2_clicked) therefore makes the browser request that URL exactly when the link is clicked. The same principle covered hovering, checked boxes, text matching a pattern via :valid, browser detection via @supports, and installed-font detection through an @font-face fallback that loads when Calibri is missing. Every request hit a PHP page that logged the timestamp and the action encoded in its URL.

Because the requests are ordinary CSS-driven asset loads, they carry no script call for a blocker to identify, and stylesheets still apply when JavaScript is off. The January 2018 Hacker News post drew 532 points and 175 comments, and the repo had grown to roughly 3.3k stars and 132 forks by 2026. The defense it provoked included the CSS Exfil Protection extension, and the author argued the robust fix was for browsers to fetch CSS-referenced external content at page load instead of on demand, a change he acknowledged would cost performance.

Treat the browser's lazy CSS resource fetches as event beacons: selectors that match only on click, hover or a missing font fire a request the server can log

Browsers decide when to fetch CSS url() content, so a matching selector produces a network request with no JavaScript call an ad-blocker can target.

The requests look like ordinary image or font loads, indistinguishable from legitimate assets in logs and most blocking tools.

State-dependent selectors encode meaning in the URL itself: the resource path names the event, and the server only logs arrival timestamps.

CSS still applies on pages where scripting is disabled, closing the gap that made no-JavaScript look like privacy.

Declarative formats still perform conditional work: any state-dependent resource load is an observable signal, so defenses must treat CSS-originated requests as behavior worth restricting

The repo reached Hacker News on 16 January 2018 and drew 532 points and 175 comments; by the 2026 crawl it showed roughly 3.3k stars and 132 forks. The demonstration seeded at least one defense, the CSS Exfil Protection extension linked from its own README, and the author's writeup argued the durable fix is for browsers to load CSS-referenced external content when the page loads rather than when a selector matches, a change he noted would cost performance. The original demo site later went offline, leaving the repository's code samples as the working record of the technique.

FOLLOW THE EVIDENCE

The sources

  1. CrookedStyleSheets - Webpage tracking only using CSS (and no JS) github.com
  2. Crooked Style Sheeding - Webpage tracking using only CSS news.ycombinator.com