Sign in

iiinova is part of the Atmosphere — an open, public network where you own your identity.

Keith Cirkel

@keithamus.social
2.3K followers 1.2K following 622 posts

Software Cyber Shepherd. Web platform engineer. Participant: WHATWG, CSSWG, ARIAWG, OpenUICG, WebComponents CG Website: keithcirkel.co.uk GitHub: github.com/keithamus Mastodon: indieweb.social/@keithamus

PostsRepliesMedia
Keith Cirkel @keithamus.social · 23/08/2026
Sorry this took over a month to get done, but csskit@0.0.30 now has a JS API. No docs yet 😳 (maybe an adventurous developer would like to contribute some 😉) but it's hopefully intuitive. Parsing only, minification/formatting will come later.
Code:

import {
  StyleRule, StyleSheet, Color, MediaRule
} from "csskit";

const sheet = StyleSheet.parse("a { color: red }");
sheet instanceof StyleSheet; // true

for (const rule of sheet.querySelectorAll("style-rule")) {
 rule instanceof StyleRule; // true
 console.log(rule.constructor.name, rule.text);
   // -> StyleRule a { color: red }
}

Color.parse("#ff0000");
MediaRule.parse("@media print { a { color: red } }");
1122 12
Keith Cirkel @keithamus.social · 17/08/2026
Headcanon now:
A picture of Brian Kardell stressing about which TOTP to input (the “two buttons” meme)
010 1
Keith Cirkel @keithamus.social · 05/06/2026
Things are escalating.
Alt text: Screenshot of a terminal split into three panes. On the left, a process monitor shows 12 `csskit` processes, most using 99.5% CPU and between about 44 MB and 219 MB of memory. On the top right, a command is running `cargo run --release -- ingest-selectors --db data/css.sqlite --jobs 12`; it reports that 36,239 CSS bodies are already analyzed and is processing selectors, currently at 5,550 of 32,269 at about 18.5 items per second, with an estimated 24 minutes remaining. On the bottom right, a repeating `ls -lah data/` output shows a SQLite database directory totaling 688 MB, including `css.sqlite` at 677 MB, `css.sqlite-shm` at 32 KB, and `css.sqlite-wal` at 11 MB.
040 4
Keith Cirkel @keithamus.social · 17/05/2026
If you're ever wondering "hey I wonder what Keith is up to right now"... I'm just running the http-archive through csskit and making databases from it. Just normal stuff over here.
A screenshot of a commandline executing a sql query. The text reads:

sqlite3 -csv data/css.sqlite "SELECT value_text, COUNT(*) AS n FROM decls WHERE property = 'touch-action' GROUP BY value_text ORDER BY n desc;"
none,2929
pan-y,2207
manipulation,1544
pan-x,907
auto,195
pinch-zoom,112
"pan-x pan-y",112
"var(--tw-pan-x) var(--tw-pan-y) var(--tw-pinch-zoom)",93
"pan-y pinch-zoom",57
pan-Y,46
"var(--tw-pan-x,)var(--tw-pan-y,)var(--tw-pinch-zoom,)",17
var(--tw-pan-x)var(--tw-pan-y)var(--tw-pinch-zoom),13
"cross-slide-y pinch-zoom double-tap-zoom",12
"var(--tw-pan-x,) var(--tw-pan-y,) var(--tw-pinch-zoom,)",11
"pan-x pan-y pinch-zoom",9
"var(--yarl__controller_touch_action,none)",8
unset,6
pan-up,4
pan-right,4
pan-left,4
pan-down,4
initial,4
var(--b-modal-custom--page-lock-touch-action),2
"pan-y pan-x",2
"pan-x pinch-zoom",2
inherit,2
"var(--tw-pan-x, )var(--tw-pan-y, )var(--tw-pinch-zoom, )",1
var(--t1ljxn-5),1
"pinch-zoom pan-y",1
pan-zoom,1
"pan-y, pan-x",1
"pan-y pinch-zoom double-tap-zoom",1
"pan-x pan-down pinch-zoom",1
"pan-x pan-down",1
"""pan-y pinch-zoom""",1
3360 36
Keith Cirkel @keithamus.social · 01/05/2026
The Web Frameworks Community Group now has over 60 members representing Alpine, Astro, Ember, Lit, Lustre, Marko, Preact, Qwik, React, Ripple, Solid, Stimulus, Svelte, Vue, Web Components, htmx, and more! Did I miss your favourite? Come join us and represent! discord.com/invite/fXCng...
A screenshot showing the icons of the frameworks listed in the post.
2335 33
Keith Cirkel @keithamus.social · 05/04/2026
5 days and over 27,000 plays. Thanks for all who had fun with it! Here are some stats for all you data nerds to enjoy.
CSS or BS? 27,004 total plays. 12 perfect scores - 80 out of 80, definitely real players, no cheating here.... Most dedicated player: Arif with 5 submissions. 6 players scored zero, that takes commitment. Broke everyone: text-combine-upright, only 11% got it right. The freebie: transform, 98% got it right. Fooled everyone: grid-rows, 72% fell for it. How did you miss this: text-decoration-line, 59% said it was BS. The coin flip: writing-direction, 50% got it right. Nobody fell for this: copy-into-scope, 96% called it out. Most wished-for property: background-opacity - every one has tried it once. The one spec authors don't want you to ask about: footnote-policy - technically in spec, but bring it up in a CSSWG meeting and watch the room go silent. Property most likely to exist by 2030: margin-trim - Safari shipped it, everyone else is 'considering', we'll be here a while...
0265 26
Keith Cirkel @keithamus.social · 02/04/2026
11%. I'll take it.
A dark-themed radar chart of my score. The caption above says ‘You scored 11%. That puts you in the "not a tech bro" range.’ Below is a radar chart with categories labeled meritocracy, solutionism, disruption, libertarianism, hustle, privilege, and utopianism. There is one small point towards privelege and one towards disruption.
010 1
Keith Cirkel @keithamus.social · 23/03/2026
A side-by-side comparison of DLSS 5. On the left a picture of Maui from the Disney animated film Moana, in all his 3d glory, underneath a caption reads "DLSS 5 Off", in a black box. On the right - divided by a stripe of nvidia's brand green - a picture of Dwayne Johnson in full Maui costume, from the live action version of Disney's Moana, beneath which the caption "DLSS 5 On" sits in a white box with an nvidia green border.
0101 10
Keith Cirkel @keithamus.social · 14/03/2026
Also in case you're curious, over 2 million people have now played this game 🥵 Site traffic is up quite a bit.
A cropped screenshot of what appears to be an analytics dashboard.

The top bar reads: "Week ↑ 385093.6% Month ↑ 89930.4%"

Below those numbers is a table showing a histogram of activity, each of the 7 rows are days of the week and the 24 columns represent hours, where bright red is the most active period. Thursday & Friday are bright red, while the prior days are almost all black. Activity has died down a bit on Saturday, which is a darker red than Thursday & Friday.
2332 33
Keith Cirkel @keithamus.social · 11/03/2026
Always use indexes.
A screenshot of a Grafana graph measuring CPU. From 16:00 to about 17:10 the CPU is 20% "Busy System" and 100% "Busy User". From 17:10 onwards the chart falls off a cliff and uses less than 5% for both, with very occasional spikes around 20%.
1240 24
Keith Cirkel @keithamus.social · 05/03/2026
A modified version of the XKCD 386 "Duty Calls" comic. Someone out-of-frame asks "Are you coming to bed?", a person tapping away on their computer keyboard responds "I can't. This is important". The out of-frame-voice responds "What?", finally the person busy typing away responds (edited from the original comic) "People are over specifying their oklch values".
0130 13
Keith Cirkel @keithamus.social · 17/01/2026
Obligatory:
A screenshot of a tweet from @AlexBlechman, at 5:49 PM, Nov 8, 2021. The post reads:

Sci-Fi Author: In my book I invented the Torment Nexus as a cautionary tale

Tech Company: At long last, we have created the Torment Nexus from classic sci-fi novel Don't Create The Torment Nexus
040 4
Keith Cirkel @keithamus.social · 30/12/2025
A rough prototype, but it's working! `csskit@0.0.11` now has a linter language! you can define "rule sheets" with a css-like syntax, then run them against your actual stylesheets and it'll lint your css in a split second! Run `csskit tree` to see how to select nodes. `npm i csskit@latest` ;)
An editor window with the contents of a "Csskit Rule Sheet". The code reads:

/* check.cks */
:prefixed {
  level: error;
  diagnostic: "Avoid prefixed properties";
}

compound-selector:has(id) {
  level: error;
  diagnostic: "Avoid IDs in css selectors";
}

style-value[name=color]:not(:computed) {
  level: error;
  diagnostic: "Don't use literals in color style values, only our design tokens";
}

compound-selector:has(:nth-child(4)) {
  level: warning;
  diagnostic: "Complex selector, consider refactoring";
}
A code edit with a CSS file open. The code reads:

#a {
	color: red;
	-webkit-animation: spin 3s;
}

div.b.c.d.e {
	color: var(--red-500);
}A terminal window. The user has run the command `csskit check check.cks style.css` and the result is the following output:

  × Avoid prefixed properties
   ╭─[test.css:3:2]
 2 │     color: red;
 3 │     -webkit-animation: spin 3s;
   ·     ─────────────┬─────────────
   ·                  ╰── Avoid prefixed properties
 4 │ }
   ╰────
  × Avoid IDs in css selectors
   ╭─[test.css:1:1]
 1 │ #a {
   · ─┬
   ·  ╰── Avoid IDs in css selectors
 2 │     color: red;
   ╰────
  × Don't use literals in color style values, only our design tokens
   ╭─[test.css:2:2]
 1 │ #a {
 2 │     color: red;
   ·     ─────┬─────
   ·          ╰── Don't use literals in color style values, only our design tokens
 3 │     -webkit-animation: spin 3s;
   ╰────
  ⚠ Complex selector, consider refactoring
   ╭─[test.css:6:1]
 5 │
 6 │ div.b.c.d.e {
   · ─────┬─────
   ·      ╰── Complex selector, consider refactoring
 7 │     color: var(--red-500);
   ╰────
Error: 1 files failed check!
A terminal window. The user has run `csskit tree style.css` and the result is the following output:

style-sheet
├─ style-rule:rule
│  ├─ selector-list:size(1)
│  │  ╰─ compound-selector
│  │     ╰─ id
│  ├─ style-value[name=color]:longhand
│  │  ╰─ style-value
│  │     ╰─ color-style-value
│  │        ╰─ color
│  ╰─ style-value[name=-webkit-animation]:unknown:prefixed
│     ╰─ style-value
╰─ style-rule:rule
   ├─ selector-list:size(1)
   │  ╰─ compound-selector
   │     ├─ tag
   │     │  ╰─ html-tag
   │     ├─ class
   │     ├─ class
   │     ├─ class
   │     ╰─ class
   ╰─ style-value[name=color]:computed
      ╰─ style-value
4461 46
Keith Cirkel @keithamus.social · 30/09/2025
It's impossible to get to inbox zero on GitHub because I got @ mentioned in a couple of spammy repos which are deleted, but the notifications are hanging around in my inbox and I cannot remove them. GitHub knows this is an issue but don't seem to want to fix it so... 🤷
490 9
Keith Cirkel @keithamus.social · 23/09/2025
Ahhh. Always nice when you can add ~180LOC to your ~100kLOC codebase and make it go twice as fast. github.com/csskit/csski...
1130 13
Keith Cirkel @keithamus.social · 19/08/2025
Arrested Development's Lucille Bluth with the caption "It's one CSS Parser. How hard could it be?"
010 1
Keith Cirkel @keithamus.social · 01/08/2025
I apologise in advance.
A set of grotesque chairs (one white, one grey, one black) which would otherwise be fine but some plonker thought it would be sensible to strap a door knocker to the back of it.
270 7
Keith Cirkel @keithamus.social · 18/07/2025
It's likely not in that release. When you go to `about:config` and search for the pref, if it's not already in the list as `false` then it is not available in that release. You might instead get a UI to create the new pref which won't do anything Consider the following screenshots; subtle I know.
A screenshot of Firefox in the `about:config` page. The search bar has the text `layout.does.not.exist` and below is a form to add a new preference with that name. One can determine this is a form to add a new pref because it has a set of radios for the type (Boolean, Number, String) and a `+` button with the tooltip `Add`.A screenshot of Firefox in the `about:config` page. The search bar has the text `layout.css.anchor-positioning.enabled` and below is a result for an existing preference with that name. One can determine this is an existing pref because it does _not_ include the form to set this prefs type (Boolean, Number, String), nor does it have the `+` button, and instead it has the default value of `false`, and a button to reset to the default value.
200 2
Keith Cirkel @keithamus.social · 16/07/2025
I did a thing. These are all the steps (with citations) each of the browsers take to determine if a <table> element is really a <table> element or if it's just sparking layout. deploy-preview-2576--wai-aria.netlify.app/html-aam/#el...
An absolutely gargantuan screenshot of the spec prose available on https://deploy-preview-2576--wai-aria.netlify.app/html-aam/#el-table
3151 15
Keith Cirkel @keithamus.social · 01/07/2025
Hot off the presses! Firefox Nightly (www.mozilla.org/en-GB/firefo...) adds the new :heading pseudo! Easily style all headings, or use nth-child-like AnB syntax to select a range of headings! Needs `layout.css.heading-selector.enabled` flag enabled. Try it out and let me know your thoughts.
A screenshot of Firefox Nightly, with the Codepen https://codepen.io/keithamus/pen/wBaZVaX open. The page showing 6 heading levels, showing the CSS, HTML and the rendered page. Each heading is styled differently using the provided CSS selectors, `:heading` (which styles all headers), `:heading(-2n+3)` (styles h1 and h3 elements), `:heading(5, 6)` (styles the h5 and h6 elements). Another Firefox Nightly window is open, showing the `layout.css.heading-selector.enabled` flag is set to `true`, making the rendered page styled using the new selectors.
310029 100
Keith Cirkel @keithamus.social · 07/06/2025
Nice! Mines in a half-way state because I recently decommissioned some machines when I upgraded from a synology+pis to a bigger NAS, so here is the current state:
210 2
Keith Cirkel @keithamus.social · 28/04/2025
Lots of sites have this "hovercard" style pattern on links which shows you a cut-down preview of the page behind the link - often times with additional interactions. I wonder if anyone has any more examples? Especially sites which do this (display a rich tooltip) on non-links.
A screenshot of a "Hovercard" on GitHub, showing the "W3C" org avatar hovered over, which has popped open a rich tooltip showing more information about the org - including their location, member count, the number of repositories, and their verified status.A screenshot of the Wikipedia "popover" article. The link "Yorkshire Pudding" has been hovered, which has displayed a preview-card with a small except from the Yorkshire pudding page, including the image on that article.Hovering over a username on mastodon renders a "hover card" - in this case hovering over the avatar of user "keithamus" shows the username, handle, description, as well as links and follower count - and an "edit profile" button.
9194 19
Keith Cirkel @keithamus.social · 28/04/2025
Browsers used to have a feature where you could add new context menu items. Is this worth reviving? Yes or No? Would you use it as a developer? What use cases do you have? Would you want this as a user?
A screenshot of a website's context menu, with additional custom menu items that the website has provided - a "Follow" option and a "Chat" option.
693 9
Keith Cirkel @keithamus.social · 16/02/2025
Like the <dialog> element? Annoyed it doesn't fire `beforetoggle` and `toggle` events? It's coming! Firefox & Chrome support, but coming very soon in Opera & Safari. I wrote a polyfill for it github.com/keithamus/di...! You can use it in all browsers today!
A screenshot of the browser compatibility table for `beforetoggle` event. On dialog elements this is supported in Chrome 132, Edge 132, Firefox 133, but flagged in Opera 117 and not yet supported in Safari.
0334 33
Keith Cirkel @keithamus.social · 12/12/2024
Yikes. Not even 650 women responding to this survey? State of JS or State of White Mans opinions amirite?
3110 11