Posts in Web-development (20 found)
Kev Quirk Yesterday

Why is Pure Blog so ugly?

Someone emailed recently to tell me that they like the idea of Pure Blog, but they thought the admin interface was "really ugly" so they can't use it. Fair enough - beauty is in the eye of the beholder and all that, but I don't think that was a fair evaluation of Pure Blog's admin UI. When I built Pure Blog, I wanted it to be different from the rest of the crowd. The whole point of it was to have just enough features, and no fluff. So to me a more brutalist/utilitarian UI made sense. The likes of Grav, WordPress, Ghost, and Bludit all have similar interfaces. White and grey with blues, purples, and greens. Rounded corners etc. All very iOS-ish. All very...safe. I wanted Pure Blog to stand out from the crowd and have its own identity, and honestly, I'm thrilled with the results. Pssst. If you haven't tried Pure Blog yet, check out the demo site . But what I like may not be what you like, which is why I built Pure Blog to be very customisable from the start. You can change the fonts from mono, to sans, or serif with the click of a button, or you can change the look of the entire UI if you know some CSS. And this is what I said to the person who emailed me saying it was ugly. But they came back with... Great. Do you have any examples? I didn't! So I decided to create some examples and show them here so you can see just how customisable Pure Blog really is. I know other CMSs can customise their UI too, but unlike them, Pure Blog needs no plugins, hacks, or bullshit. This can all be done with standard Pure Blog right out of the box. So here are some examples of the Pure Blog admin UI where all I've added is custom CSS within settings. How about bringing a macOS / iOS vibe to your Pure Blog site? Or maybe you like the super clean lines of the Ghost UI? Well, you can have something similar to that too if you like: Are you a WordPress purist who really wants to be as faithful as possible to their design? Well guess what - you can have that too! Maybe you're a lover of anything Bill Gates touches. If so, a Windows theme might be more your thing. Maybe all this GUI stuff isn't your jam? Do you yearn for the days of yore when the interface to a computer was terminal-only with a monochrome CRT monitor? Well, Pure Blog can do that too: Green – the connoisseur's terminal. Or orange, the truly old-school terminal. I think these screenshots show what Pure Blog is capable of. Your imagination really is the limit. So just because you think the default look of Pure Blog is ugly, don't fret - you can easily change it to be whatever you want it to be. If you're interested in grabbing any of these themes for your Pure Blog installation, all the CSS is available over on the docs site . Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views
Unsung Yesterday

The distance between ⌘8 and ⌘9

One thing that might be fun to add to the ⌘1/2/3 tab post is this: while ⌘1–8 select tabs from the left, ⌘9 doesn’t jump to the ninth tab, but to the last tab: I think it’s thoughtful – a recognition that both edges are important. (Previously we’ve seen Bear understanding that , too.) Why not ⌘0, though? Sure, you can say it’s not as elegant (0 is smaller than 9), or that it wouldn’t work in Hungary… = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-distance-between-cmd8-and-cmd9/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/the-distance-between-cmd8-and-cmd9/3.1600w.avif" type="image/avif"> …but I think the Occam’s Razor is simply that ⌘0 has already been taken by a popular “zoom to 100%” command by then, and overlapped too often for comfort.

0 views
Chris Coyier 2 days ago

Archived Tweets

I finally got around to importing my whole historical Twitter archive (just my own original tweets, not replies or retweets) into this WordPress site as a proper Custom Post Type: https://chriscoyier.net/tweets I haven’t added it to the navigation or anything else on the site yet. Not sure what I want to do there. Just feels good having my own data. The Tweets show up in the Jetpack-powered search too, which I’ve found nice. I used this and hacked it up a bit to fit my needs, and so I didn’t have to leave it as a permanently installed plugin. It’s coming at a weird time, with quite a few people “going back” to Twitter. It’s actually called X now; I’m aware. It’s named after the hand gesture you do when Elon Musk asks if you’d like to come over for a dinner party: 🙅‍♂️ Casey Newton just saying, “Look, I tried, but X is where the action is,” and John Gruber being like, “Take a whiff; the Elon stench is gone.” I understand both of those things. I honestly really like both Mastodon and Bluesky, but after years and years, the fun and engagement have never reached old Twitter norms. And I miss that! But it also feels like you have to ignore a lot of bad behavior to use a platform that Elon Musk not only owns but literally bought to be his megaphone and power center. Do people not remember the horrible shit he would do on a near-daily basis? Tasteless, dangerous, and often both. I can remind you! Here’s just one straw from a haystack. Elon loves him some Trump. They are big buddies! Elon shouldered up to Trump for the power, and Trump gave it to him. Elon decided to take this power (granted to him by a scepter touch? apparently?) and created a real government organization called DOGE, which is a joke name, named after a joke cryptocurrency that is inherently corrupt. DOGE’s job was to make the government “more efficient” by eliminating funding for tons of stuff. One of the things they did was entirely get rid of the USDS, which was the organization that did incredible work, ya know, making governmental websites far more efficient. Now, our government makes racist video games on the web instead. Not kidding. That’s a fucking game on our own government’s website, where you play a white dude who walks around a page collecting brown people to deport. I find it more than a little hard to swallow.

0 views
./techtipsy 2 days ago

Faithfully reimplementing an obscure Estonian Flash game for modern browsers: GTA õppesõit

Play it here! (desktop browsers only) Or try the “remastered” one! (desktop and mobile) There used to be an Adobe Flash game where the goal was to pass a driving test, with the instructor being ready to berate you whenever you screwed up. It’s virtually unknown outside of Estonia, but I remember playing it as a child, and it was a lot of fun. Sadly, Flash is no longer relevant, and the original website has gone offline a long time ago. For a while, the only way to experience what the game is, was this YouTube video showing its gameplay. Luckily, backups of the original Flash game exist in the Internet Archive , and I also learned that this website hosts it with a solution that translates the original game, albeit with less than stellar results. To preserve a piece of media reliably over a long time period, you need to format shift it. I decided to use a similar idea to preserve this game by putting my responsible vibe coding hat on and turning this into an authentic recreation that runs on modern browsers, including all the tiny details and admittedly horrible key bindings. After all, making old games work on modern browsers is so hot right now. For this, I relied on my homegrown custom sandbox (Podman and a shell script), Claude Code, and Opus 5.5. The workflow was quite simple, with the main goal being to offload as much of the work as possible, and to ensure that the agent can check its work along the way. By the time it was specced and a few clarifying questions covered, it executed it and the end result was playable the first time. On a high level, the process was this: I expected a lot more trouble than that. But no, it just works. Smartphones weren’t a thing back when this game was made, so don’t expect to play the game on those, yet. Performance is horrible though, all the assets are downloaded separately. But don’t you worry, this game is now ✨ remastered! ✨ find every single possible reference and backup/archive of this game online take the existing YouTube video as a reference point in case assets are missing or broken let Claude Code unpack and go through the assets and code let Claude Code play through the actual game on an actual Adobe Flash installation, using prepared scenario scripts put together a spec document read through it myself for confirmation execute on it let Claude Code play through the whole game itself to validate the results in an actual browser play the game myself

0 views
Jim Nielsen 4 days ago

The Fascinating World of Domains

Pete Millspaugh has a lovely article over on WIRED that peers into the world of domains. (If you’re as interested in the esoteric details of domains as I am, follow Pete’s writing at Dot Com Press .) You should just read the article, but here are a few things that stood out to me. Did you know who the registry for is? I didn’t. The registry that owns .com, Verisign, makes a billion and a half dollars every year just by keeping the lights on. To Verisign’s credit, the lights never go out: It reports 100 percent uptime over the past 28 years. It’s a pretty slick business model, watching over a database of words and collecting annual renewal fees. Warren Buffett thought so too, investing in Verisign in 2012, when its stock price was about one-eighth what it is today. Why is it simultaneously surprising and not surprising that the company running makes billions and has 100% uptime over almost three decades? Maybe GitHub should reach out for some advice, lol. Apparently the last time you could buy generic top-level domains (gTLDs) was in 2012. So now that ICANN is providing another window of purchases in 2026 — and nobody knows when another window will open — there’s a lot of interest in capitalizing on these moments for new gTLDs. most organizations [are] extremely secretive about their plans. One applicant from the last round tells me companies were flying around the world, meeting in person to avoid any risk of digital leaks, avoiding Gmail for fear of Google spying. Instead of email or video calls, she flew to London, then to Madrid. “We did it all in person. People got a little weird and scary, super paranoid.” There’s a certain irony to this — people flying around the world to conduct business on owning a piece of the internet because they don’t trust the internet. It appears the future of the internet is to be negotiated offline lol. We haven’t had new gTLDs since 2012. Why do we need more? I can imagine a future where expressive top-level domains become our personal brands, identities on the internet. This is already true in some nerdy corners of the web, like on Bluesky, where your domain is your username. I don’t call my internet friends Neal and Luke, I call them neal.fun and luke.zip. Instead of joining the land rush to grab our username on each new social media site, we’ll carry our domain around the web with us. I’m telling you, domains are the OG handles on the internet . More domains mean more opportunities for individual expression at the root layer of internet infrastructure — that makes sense for a web that’s meant to be worldwide! As developers, we often joke about our addiction to buying domain names for our side projects. But buying a domain name — e.g. — is child’s play compared to buying a generic top-level domain name (gTLD). That’s where the domain whales are. ICANN charges a $227,000 application fee for each string, to recover the cost of running the program. The $36 million or so that Nova will need to cover those fees […] is coming from the personal bank account of Yoni Belousov, a reclusive domain investor (industry jargon: “domainer”) who’s been in the business since he was 14 years old. Next time somebody asks me what I’d do with an insane amount of wealth, I now have the jargon for an answer: “I’d become a domainer.” A few things about domains I didn’t know until I read this: all two-letter extensions are off the table. Those belong to countries, like .co in Colombia and .me in Montenegro and .ai in Anguilla. If you want to run a geographic TLD, like .nyc or .paris, you need approval from that municipality your string can’t be too similar to an existing one (.corn is a no-go; looks too much like .com) certain special strings are off limits, like .icann and .www (wouldn’t that be a trip). would be a baller domain! Just think of the recursion you could do with that on the subdomain level. Reply via: Email · Mastodon · Bluesky

0 views

Picks and Shovels

I've owned picksandshovels.org for the better part of a year. This afternoon, Claude Opus 5.5 built a web game for the site (with a little bit of inspiration from me.) As Claude was working, I interjected a bit of commentary, but pretty much all of the jokes and catastrophes are Claude's doing. Below is the sum total of my prompting to make the game. Happy clicking! Good luck avoiding the apocalypse!

0 views

Type-safe HTML templating in Zig

I’ve done a lot of web development over the years. I started around the year 2000, just after PHP 3.0 was released and started taking over the web world. I’ve used all kinds of approaches for generating HTML: raw PHP, string concatenation in Python, Smarty templates in PHP, Template Toolkit in Perl, and Jinja/Django templates in Python. Then, as the world moved on to SPAs and JavaScript frameworks, I stopped working on frontends. Two years ago, I picked up Zig, and I’d never have imagined I’d be considering web development in such a low-level language. But as I was building my own ecosystem with zio and Dusty , I realized it’s not that far-fetched. I built these libraries for API backends, where the output is JSON or MessagePack, but then I saw that with proper use of arena allocators, even web development is actually manageable, since you don’t need to remember to deallocate all the strings that are typically involved. And with Zig’s comptime, you can build very high-level interfaces without losing the performance benefits. And with the help of htmx or Datastar , you can even build SPAs without touching JavaScript/TypeScript, which I promised myself I’d never do. That said, one thing was still missing: templating. String concatenation was not an option, I didn’t want to go back to the pre-2000 CGI days. I had a few requirements for a templating library: I couldn’t find any solution that would satisfy all these requirements. Then I saw Ziex and I was amazed. It never occurred to me that the JSX approach could be done outside of JavaScript. The developer experience Nurul Huda managed to build in Zig was just unimaginable to me. It didn’t fit my needs directly, because I didn’t want a WASM framework, but the syntax and his approach to integrating Zig code into templates gave me some ideas. Then, after further research, I discovered Templ for Go, and it was pretty obvious to me what I wanted to build. So, let me present zt (I’m not good at naming, sorry) . It’s an adaptation of Templ to Zig. The templates are parsed and transpiled to Zig code during . That means you can import them directly from your app code, but also, perhaps even more importantly, the templates can import your app code. As a result, all parameters can be fully typed. If something can’t be rendered, the Zig compiler will tell you so. The generated code is fairly simple, all it does is write to a . You can write directly to a socket or accumulate the output in a buffer, your choice. Here is what a template looks like: And here is how you would use it from Zig code: If you want to use it inside Dusty to render an HTML page, you just do this: As a side note, the snippet above has a very non-obvious bug in error handling if you use the same pattern somewhere cancellation matters. I’ll probably write a blog post about it, but if you are interested, check out this Ziggit thread . The function in Dusty that wraps the handling solves it. All dynamic values are HTML-escaped by default, both in text and in attributes, and values in URL attributes like or are also checked for dangerous schemes. If you really need to output raw HTML, you have to ask for it explicitly with , so it’s easy to spot in the template. The parser also requires all elements to be properly closed, so you can’t accidentally produce broken markup. It won’t protect you from everything, but it removes the most common sources of XSS. What I like the most is that template errors are just Zig compiler errors. If you make a typo in the template above and write instead of , will tell you: The error points to the generated code, but each line has a comment with the location in the original template. The same applies to the calling side, if you try to pass a string where expects a , it won’t compile. Beyond the basics shown here, you can build reusable components and pass them around as values, and with you can build layouts that wrap other templates, which covers what you’d use template inheritance for in other languages. Control flow is just Zig, so , and work as you’d expect, including payload captures. All of it still compiles down to a sequence of writes, without any allocations. You can have a look at the TODO example in Dusty. It’s a simple htmx-based web app that showcases this library, plus other parts of Dusty that are needed for building a dynamic SPA. One part of the syntax is still open. Block-level control flow is written as plain Zig, following the example of Templ, so a line starting with , or is parsed as code. That means text like “if you forgot your password…” on its own line is a parse error, and you have to wrap it in an element or write it as a string expression. I’m considering switching to , and , similar to Razor or Twirl, which would remove the ambiguity, at the cost of slightly noisier templates. If you have an opinion on this, please leave a comment in this GitHub issue . Although multiple people are already using it, the project is not very mature yet, so I welcome any feedback. You can open a GitHub issue if you find any problems, or ping me on the Zig Discord. It has to be type-safe, with all inputs typed and checked at compile time. I’ve dealt with dynamic languages enough in my life, and I don’t want to deal with runtime template errors anymore. It has to be fast. No allocations, no intermediate state, just write the output to directly. It needs to have safe defaults. I don’t want to deal with XSS anymore, so all inputs have to be escaped by default. It should still feel like writing HTML. I didn’t want a Zig-based DSL I’d have to fight constantly.

0 views
Lea Verou 4 days ago

The best way to use icons in Web UIs

I’ve always had a soft spot for icons 1 . Not only do they add polish to a UI, they can also tangibly improve usability. Familiar icons help users find what they need quickly, since we recognize pictures much faster than we read words. And as a web architect at heart, the current dominant ways we have to include icons on the Web make me sad. While there are many, many different ways to include icons in a Web UI, each with different performance characteristics , by far the most common ones involve adding inline SVG to the HTML. For example, a trash icon might be included like this: Some people use a separate SVG file for sanity and include icons via , but the markup is still fairly clunky (not to mention slow, sans bundlers). All this clunkiness forces people to resort to hiding the icon under layers of abstraction, such as dedicated custom elements like or React components like , but the ugliness still ships under all these layers, and the browser still has to deal with it. Icon fonts did put icons in CSS ( is still how Font Awesome’s pseudo-element mode works), and a lot of their appeal was exactly that. But they came with a long list of issues : large downloads (even with subsetting), fallback glyphs when the font fails to load, screen readers announcing private-use codepoints, user font overrides (e.g. for dyslexia) wiping them out, and text hinting that was never designed for pictures. We threw out the baby with the bathwater: the problem was the font, not the CSS. Many of the attempts to move this to CSS still involve markup. The mask trick that most of them rely on is not new either: Chen Hui Jing covered it in 2021, and Iconify generates mask-based CSS for its entire catalog. But in all of these, which icon to use (and whether to use one at all) is still decided in the markup, via one class per icon; CSS only handles color. The closest I’ve seen is David Bushell’s 2024 post on including icons purely via CSS via generated content + masks, where the icon is picked in CSS, but every selector that wants to support icons needs its own chunk of CSS, and there is no way to override the icon on a case by case basis. I still think it’s superior to inline SVG in HTML, and it baffles me why it isn’t more popular. Per the principles outlined in my user effort article , a good icon system should: How does that translate to an icon system? Per consumers > producers , making icon usage ergonomic is more important than making icon definition ergonomic, but ideally adding a new icon to the icon system should not require much more than: And of course, it still needs to be reasonably performant — the existing success criteria don’t disappear! The dominant ways to include icons today fail to meet at least one of these criteria. Can we do better? CSS is the only web platform language that facilitates reactive aggregation : you declare what applies to what conditions (type of element, interaction state, media query, etc.) and the browser automatically applies the right styles when those conditions are met and cleanly removes them when they are no longer met, without affecting any other conditions that simultaneously apply to the element, and without forcing developers to manage any of these side effects manually. I personally think we are underutilizing this wonderful language by artificially restricting it to styling, but that’s a topic for another article. If we can nail icons via CSS, this gives us tremendous expressive power, with practically no loss of flexibility. Imagine being able to tweak icons based on… Additionally, if icons can be injected or tweaked via CSS, this means we can specify them on pseudo-elements, such as , , or , something no markup solution accommodates. Or even, imagine applying entirely different icon sets to the entire page (or a portion) without having to touch any markup! E.g. a section with a hand-drawn aesthetic could get a hand-drawn icon set, without affecting the rest of the UI. The possibilities are endless. Once you allow yourself to consider that this is possible, you will start seeing use cases everywhere. Including icons as direct s (especially with no wrapping abstraction to manage a shared registry) means there is no way to enforce consistency — anything goes. One page might use a Font Awesome trash icon, another might use a Lucide trash icon. I think the icons themselves should be a type of design token, managed by the design system, that UI components simply use, just like colors and gradients. Managing icons via CSS also allows us to define them alongside other design tokens (e.g. as CSS variables on ), rather than in a separate place. Suppose icons were CSS variables, and we could add an icon to an element simply by setting an custom property, e.g. by doing something like This means we could also make simple things easy via: while maintaining the ability to override the icon on a case by case basis by simply overridding the property. We can even adapt to state reactively: or user interaction, e.g. to communicate both where a link goes (GitHub) and what it is (an external link): And for completely ad hoc standalone icons where adding CSS would be more work than doing it inline in HTML, we can have an class: This makes it strictly more powerful than the markup approaches , with the only exception being that completely inline SVG allows potentially changing the SVG itself in arbitrary ways (e.g. morphing it into another icon or changing it dynamically as the result of user input). For those cases, we’d still need inline SVGs. But how many of your icons fall in that category? The core idea can be summarized as: Icons are inserted via pseudo-elements, which use the icon to mask a square with equal to the icon color. The referencing syntax I’ve settled on is: You could be more elaborate and also define properties like , etc, if you deem them useful! The beauty of this approach is its immense flexibility. Available icons are defined on as CSS variables, e.g.: One-off icons can still be used by setting e.g. instead of , but if most UI references registered icons, they will stand out like a sore thumb and will be easy to spot in a review. Then, to display these as icons, the crux is: For simplicity, I will only discuss / in the rest of this section, but everything applies identically to / and any additional ones. You may be wondering why I’m specifying the size twice instead of . Flex items stretch by default, and a stretched size is definite, so is ignored. Since icons so often live in buttons, and buttons are so often , an explicit is far more robust. Grid happens to be fine ( behaves as for items with an aspect ratio), but flex has no such exception. Unfortunately, you need to repeat the pseudo-element contents for every type of pseudo-element you want to be able to support icons on. Mixins will eventually fix that. As described above, this would apply to all elements, which is far from ideal! We can use a style query ( finally Baseline! 🎉 ) to restrict this to only elements with the property set: We would also need to register as non-inheriting via , otherwise any container with an icon would sprout an icon for every single descendant (including inline formatting like , etc!), which we definitely don’t want. And then just explicitly inherit them in the pseudo-element: Style queries are Baseline 2026 , which sounds quite cutting edge. However, if you look at market share, it is supported in ~93% of users’ browsers worldwide per Can I Use data. While this data under-represents old Chrome Android (it lumps all Chrome Android under its latest version), Chrome shipped style queries in 2023 (in version 111) and Chrome Mobile users do seem to upgrade pretty quickly , so the real number won’t be meaningfully lower. How is this possible? If you sort by date, you will see that all major browsers except Firefox had shipped style queries by 2024. Firefox was the last one to ship them, in May 2026. Now, let’s see the Usage relative chart: Firefox as a whole accounts for 2.28% of worldwide market share. Now, I’m not saying ignore Firefox because of its low market share! That would be a d*ck move, comparable to making UIs inaccessible because screen reader users are a minority. Some things matter more than their raw numbers might indicate , and not excluding Firefox is essential for the Web to remain open, interoperable, and not controlled solely by large companies. That said, for features that have shipped in every major browser, I think it’s defensible to take market share into account. Baseline tiers are a great …baseline, but no compact metric could possibly convey this kind of granularity. Especially for something like this, where things generally still work fine without icons, it’s a plausible strategy to treat icons as a progressive enhancement and just accept not having them in the 7% of browsers that don’t support them. For the cases where icons are crucial, (e.g. icon-only controls) we can use a class (e.g. , , , etc), so that older browsers with no style query support still get them. Then, how much you want to lean in to progressive enhancement depends on how widely you rely on the class vs the style query. You could even add other known selectors to it e.g. inline styles or known selectors with icons: Do note that unrestricted attribute selectors like that can be slow, so use them judiciously. One issue with the class approach is that it hardcodes icon presence , even if you can still tweak the icon itself via CSS custom properties. One way to deal with this is to specify a value that becomes IACVT if the custom property has no value, which would make the entire pseudo-element disappear: This will resolve to a transparent image if is defined, and to → if it is not, which will effectively remove the pseudo-element. And yes, is Baseline Widely Available . It doesn’t remove any of the other properties, so it still cannot compose with other styles, so don’t apply it so broadly it can clash with other elements that may have styles. The styles above are a start, but we can do better: Putting it all together so far, we get something like this If you’re viewing the demo in Chrome or Firefox, it should work as expected. If you’re viewing the demo in Safari, you’ll already know that it’s severely broken. My research on this resulted in filing not one, but two Safari bug reports. The good news is that all have workarounds. The bad news is that these workarounds force us into suboptimal code, and unless we’re willing to ship a different version to Safari, everyone suffers. WebKit bug #301609 was the one that really threw a spanner in the works the most for this technique: The tl;dr is if you use what I wrote above, the icons will not show up in Safari until the user interacts with them in some way (e.g. hover, focus, etc.). Thankfully, I found a CSS workaround: However, since this applies an animation to all and pseudo-elements, ideally we’d want to restrict it a bit, and make it easier to override by wrapping it in a layer. Turns out this seems to magically also fix WebKit bug #320220 , which is also relevant here. At this point our demo works almost perfectly! Can you spot the bug that remains? There are two buttons that change their icon on hover: Default icon and Github to link . The former works, the latter doesn’t. WAT?! So, there is a difference between them: sets on hover, whereas Github to link sets directly, via . And is registered as non-inheriting, which is quite relevant here. Turns out that used to not work at all in Safari until 2023 , and there are still some cases where it reproduces today. The investigation resulted in WebKit bug #325900 being filed. There are a few solutions here of which the only workable one seems to be to register the property as inherited after all, and add a style query that resets it on descendants: It’s a bit more fragile and likely slower, so ideally we’d only ship it to Safari. can only detect features, not bugs, so once more we have to resort to sniffing WebKit. Conveniently, is allowed inside conditional rules, and when a property is registered multiple times, the last registration wins: The layer means any unlayered declaration wins over the reset, even zero-specificity ones like . Putting it all together, here is the final demo, with both workarounds applied: When using icons from SVG files it’s important to remember that any relative URL will resolve relative to the CSS file that uses the icon, not the one it’s defined in . In practice, this forces you to use root-relative URLs (e.g. ), otherwise you’ll have random breakage in any nontrivial project structure. An alternative is to register the icon properties as via and specify their values via : This is also better for other reasons: The obvious downside is DX: there is a lot more boilerplate to define an icon this way. The earlier syntax can be managed by hand, even for many icons. This starts requiring a build step after a dozen or so. Additionally, registered properties are currently global and don’t work in shadow roots , so that may not fit every use case. Another option might be to go through all properties in and register them via JS: An even cleaner option, if you know which stylesheet includes the icon tokens (and it’s same-origin) is to use the CSS OM to actually edit it, so that the declarations are removed once you register the properties: Since the icon is a mask, this technique only works for monochrome icons (varied opacity is fine) — but most icons are monochrome these days anyway. If you really need more, Allegro’s engineers stack masks on the element and both its pseudo-elements, which gets you up to three colors from a single element. But what about full color icons, e.g. emojis? Or textual icons, e.g. …emojis? In theory, the technique can work fine with them, these are actually easier! For full color icons you just set them as background images, no masking required. And for textual icons, you can just set them directly on the property. The only challenge here is branching between these three. But this may be the subject of a future post, as this is already getting quite long. Since the entire pseudo-element is masked, you cannot apply a separate background or border to it. For that, you’d need an actual element (e.g. ), and you can apply the borders, backgrounds, etc to that. Completely arbitrary animation would obviously still require inline elements. But what about predefined animations? A checkmark or X being drawn, a hamburger animating to a close button, etc.? I thought I had figured out a way. And I did get so close! Close enough that the whole saga deserves its own post, so stay tuned 😉 The system above gets us pretty good DX (especially without the Safari bugs!), but some things are still not ideal. First, the masking approach does introduce some limitations it would be nice to be able to get rid of. Then, signal-to-noise ratio could be even better: And while consumers > producers, it would be really nice if adding support for new pseudo-element types did not require such a song-and-dance. A number of upcoming CSS features get us closer to this North Star . If you haven’t heard of the new CSS Linked Parameters spec, it’s the best thing that has happened to CSS icons in a long time. It allows us to pass arbitrary data to any resource that supports it (and yes, SVG is one of them), which means we can customize icons in ways that were previously impossible, such as changing the stroke width, color, or even entirely arbitrary customizations, since SVG also supports style queries. And as of a couple weeks ago, it also supports passing and without any double opt-in from the icon, which means we can use any existing icon library without it having to be updated to utilize them! There are some limitations still, but it is being actively designed, Firefox has shipped an earlier version of the spec , and is one of the top Interop 2027 proposals , so I’m quite hopeful it can make it much easier to use icons in CSS. Keep a close eye on that one! Currently, due to a technicality in how the property is handled, we have to rely on background images to include icons, because otherwise and don’t work. Even Link Parameters by itself won’t change that, it will just allow us to get rid of the masking hack. Thankfully, we (CSS WG) recently resolved on a change that will fix this! (pending compat analysis) is the CSS feature you didn’t know you were desperate for, and deserves an article of its own for its myriad of use cases in design systems. Until I write that, Bramus has a great write-up . But more relevant to icons, once is widely supported, we can construct variable names dynamically, meaning we can use plain identifiers instead of CSS variables, which will make the syntax even cleaner, meaning we’d be able to translate into at the cost of a little complexity on the producer side: Yes, it’s ugly, but it’s also an implementation detail that’s not exposed to icon consumers, so I think the tradeoff is worth it. Combined with expanded , which is getting there with only Safari remaining (Safari TP already supports it), this also unlocks ad hoc icons via a plain attribute: We recently resolved to support registering multiple properties with the same descriptors at once via , this won’t help much here, since we need different initial values. You could of course register multiple properties with the syntax and then also set their actual icons on but now you need to add each icon in two places, so I’d consider it worse than the current expanded syntax. However, another direction we are exploring in the CSS WG is a shorthand form of that would allow more compact registration. For the icon above it would look like this: Currently, we have to repeat a lot of styles between the different pseudo-elements. If we want to also have a fallback class that doesn’t depend on style queries, we need to repeat them four times! With we can just do: And then we can use them all over the place: I published a package that puts together everything from this post, polish and warts included. It contains no icons, just the icon system. You’d just include it and then you can use and in your styles. It also includes the , , and classes. It does not wrap its contents in a layer to give you maximum choice, but I’d recommend importing it in a layer anyway. @nudeui/icons There’s a small chance I may have been the first to use a web font for UI icons , in 2010. I even worked as Product Lead at Font Awesome for a bit. ↩︎ I’m using “components” here in the general sense of a reusable UI element, not in the sense of a framework component or a custom element. E.g. a styled or an would qualify. ↩︎ keep syntax close to the minimum necessary to declare intent , and make simple things easy, complex things possible, and the transition from one to the other smooth (no usability cliffs) High signal-to-noise ratio: The intent to add or override an icon is basically “icon” plus the icon name, and possibly its location (start, end, marker, etc). Anything beyond that is boilerplate. Some boilerplate is unavoidable, but most -based solutions involve unacceptable amounts of boilerplate (which is why we end up abstracting that away). Simple things should be easy: We should be able to define default icons for certain cases without having to explicitly include them at every callsite. E.g. a should automatically get a trash icon, without needing to declare it in the markup in any way, shape, or form, unless we want to override it. The default icon color should follow the local text color (or designated icon color, if different) without any additional song and dance. Complex things should be possible: We should be able to easily override the default icon for a component, either permanently or as a result of various conditions (state changes, user interaction, etc.). Styling the icon should be as easy as applying a CSS property. The minimum is color, but the more extensive styling is possible, the better. No usability cliffs: Overridding an icon, temporarily or permanently, should still not require much more than the bits of information necessary to declare intent. declaring the name of the icon, and providing the SVG path data or a URL to an SVG file Any selector, including interaction pseudo-classes ( , , etc.), e.g. to communicate additional information about the action or adapt to a different background color Media queries ( , dark mode, high contrast, etc), e.g. use different icons in dark mode, add or remove them in print, etc. Container queries Writing mode, e.g. to use a different icon for RTL text Icons are first-class design tokens stored in properties that hold values (embedded or remote) Icons are inserted via pseudo-elements. The icon is applied as a mask to a square with equal to the icon color. The system uses general CSS custom properties like , , and for flexibility and reusability. Style queries + for conditional icon insertion based on these custom properties. Low-level properties: to prepend an icon to element contents (via ) to append an icon to element contents (via ) Optionally, additional properties can redirect to other pseudo-elements, e.g. for higher level abstraction that just means “add an icon to this component”: components 2 can redirect it to any of the lower-level properties on the element itself or a descendant depending on what makes sense for that component. E.g. may set on a but on An empty pseudo-element e.g. or is used to display the icon The pseudo-element is painted as a square with A CSS masks the square in the shape of the icon ( But, but, but …browser support?!? Fear not! Masks are actually Baseline Widely Available nowadays) A CSS property ( or ) is used to specify the icon to display, instead of an ad hoc one like . This means we can set any element’s icon from any place that accepts declaration, including via inline styles Customizable color and size : Rather than hardcoding and , read them from custom properties with those as fallbacks: and (same for ). Since they inherit, you can style every icon in a subtree by setting them on an ancestor, without ever touching the pseudo-element. The prefix keeps them from colliding with the icons themselves, which are also . Preserve in forced colors mode : to keep the mask fill in forced-colors mode. will still follow the forced text color. Don’t get in the way of pointer interactions : so that it doesn’t trap clicks it shouldn’t. Don’t shrink in flex containers : . An empty pseudo-element has a zero minimum size, so in a flex button it is the first thing to shrink when the label is long, and it can shrink all the way to zero. An icon’s size is a design decision, not something layout pressure should negotiate. Vertical centering : I add to center the icons and nudge them a tiny bit upwards (our eyes weigh the space above the icon more than the space below it, so if something is perfectly centered mathematically, it will look a bit low). With a customizable size, that becomes , so that the icon’s center stays put as it grows. Spacing from text : to add a bit of space between the icon and the content ( for ). Make sure to remove it for standalone icons. Accessibility : The pseudo-element has no text, so assistive technology ignores it entirely, which is exactly what we want for an icon next to a label. Icon-only controls still need a name, and we can let the icon provide one via alternative text for generated content : , so that is announced as “Delete”. on the control itself still works, of course. There won’t be hundreds of variables in dev tools for You can even override it temporarily with another icon for a specific context, and reset it wherever via What if could work, instead of ? What if could work, instead of ? (ignoring HTML restrictions around attribute names for a bit) There’s a small chance I may have been the first to use a web font for UI icons , in 2010. I even worked as Product Lead at Font Awesome for a bit. ↩︎ I’m using “components” here in the general sense of a reusable UI element, not in the sense of a framework component or a custom element. E.g. a styled or an would qualify. ↩︎

0 views
Chris Coyier 5 days ago

Multipage

Just noting Mat’s Multipage Version zine rules. I bought both issues right away. It’s weird, it’s funny, it’s a work of art, and you might even learn something. The page that is a spliced version of Marc Andreeson proposing the IMG tag in HTML with all his recent crazy shit about how he “has” zero introspection is, as previously mentioned, a work of art.

0 views
Chris Coyier 6 days ago

Justice for CSS

Fun seeing CSS be a topic in WIRED . Pete Millspaugh shouting out some greats: One programmer recently re-created Doom in CSS . Others have used it to build holographic Pokémon cards and 3D-rendering engines . Cassidy Williams, who competed in this year’s inaugural March MadCSS tournament , built an experimental database-query engine entirely in CSS. I mean, hell yeah. Allow me to just… And I think Adam did it first!

0 views
Simon Willison 6 days ago

A new feature for my blog, built using my voice

I shipped a new feature for my blog today: the Newsletters page, which offers an index of all of the newsletters I've sent out, both my free weekly Substack and my monthly sponsors-only updates. I built the feature almost entirely using my voice, chatting away to my laptop while I cooked dinner. I used the ChatGPT desktop app for this, in the Codex tab, using the voice conversation mode, running against a local development environment. Here's what that looks like: I started the session against my local simonwillisonblog checkout by typing: This gave me a preview of the site that it would be working on, and meant that I could later ask it to show me the new pages so I could visually track its progress. Then I clicked the "Start new voice chat" button - that's not the microphone button, it's the one to the right of it - and set my laptop up in the kitchen so I could talk to it while I cooked. I had a pretty good idea of what I wanted to build, and it's a simple enough Django feature that I was certain the model (in this case GPT-6 Astra High) would be able to do it. A new model, a migration, some view code, templates, and a couple of import functions to populate the database from external sources. Here's an extract of my voice transcript that was captured by Codex: Um, they do not. Um, this is going to be a new type of content. Um, it's not going to show up... Oh, hold on. Yeah, no- I do not want this to show up in my, um, tag pages and date archive pages and... Actually, no, I think... I don't want it on the tag pages. I don't want it on the, um, blog index page. But I think I do want it to show up on the date-based pages. You know, if you navigate to September the 19th, and I sent a newsletter on that page, I think I want that to show up. So... this is- so I think we probably need a new model. The other thing is that I want them searchable, uh the Substack ones are not searchable, because those are actually just copies of other s- on content on my blog. These monthly ones do contain unique content, and spe- and once they're... published, like once they're made public a month after they've gone out, I want them to show up on my search results. Apparently this was clear enough that the model knew what I wanted to build! You can read the full transcript, disfluencies and all, in this Gist . We went on like this for about half an hour (the time it took to cook dinner). The model would reply and occasionally ask clarifying questions, then get to work modifying the code. We got a surprisingly long way entirely by voice: It was almost ready to ship. The catch was the imports: Astra offered to export data from my local copy so I could import that into production, but I wanted it to work like my other import scripts. Since some of the data lived in a private GitHub repository, this would involve creating a new API key, and for that I knew I'd have to sit at the keyboard for a while. Once I had finished cooking and judged it mostly feature-complete, I had Codex create a branch and open a pull request. I reviewed the code in the GitHub PR interface. It was nearly what I needed, except it had chosen to use Git in a subprocess for one of the import scripts. I needed one of the imports to pull from a private Git repository, so I figured the API would be a better bet. I switched to typing and had Codex swap that out for an API-based import instead. You can see the changes I made during the review in the extra commits on the PR . I fixed the import mechanism and made a few tweaks to the display of those public pages. It took an additional half hour of typing-based prompting to get to the point where I was happy to deploy it to production by landing the PR. You can see the end result at the new newsletters index page , or view the page for a previous monthly newsletter . The index page shows my most recent Substack weekly newsletters and GitHub sponsors monthly newsletters mixed together in reverse chronological order. Further down the page are links to my by-year archive pages. GPT-6 Astra designed the page, and then tweaked that design based on my vocal feedback from glancing at the local preview across the kitchen. OpenAI love using voice-driven demos like this one for things like DevDay - and they do work well in that environment. I don't think this is going to be a daily driver for me though. I've written before about how much "work" I get done using ChatGPT voice mode on my phone while walking the dog - mostly research and brainstorming, but occasionally actual development work by having ChatGPT write and test out snippets of code. This feels different. The addition of the visual preview, plus being able to type or paste things in via the keyboard when I need to communicate something that doesn't work vocally, makes this a much more powerful way of interacting with a coding agent. I still switch back to typing once I get down to the details of things though. Being able to paste in examples and error messages, or directly highlight the code or feature that needs changing, remains more efficient than trying to describe it in words. I mainly work from home, which is good because there's no way I'd want to talk to my computer like this in a shared workspace! The killer feature for me is the ability to multi-task. I usually cook with a podcast or TikTok running; now I can actually build stuff instead. You are only seeing the long-form articles from my blog. Subscribe to /atom/everything/ to get all of my posts, or take a look at my other subscription options . A new model and migration to represent imported newsletters in Django, plus Django Admin configuration for that Four working imports: The most recent Substack items via RSS Every other Substack item via their undocumented API, which GPT-6 Astra knew about (it tried directly) and then ran a search to figure out how to paginate it and found this article by Karen Spinner All of my published monthly newsletters from my simonw/monthly-newsletter-archive GitHub repository My most recent private sponsors-only newsletter from a private repository The /newsletters/ and /newsletters/2026/ public archive pages Newsletters showing up on day and month archive pages too, but not on tag pages or my homepage Weekly Substack newsletters link to Substack; archived monthly newsletters have their own pages Integration with my site search engine

0 views
Ahmad Alfy 6 days ago

Iframes that finally fit their content

Chrome 154 lets an iframe grow to the height of its content with one line of CSS without having to measure, without messages, and without resize scripts. But the page inside the iframe has to agree to it. That catch is the most interesting part of this feature, so this article spends some time on it. I have built many checkout pages that use a payment provider’s iframe. The goal was always to have the card form feel like part of the page. The user should not notice that it comes from another website. The iframe never helped with that. It has a fixed height. Make it too tall and you get an empty gap under the form. Make it too short and you get a scrollbar inside the page’s scrollbar. On mobile, that second scrollbar is the worst thing you can show someone who is about to pay. So I kept increasing the height, testing on different phones, and increasing it again. This is a small problem. It should have a small solution. For years it did not. The parent page cannot look inside a cross-origin iframe. It does not know how tall the content is. So the only way was to make both pages talk to each other with JavaScript. Inside the iframe, you measure the content and send the height to the parent: In the parent page, you listen, check who sent the message, and set the height: This looks short, but it hides a lot of problems: That last point did not go away with the new feature. It just moved into the browser. In the parent page, you add one CSS property to the iframe: Inside the iframe, the page opts in with a meta tag in its . It also says which websites are allowed to size it: That is all you need for content that does not change after it loads. The browser measures the content and sizes the iframe. No messages, no listeners, no origin checks in your code. The meta tag must be in the HTML from the start. Adding it later with JavaScript does not work. If the content changes later (an error message appears, a section expands, more comments load), the page inside the iframe asks the browser to measure again: So JavaScript does not disappear completely. The embedded page still calls one function when its content changes. But the hard parts are gone. The browser does all of that now. also accepts , and . For most pages, is the one you want. You can still combine it with limits like . This is the use case I care about most, and it is also the one that depends most on someone else. A payment form changes height all the time. An error appears under the card number. The user switches from card to wallet. A saved card list shows up. With , all of this could look smooth inside your checkout. But you cannot turn it on from your side alone. You control the CSS on your checkout page. The payment provider controls the page inside the iframe. Only they can add the meta tag, list the merchant sites that are allowed, and call when their form changes. So for payments, the real question is not “does Chrome support this?” It is “does my payment provider support this?” Today, most providers either ship their own postMessage script or do nothing. If you work with one, ask them. If you build one, this is a cheap win for every merchant using you. Comment sections, contact forms, newsletter sign-ups and booking widgets all have the same problem. Their height depends on the content: the number of comments, the number of fields, the validation errors. These services already control their embedded page, so adding the meta tag is easy for them. The list fits well here, because they already know which customer sites embed them. I have this exact problem on this website. My contact form is a Wufoo form inside an iframe, and I set its height by hand until it looked right. Each step of a form has a different height. Step one has two fields. Step three has ten. Today, you either reserve space for the tallest step or let the iframe scroll. With this feature, the form calls after each step and the iframe follows. This one does not need any third party. Many apps show HTML email previews, rich text previews, or code demos inside a sandboxed iframe using . Here you write the embedded HTML yourself, so you can add the meta tag directly. This is probably the easiest place to start using the feature today. Browser support. This is Chromium-only for now. Firefox and Safari do not support it yet. Keep a fixed height as the default and switch to content sizing only where it works: Inside the iframe, check before calling the new function. Your old postMessage code can stay as a fallback until support grows: Layout shift. The iframe loads after your page, then grows. Anything below it moves down. If the iframe is in the first screen, this can hurt your Core Web Vitals. A sensible reduces the jump. Do not use without a reason. Letting any site read your page’s height can leak information. For example, a page that is taller when the user is logged in tells the parent something about that user. List only the sites that need it. This works together with the CSP rule, which controls who can embed you at all. For years, a simple layout need, “make this box as tall as its content”, required two scripts on two websites that had to agree on a message format. Now it is one CSS property, one meta tag, and one function call when things change. The browser side is ready in Chrome. The rest depends on the people who build the pages we embed. If you run a payment gateway, a comments service, or any widget that lives inside an iframe, add the meta tag. Your users’ checkouts and pages will feel like they were built as one piece. I will come back to payment providers in our region specifically in a follow-up post. Width changes height. On a small screen, text wraps more and the content gets taller. Every resize or phone rotation needs a new measurement. Content arrives late. Fonts, images and error messages load after the first measurement. The height is wrong until someone measures again. Dynamic content. If the page inside the iframe shows or hides elements after the initial load, the height changes and needs to be measured again. More than one iframe. If the page has several, you need IDs in every message to know which one to resize. Both sides must cooperate. If the third party does not send its height, there is nothing you can do. You go back to guessing a fixed height. Responsive iframes in Chrome 154 , Chrome for Developers New in Chrome 154 , Chrome for Developers

0 views
Unsung 1 weeks ago

Deeper dive: Keyboard differences between Windows and Macs

Over the years, I learned about many gotchas and strange differences between keyboard handling on Mac and Windows – pertinent especially to web apps, which use the same codebase to cater to both. I thought it might be helpful to someone if I compile them all in one place. This post is meant to be a reference, and there aren’t any cute or riveting stories hiding inside – if this seems boring to you, feel free to skip to the next one! What Windows calls Backspace, Mac calls Delete. What Windows calls Delete, Macs call Forward Delete. (This means saying “Delete” without specifying the platform might actually be confusing.) What Windows calls ⏎ Enter, Mac calls ⏎ Return. However, Macs also have an ⌤ Enter, although only on a numeric keypad (previously, it was even there on laptops !). On keyboards without the physical Enter key, you can simulate it via Fn+Return. In most Mac software, Enter and Return do the same thing. There are a few exceptions – for example, Photoshop enters a new line on Return but commits on Enter, and some classic pro apps like Cubase or Pro Tools do different things, too – but it seems to be a dying tradition. (If you are curious about the history of Return and Enter, I wrote about it once .) Windows customarily calls the secondary key Numpad Enter. I don’t believe Fn+Enter works to simulate it. Generally, third-party keyboards use Windows verbiage – so, Backspace and Enter. If a keyboard offers Mac conventions at all, they usually only extend to modifier keys. ⌃ Control on Windows is the equivalent to ⌘ Command on a Mac. (Paste, for example, is ⌃V on Windows and ⌘V on a Mac.) But, confusingly, Apple devices still have a Control key, too. This was originally meant for terminal applications, but these days many GUI apps use it as an extra modifier key. This means that for apps, Windows devices offer Ctrl, Alt, and Shift – and Macs offer ⌘ Command, ⌥ Option, ⌃ Control, and ⇧ Shift. That’s one more modifier key, and thus more space to breathe. (We’re not counting the Windows key or the 🌐 Globe/Fn key since those are technically reserved by the operating system.) Some keyboards offer extra key caps you can swap to match the platform, for example: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/1.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/1.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/2.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/2.1600w.avif" type="image/avif"> Others cover all the bases on fixed key caps, in an awkward way: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/3.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/3.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/4.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/4.1600w.avif" type="image/avif"> Many stick with Windows-only legends. Apple devices rely more on symbols on their keys and in their menus, although they don’t do so consistently. Here are all of them: Actually, I lied about the last four. On modern Apple keyboards, they are: Reusing the regular arrows for Page Up and Down is one of a few perplexing decisions from Apple’s keyboard designers. The arrow key symbols look like this – ◀▶▲▼ – but only on Apple keyboards. Here is an older and a newer Apple keyboard showing what happened: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/5.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/5.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/6.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/6.1600w.avif" type="image/avif"> (Luckily, the confusing dual arrow key situation only happens on less popular, full-size keyboards.) Historically, Apple keyboards used symbols more on non-US keyboards, but starting with the 2026 models, they unified when they show symbols and when they show symbols and legends, across all keyboards. (The only key with just a text legend is Esc, making the appearance of ⎋ in menus extra puzzling.) Windows keyboards typically use words – this is why in tight quarters you sometimes see shortenings like Ctrl, Bkspc, PrtSc, Del, PgUp, Win, and so on. (I don’t think Apple ever abbreviates their legends with the exception of Esc for Escape.) In some countries, the legends are translated – as an example, in Germany, Ctrl sometimes appears as Strg. The symbols that crossed over to Windows side are: I have not seen any other popular symbols on the Windows side of the aisle, and I am not even sure if the above would be widely understood. But here’s an example: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/7.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/7.1600w.avif" type="image/avif"> ( I wrote a bit more about Mac symbols before , and also about the rare Canadian symbols .) In menus and other places, Windows joins the key combinations/​shortcuts with a plus, but Apple just glues them together: Here is the same Chrome menu on Windows and on macOS: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/8.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/8.1600w.avif" type="image/avif"> = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/9.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/9.1600w.avif" type="image/avif"> (In other words, you’d never say “⌃V is Paste on Windows” like I did above.) Both Windows and Macs have function keys. On Windows, traditionally those were claimed by the operating system or the apps as shortcuts. Here are some examples of well-known function key assignments: On Macs, traditionally the apps didn’t reach for function keys, as those were reserved solely for the users to do stuff with. (However, some combination of ⌃ and function keys are used by the operating system for accessibility options, and I occasionally see apps use function keys these days.) Windows keyboards top off at F12, but some Mac keyboards reuse the three special PC keys, and even take over the unnecessary Num Lock/​Caps Lock/​Scroll Lock island, and end up going up to F19: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/10.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/10.1600w.avif" type="image/avif"> Access to extra characters In text fields, Apple has a system where pressing ⌥ with printing keys outputs more characters, for example ⌥Q outputs œ, and ⌥7 outputs a ¶ pilcrow. Additionally, ⇧ works in this context, so for example ⌥⇧Q outputs Œ, and ⌥⇧7 outputs a ‡ double dagger. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/11.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/11.1600w.avif" type="image/avif"> Note that not only letters, but basically all printing keys have secret ⌥ and ⌥⇧ assignments. Also, ⌥ assignments vary per location! The above was U.S. English, here’s Polish with a lot of differences: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/12.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/12.1600w.avif" type="image/avif"> This means it’s best to avoid ⌥-based shortcuts in text fields, since they might conflict with some important character. By the way, while the above two are just mock-ups, on some physical keyboards (here: British English), some of the important ⌥ invocations are actually printed on keys: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/13.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/13.1600w.avif" type="image/avif"> Windows doesn’t have the above feature. However, Windows has an alternative feature where typing Alt+numpad keys allows to enter any character by its code. (For example, Alt+0128 outputs €. Num Lock has to be enabled. I don’t think it’s possible to do it without a numeric keypad present.) Mac has a version of this feature, but it requires adding Unicode Hex Input keyboard and switching to it beforehand. Then, pressing ⌥20AC outputs €. While Mac modifier keys are completely symmetrical, Windows makes an exception for Alt. On many non-US keyboards, right Alt is also known as AltGr , and does something similar to ⌥ on a Mac: it outputs letters when pressed in combination with printing keys. For example, on Polish keyboards AltGr+A = ą, AltGr+C = ć, AltGr+Shift+A = Ą, and so on with 15 more combinations. Many other keyboards do similar things. The way it differs from ⌥ on a Mac is that these are usually reserved for core letters and punctuation necessary for each language, rather than the typographical smorgasbord that Apple provides. For legacy reasons, and also for keyboards that do not have a physical AltGr key, you can also invoke all these using Ctrl+Alt combinations instead (so, Ctrl+Alt+A = ą). This means that just as you have to be careful about ⌥-based shortcuts in text fields on a Mac, so you should be of Ctrl+Alt-based shortcuts on Windows . Just like on Macs, on some keyboards, selected AltGr options will be printed in the corners or fronts of keys: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/14.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/14.1600w.avif" type="image/avif"> Text fields Text fields in Mac OS apps and web browsers/​websites use some of the standard Unix/​Linux shortcuts based on the ⌃ Control key: You can combine many of the above with holding ⇧ to extend the selection. A small group of vocal users love these. Windows still supports Ctrl+Insert for copy and Shift+Insert for paste. I am not sure if those are being used. On a Mac, in simple input fields, ↑ and ↓ jumps to the beginning and end (same as ⌘←→). This often conflicts with command line history, autocomplete pop-ups, and so on. Windows doesn’t have this convention, and Home and End serve this purpose instead. Macs support the iPhone-inspired convention of holding a key to show related accented characters, instead of triggering auto-repeat. Windows doesn’t have this feature. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/15.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/15.1600w.avif" type="image/avif"> Differing shortcut conventions worth knowing about On a Mac, redo is typically ⌘⇧Z. On Windows, it’s typically Ctrl+Y. On a Mac, refresh (in browsers, etc.) is typically ⌘R. On Windows, it’s typically F5, although some browsers now support Ctrl+R, too, presumably since function keys are harder to access than they used to be. Windows’s eponymous ⊞ Windows key is reserved solely for the use of the operating system, and so is Mac’s 🌐 Fn/​Globe key. (Although I am not 100% sure of that as I found one place you can create 🌐 shortcuts as a user – I’m just not certain if it’s intentional.) However, each platform also has a lot of shortcut combinations that are effectively unavailable, for example ⌘⇥ and ⌘M on a Mac, or Alt+Tab and Ctrl+Shift+Escape on Windows. These official lists can help: If you’re a web app, you will compete for shortcuts with the operating system (like any app would), but also with the browser itself. You can typically take over shortcuts like ⌘S or ⌘P, but depending on the browser or the platform, some might be sacred and unavailable. No Mac browser will allow a website to claim ⌘Q, ⌘W, or ⌘T. Safari won’t allow a web app to override ⌘R. Arc browser won’t allow to override ⌘⇧C. (This is not a complete list.) Tabbing and Shift tabbing is customarily used to jump between UI elements, but it behaves slightly differently in native apps. On Windows, tabbing jumps through all elements: On Mac, Tab jumps only to elements that require keyboard to operate (such as input fields). You can toggle a System Settings preference and ask macOS to mimic Windows behaviour – see the last toggle below – but it’s not supported well everywhere. = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/18.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/18.1600w.avif" type="image/avif"> PgUp and PgDn work differently: Similarly, Home and End work differently: On both platforms, Fn+↑↓ does PgUp/​PgDn, and Fn+←→ does Home/End. (Do you see how confusing it is to say that given that ↑↓ already mean PgUp/Dn on a Mac?) Windows has a tradition of enabling access to menus and visible controls by pressing Alt and letter keys. This has evolved over time and is not as consistent as it used to be, but it might be worth knowing about. On a 100-plus-key keyboard, Windows might have: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/19.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/19.1600w.avif" type="image/avif"> Macs have: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/20.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/20.1600w.avif" type="image/avif"> Macs never had arrow keys on a numeric keypad nor a Num Lock key to enable it. (I’m breaking my promise! Here’s a fun bug story about Num Lock .) In a strange twist of fate, it’s not only third-party keyboards that favor Windows legends. Some of Apple’s keyboards in between 1980s and 2000s showed PC legends, too! (This was to court PC compatibility of then-beleaguered Macs.) Here’s the classic Apple Extended Keyboard, showing legends for Insert, Delete (naming it Del to avoid confusion with its own), Print Screen, Scroll Lock, Pause, Num Lock, and Alt: = 2x) and (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/21.2096w.avif" type="image/avif"> = 3x) or (width >= 700px)" srcset="https://unsung.aresluna.org/_media/deeper-dive-keyboard-differences-between-windows-and-macs/21.1600w.avif" type="image/avif"> (Did I miss anything or make a mistake? Let me know !) ⎋ Esc (not printed on keyboards, for some reason) ⌦ Forward Delete ≣ Contextual Menu (only on full-size keyboards) ⇞ Page Up (only on full-size keyboards) ⇟ Page Down (only on full-size keyboards) ↖ Home (only on full-size keyboards) ↘ End (only on full-size keyboards) ↓ Page Down ⇧ for Shift ⇪ or 🔒 or a similar symbol for Caps Lock (on non-US keyboards) ⏎ for Enter – note the same arrow as Mac’s ⏎ Return ← for Backspace – note a different arrow than Mac’s ⌫ Delete ⇥ for Tab (you can also sometimes see ⭾, which is a symbol representing Tab and Reverse Tab together; Reverse Tab used to be a separate key on some 1970s terminals) ⊞ for Windows key – the style of the logo will be different depending on the age of the keyboard, roughly matching the Windows logo at the time; some keyboards also use a more abstract shape, or call the key Start or System instead of Windows ≣ for contextual menu key (a.k.a. Application Key) – just as Apple added that key on its large keyboards, Microsoft started removing it in favor of emoji key , Office key , and then Copilot key ⌃ for Control (especially in nerdy contexts) Windows: Shift+A, Ctrl+Shift+G, Ctrl+F11, Alt+Enter Mac: ⇧A, ⌃⇧G, ⌘F11, ⌥⏎ Alt+F4 – close the app F11 – maximize window F12 – dev tools in browsers ⌃A – move to the beginning of the line ⌃E – move to the end of the line ⌃F – move to the right, or forwards (hold ⌥ to jump through words) ⌃B – move to the left, or backwards (hold ⌥ to jump through words) ⌃N – move down or to the next command ⌃P – move up or to the previous command ⌃L – scroll the window so that the text cursor is in the vertical middle ⌃H – delete (backspace) ⌃D – forward delete ⌃K – delete (kill) to the end of the line ⌃T – swap (transpose) the adjacent characters ⌃O – insert new line, but (contrary to Return) do not move the cursor there Mac keyboard shortcuts Keyboard shortcuts in Windows On Windows, they move the text cursor a screen up or down. On a Mac, they scroll the view up and down, but they do not move the text cursor if it’s present (so, they are more an equivalent of clicking on the scrollbar chute). On Windows, they scroll the contents (and move the cursor if present) to the top or the bottom of a view, or move the cursor to the beginning or the end of an input field. On a Mac, in views they scroll to the beginning or end without moving the cursor. In input fields, Home/End do nothing, but you can use ⌘←→ to accomplish the same. Insert – still used in some contexts for overtyping Print Screen – today taken over by screenshotting Num Lock and Scroll Lock Pause/​Break Help – rarely used, and now abandoned in favor of… ≣ Contextual Menu – shows the same menu as right click would ⌧ Clear – a deterministic backspace , these days seldomly different than the actual Delete key

0 views
Jim Nielsen 1 weeks ago

“Getting off the Modernization Treadmill”

My notes from this talk by Alexander Petros at Big Sky DevCon 2026 . Alex starts by noting how “modernize” used to mean something along the lines of “update this thing that was made before I was born”. But now “modernize” means something more like “update this thing from 5-10 years ago” (hence the framing of the talk, the “modernization treadmill”). Using a real-world example of an incredibly slow website that was required to access state-sponsored programs for welfare, Alex points out the disparity in conditions between those of us who make software and those who have to use them: The people who develop these websites are usually doing so on high-powered internet connections and high-powered devices, but they're not using them in the conditions that the people who most need those benefits are going to be. Then he shows a Reddit thread where somebody essentially posted, “I’m having problems with this website. I’ve been waiting for months for my application to go through. Any suggestions?” And one Reddit user responded, “The best thing you can do is go into the physical office, get a case worker, and your problems will be solved within the hour.” I guess we've come full circle now. It used to be: “Don’t talk to anybody. It’s faster and more convenient to use the website!” But now it’s: “Don’t use the website. It’s faster and more convenient to talk to somebody!” Have we failed at making websites? And is our failure, at least in part, rooted in the fact that we don’t leverage the basic tools for making websites: HTML, CSS, and (in a distant third) JavaScript? Alex goes on to argue that the technologies of the web have an ideological bent and, if used as designed, can solve so many of the performance, accessibility, and usability issues that plague so many websites. The grain of the web’s technologies are rooted in these values: Which means if you use them as intended, they are optimized to deliver outcomes rooted in those same values. So if you like those values and you want those outcomes, use the platform. Take HTML, for example. Here’s Alex: HTML does [performance improvements] for you for free. If you've coded your website in a proper, semantical, structure HTML style, it will just get better over time at zero cost to the people who built that website HTML is your friend. HTML won’t give you up or let you down . HTML will make it difficult for you to make a bad website. Write it in to the requirements of the project you’re doing that it work without JavaScript. Not necessarily that it doesn’t have any JavaScript, but just that the core functionality of the website can happen without JavaScript. If you do this […] you will find that it’s very hard to deliver a bad web page because the structure that HTML requires is one that fundamentally is good for the user, performant, and cost effective. Technologies are imbued with culture, which influences what you do and how you do it. If you can align your ideological beliefs with your technological choices, you might end up with an outcome that aligns with your values — who would’ve thought, eh? A lot of modern software developers come from websites like Facebook, they come from big tech companies [who] fundamentally have a different set of priorities. Their job is to keep you on the website as long as possible so that you consume more ads. But that’s the opposite set of requirements and priorities that the government needs to be doing, which is to build something that is clean, quick, efficient, and gets you in and out as fast as possible. So [I tell people] that the technology they use comes from [an] ideological place. But there are different ideological places that produce different technological results and if we start from those through lines then we can produce services that help people who need them. The ideological principles of the web are well established : users over everything else. If you use HTML as much as possible, you’ll make something that’s as user-friendly as possible on the web. Reply via: Email · Mastodon · Bluesky User-friendly Backwards- and forwards-compatibility Long-term viability Universal accessibility

0 views
Andre Garzia 1 weeks ago

BlogCat got a new Youtube subscriptions page

Made a really nice feature today after a friend requested it, added a new page to BlogCat that will list all the Youtube Channels you subscribed as a thumbnail grid, much like a non-algorithmic version of their home page. That means that you can use BlogCat to subscribe to channels, use the new page to view latest videos from the channels you subscribed, and use an alternative front-end to view the said videos such as invidious or nadeko. By combining these features, one doesn’t even need to have a Youtube account. It is quite neat and it skips algorithms and so on.

0 views
David Bushell 1 weeks ago

A sustainable web career, for when all this blows over

For better or worse the web industry is going through a bit of a phase. The reasons are largely irrational. People still need the web, nothing has changed there. Regardless, the financials of this business are a struggle. Longterm career prospects are looking dicey. Because I openly reject the driving force intent on destroying my profession, and ruffle a few feathers doing so, I often get asked privately for advice from like-minded peers. I can only offer an uninspired but sensible reply: don’t quit a paying job without a fallback. Go to the Winchester, have a nice cold pint, and wait for all of this to blow over. I’m confident the situation will improve. Before it does, what can we focus on to accelerate past the intellectual slump, and better position ourselves once things calm down? For a sustainable web career, where better to look than critical skills in desperately short supply? My focus is on front-end development, but these areas of knowledge are relevant to anyone in the business of making websites. Accessibility has always been a foundation of web development but it’s never been more critical for everyone to champion it. Understand why accessibility is for everyone. Learn how to talk about accessibility in respect to real needs and practical implementation. Accessibility has unfortunately become a virtue signal for certain tech groups. (I’m told LinkedIn is rife with misinformation.) Accessibility is not a feature that can be tacked on to a website like garnish. Accessibility issues can’t be fixed with an automated process at the end. Web professionals must be able to counter this mindset by respecting accessibility in all decisions from day one. Learn and adopt the guidelines as your baseline. Speak to and test with real people. Defer to specialists who are eager for you to understand the realities. CSS is the most vibrant and evolving of the front-end standards. To architecture a good stylesheet takes deep understanding of the language features. Newer features like cascade layers and selectors that reduce specificity make this much easier. CSS has always been equipped to handle well organised styles, but developers who refuse to learn and respect the language have sought to push complexity elsewhere, using simplified abstractions or “CSS-in-JS” solutions. These are inherently limiting, lead to poor performance, and don’t actually solve the problems they claim. CSS should be hard and learning it will give you the ability to express creativity beyond cookie cutter web design. CSS skills will be highly desirable as more websites wish to stand out against the convergence of a generated aesthetic. Communication is a “soft skill” in short supply (for obvious reasons). It’s a great skill if you wish to stand out as an expert, or simply be heard amongst the noise. Learn brevity and focus on important points. Don’t be afraid to ask questions. Address concerns tactfully and early before they escalate. Don’t point fingers, but “cover your ass” — everyone on a project should be working towards the same goal, but some may be misguided in their approach. Remain positive and don’t meet negativity head-on. If you can communicate well you’ll be highly respected in your role. You probably weren’t expecting this one, but here we are. The luxury of not “getting political” has abated. Far-right political ideology is on the rise and dormant hatred is waking up in tech. The epicentre of fash-tech is Musk’s “X” with people like David Heinemeier Hansson spewing racism and abusing authority in communities to push an agenda, and Guillermo Rauch taking a selfie with a war criminal . Large tech giants like Digital Ocean are funding this power grab . Be wary of those denying this threat. If you want to avoid being pushed away from this industry, recognise and reject fascism before it comes for you. Don’t stay silent. I’ve covered topics that’ll see us well for the future, but what should we forget? Facebook’s experiment turned cargo cult is a legacy framework that still lingers, but there’s no reason to learn it today. React has entrenched itself as a lingua franca of code extruders. React code is generated faster than any human can possibly read it. Suffice it to say that despite stale job vacancies still demanding experience, React is not worth investing time. The days of high-paying React development are numbered. GitHub is now a liability. For private repositories use self-hosted git forges. I’d recommend Forgejo . One of the many Tailscale-like services is an easy way to gate remote access. Don’t make stuff public for the dead internet to attack! For CI/CD go local too, or use independent services not tied to tech giants. Take the time to learn basic commands. A little technical and infrastructure knowledge goes a long way. These people are handsome, charismatic, highly personable. I’m talking about: developer relations, youtubers, start-up founders, etc. When the tech industry met us halfway, influencers were entertaining and a good chinwag at after parties. Now the game has changed and we should not allow false narratives to dominate and dictate a closed-web future. Normal people still use the web. Incredibly few can afford to pay for the novelties that influencers peddle. Their attention economy is no longer our concern. So that’s my focus for a sustainable web career, when all this blows over. Remember that above all else: the web is a human creation for human needs. Those needs are not going anywhere. Drop the dead weight accumulated in times of prosperity. Go back to basics and position yourself well for when professional demand returns. Thanks for reading! Follow me on Mastodon and Bluesky . Subscribe to my Blog and Notes or Combined feeds.

0 views
Langur Monkey 1 weeks ago

JPEG XL finally lands in Chrome!

Today, I was browsing Hacker News , when a particular item caught my eye: Hacker News post with the Chrome JPEG XL announcement . I opened it promptly and, indeed, it was not a prank. Finally, after years and years of bull**** from the Chrome team, they are shipping it. They are shipping a JPEG XL decoder. For those of you who don’t know, JPEG XL is a new image codec that includes most of, if not all, the features we’d want in the image codec of the future: This is awesome news for the codec . Whether we like it or not, Chrome is the dominant web browser, with ~66.5% of the market share , very far from its competitors (Safari, Edge, and Firefox, in that order). Now, I don’t use Chrome at all, but I still think that this was just the final piece of the puzzle needed to help the format go mainstream. So, what finally pushed them over the edge? If you read their announcement , they cite “consistent feedback and requests from web developers” and its massive popularity in the Interop 2026 project. Translated from corporate PR-speak: the community simply refused to let it go. Web developers, photographers, and open-source advocates kept pushing, complaining on bug trackers, and demanding a truly superior image format instead of settling for Google’s own WebP or the heavily pushed AVIF. The technical excuse the Chrome team used for years was that a C++ decoder was too much of an attack surface to run safely in the browser. Well, it has now been elegantly sidestepped. To bring JPEG XL to Chrome 155, they have integrated , a pure Rust reimplementation of the decoder. This tackles the memory safety issues head-on, eliminating the risk of out-of-bounds reads and use-after-free bugs of other decoders. And to make sure it doesn’t run sluggishly, they built a SIMD abstraction layer ( ) to maximize hardware performance without compromising Rust’s safety guarantees. This is a massive victory. Not just for JPEG XL, but for the open web. As I demonstrated in my comparison back in 2023 ,JXL has significant advantages over older formats and, in many cases, over AVIF as well, especially for high-fidelity photography, lossless compression, and progressive decoding. The fact that it allows lossless transcoding of existing JPEG files is of special importance. It means that we can finally upgrade our backlog of old images without losing a single pixel of quality, while saving a big chunk of disk space and/or bandwidth in the process. With Firefox adding it to Labs earlier this year, and Chrome finally capitulating, Safari is left as the major outlier with only partial support. The dark days of “Google kills JPEG XL” are officially over. It’s time to start converting your image libraries, updating your tags, and serving . The future of (high-quality) web imagery is finally here, and I’ll be ready for it. File size reduction by \(~20-60\%\) w.r.t JPEG. Lossless JPEG transcoding. Progressive decoding. Wide gamut, HDR and 32-bit support. Animations and transparency (alpha channel). Shines with high-fidelity photographic images. Fast-ish encoding and decoding. Royalty-free and FOSS. Support for super high-resolution images, of up to 1 terapixels ( \(2^{30}-1\) pixels per side).

0 views
Evan Schwartz 1 weeks ago

Scour - September Update

Hi friends, In September, Scour scoured 1.2 million articles (up from ~880,000 in August) from 28,568 feeds . Also, welcome to the 116 new users who signed up since my last product update email! Here's what's new in the product: You can now find all of your saved, loved, and liked posts, as well as your full reading history, in the Library section. Also, if you click Read on Scour for any article, that page now has tabs for the article's content, other posts that it cites and that cite it, and the feeds it was found in. Here's an example for a widely cited post. Scour now tries to determine the level of expertise each post assumes and infers the level of expertise you have per topic (based on the wording of your interest is and the types of articles you click on or like). At least for me, this means I'm seeing far fewer beginner Rust questions from Reddit showing up in my feed. (For those in tech, this is powered by Jev.) Scour's Search will now show you results for feeds and authors, in addition to posts that match your query. Relatedly, you can now follow individual authors as sources and Scour will try to show you their posts from any website they publish on. Scour now detects and hides more junk, ranging from sales pages and SEO garbage to uninformative link roundups and low-value discussion threads. You should see more high-quality content in your feeds. By my current count, about 1 in 10 posts being shown before was some kind of junk that Scour now hides. I continue to obsess over making Scour feel super fast and snappy. In September the slowest feed loads got about 7x faster (p99 went from 2.1 seconds to 282 milliseconds) and the median feed load time got 2x faster (p50 went from 90 ms to 40 ms). This is also while ranking about 1.4x as much content as the month before. Unfortunately Reddit announced their plan to turn off RSS feeds on November 13th . This is how Scour checks which discussions are happening on Reddit and finds articles posted on different subreddits. After November 13th you'll no longer see links to the Reddit discussions from Scour 😢. Here are some of my favorite articles I found on Scour in September: Happy Scouring! - Evan The biggest news in the tech / AI world was the release of TypeSafe's Jev model . These were some of the related articles that I found interesting: The Latent Space interview with TypeSafe's CEO, Jev: System One models for Prod, not God — with Diogo Almeida, CEO, TypeSafe AI . Fingerprints of Jev and Jev's Architecture Unmasked were interesting black box investigations into Jev's base model using the tokenizer and other externally visible properties. Sixteen Models Walk Into a Storefront gives a very nice breakdown of techniques that can be used to manipulate LLMs' assessments of which products to buy and how much to pay for products. Logo Design Trends in 2027 Favor Marks Someone Can Prove They Made . In the age of AI-generated glossy slop, this is no surprise, but it's a nice write-up. The engineering behind the US Strategic Petroleum Reserve . Quite random but an interesting read. I Judged My Mum for Overusing AI, Until I Caught Myself Doing Worse . I continue to appreciate Sid's commentary on the age of AI. This is very relatable.

0 views
Kev Quirk 1 weeks ago

2026-10-06 09:47: Been trying a new email client, Hylki, after reading about it on OMG! Ubuntu! Really...

Been trying a new email client, Hylki, after reading about it on OMG! Ubuntu! Really enjoying it. It's modern and has a tonne of features. https://hylki.app/ Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️ You can reply to this post by email , or leave a comment .

0 views