Tags: frontend

2571

sparkline

Friday, October 16th, 2026

Ranking proposals for Interop 2027

The Firefox team are asking us to weigh in on proposals for Interop 2027—what features should browsers be concentrating on implementing or improving.

Here are my top five:

  1. Web app installation via <install> and navigator.install(). Prompts the user to install a progressive web app.
  2. Speculation Rules API. Hints to the browser to proactively download pages in the background so they appear instantly when the user navigates to them.
  3. CSS var() in size container queries. Such as @container (width >= var(--min-width)).
  4. CSS flex-wrap: balance. Distributes items in a multi-line flex container so each line has about the same number of items.
  5. Interest invokers. The interestfor attribute triggers actions on a target element when the user shows interest, such as via hover, focus, or long-press.

Those are very much in order of priority. Imagine them following a Pareto distribution; the top 20% (in other words, the first one) is 80% of my priority.

But other people have other priorities: Stu, Eric, Ana, Tyler, Paweł, Declan, Sara, and Cyd, for example.

There’s a lot of love for styleable select in there—can’t argue with that.

Get in there and rank your priorities. Then share them.

Introducing the Accessible Components Library - TetraLogical

A great little collection of accessible interactive components: dialogs, tabs, accordions, stuff like that.

Best of all, the components come with documentation: what problem is solves; when to use it; when not to use it; where to use it, and more.

Tuesday, October 6th, 2026

Tuesday, September 29th, 2026

Justice for CSS | WIRED

In defense of the girliest programming language.

I was pleasantly surprised to find a blog post of mine quoted in this article.

Friday, September 25th, 2026

Monday, September 14th, 2026

Stalling installing

I’m an invited expert at the World Wide Web Consortium.

That sounds impressive, but it isn’t. Anyone can become an invited expert. The fact that I am now one proves it. You apply to be an invited expert and once that application is approved, you’re in. So you too could and probably should be an invited expert to a working group at the W3C.

I was strongly encouraged to become an invited expert in the web applications working group after weighing in on the matter of installable web apps (or progressive web apps or whatever).

Last week I had my first call but it wasn’t with the web apps working group, it was with the technical architecture group, a meta-group that helps the other groups if there’s a big-picture sticking point.

There’s a big-picture sticking point with installing web apps.

While most of the participants (read: browser makers) would like to spend their time deciding the details of what API to implement in order to support installable web apps, Webkit is rejecting the very premise of that work.

On last week’s call, Webkit outlined their position: there shouldn’t be a way for developers to allow users to install the current website. Leave it to the browser, they say. Also, is this even something that users want? Looking at the stats, it certainly doesn’t seem like it.

That would be a reasonable position if there were already a usable way to install web apps. But there isn’t. It’s technically possible to add a website to your iPhone’s home screen. In practical terms, it’s a convoluted usability nightmare.

(It’s hard to avoid veering into conspiracy theory territory and seeing this as some kind of malicious compliance. Especially when you compare it to how native apps are shoved in your face thanks to “smart app banners” better known as dickovers.)

So Webkit’s stance would make total sense if there were a reasonable way for users of Mobile Safari to install web apps already. But there isn’t.

Last week’s call was quite illuminating. It showed some incredible cognitive dissonance in the Webkit position. Let me explain…

On the one hand, installing web apps is kind of like bookmarking, they say. That’s true. We don’t have an API for bookmarking so why should we have an API for installing web apps?

That would be a fair point if the user interface for bookmarking and installing were in any way comparable. But bookmarking is literally front and centre of the user’s experience of a browser, backed up by decades of convention. Meanwhile the option to install a web app is buried five levels deep behind a “share” icon.

Also: we’re not talking about an API for installing web apps. We’re talking about an API for initialising the flow for installing web apps—the very same flow that’s triggered from that buried menu item. And that flow begins with a prominent option to cancel. So let’s not have any scaremongering about users somehow being tricked into adding web apps to their home screen.

Which brings me to the other point…

Webkit are concerned about allowing installed web apps getting access to more powerful APIs. They’re quite right not to want that! A web app launched from the home screen shouldn’t have any special privileges. If it wants access to say, geolocation, the user needs to grant permision just the same as if the page were in the browser.

Why, oh, why then did Apple limit push notifications to installed web apps?

It’s not like other browsers haven’t managed to implement permission-based APIs like push notifications. But apparently limiting notifications to installed web apps was the only way that Apple could think of implementing this API safely.

You see the contradiction, right?

On the one hand, Webkit is saying that installing web apps is like bookmarking. No big deal.

On the other hand, Webkit is saying that installing web apps grants special privileges. A huge deal!

Which is it?

It’s almost as if Webkit aren’t actually participating in good faith but rather have already made up their mind to drag their heels when it comes to any kind of progress on this topic.

Anyway…

On last week’s call, I was supposedly representing the interests of developers. No pressure!

I can’t make any claim to represent all developers, but I like to think I’m fairly representative of a typical developer who’s quite fond of the World Wide Web. So in my allotted ten minutes of speaking time, I said:

  • Developers would love a way to initiate the installation flow. The alternative is to provide browser-specific instructions—always a bad sign.
  • If browsers provided a prominent usable way to initiate the installation flow, this wouldn’t be such an urgent need.
  • Users should have the option to install web apps just like they have the option to install native apps. Technically both options are available, but practically the scales are tipped very, very heavily towards native apps.
  • Native apps don’t have the same security model as web apps, allowing them much greater access to user data. If security and privacy are values that the W3C thinks are important for users, they should do everything in their collective power to help tip the scales back in the direction of web apps.

Wednesday, September 9th, 2026

Native HTML and CSS Features That Replaced JavaScript · Ronalds Vilciņš

Modern HTML and CSS have gained a surprising number of features that cover interactions and layout problems we used to solve with custom scripts or libraries. JavaScript obviously isn’t going anywhere, and there are plenty of things that still require it, but in 2026 I find myself needing it less often for ordinary website interfaces.

Tuesday, September 1st, 2026

CSS is Still Awesome • Jason Santa Maria

CSS finally gave the web its own grain.

And the real crazy part is that my bad decades-old code still renders fine in today’s latest web browsers! I would be sad if it didn’t, but I also wouldn’t be surprised. How is this stuff still backwards compatible!?

How much of your software from 20 years ago runs on your devices today

Thursday, August 20th, 2026

HTML Can Do That · Chris Burnell

HTML has been gobbling up swathes of what used to be JavaScript’s remit. This page lists a bunch of dynamic functionality that we can now achieve with just HTML.

Ebb, Meet Flow: Intrinsic Design in a Nutshell - Jeffrey Zeldman Presents

Instead of chasing an ever-changing number of fixed breakpoints, utopian or intrinsic design follows the web’s intrinsic ebbs and flows via fluid type scales that are always in tune with the screen on which they’re viewed

Saturday, August 1st, 2026

Styling the Navigation: Declarative Route and Navigation Matching in CSS – Bram.us

I really, really, really like this proposal! This would absolutely turbo-charge cross-document view transitions with nary a line of JavaScript in sight.

Wednesday, July 15th, 2026

Image to text

At The Web You Want event in Amsterdam last month, Léonie gave an absolutely fantastic talk. You can now read the whole thing: Accessibility is resistance!

She makes the very good point that generative tools are a necessary accessibility recourse when humans have failed to do their job properly.

Images without alt text? Somebody messed up. But this is damage that can be routed around with large language models.

So if you—like me—don’t like the idea of people using extractive generative tools made by the worst kind of people, pay heed:

If you want to resist AI, make accessibility part of everything you do, every decision you make, every product you design and build. Remove the need for people to use AI to compensate, and remember, accessibility is resistance.

Also last month, I wrote about enhancing images from a carousel to masonry using CSS Grid Lanes. Here’s the context:

Over on The Session, I added a little enhancement to the events and sessions listings recently. I make a call to the Google Places API to see if I can find a match for the venue, and if I do, pull in some photos.

Sidenote: right now there’s a major issue with this. None of the photos come with text descriptions. This is something I need to fix, and I’ve got some ideas on how to do that.

I was one of those people with a website that doesn’t have alt text for images. I was one of those people not doing their job.

The first fix I put in place was very much in keeping with the ethos of The Session. I added a form so that any member of the site can edit the alt text of the images in the carousel/masonry layout.

The Session is quite WikiPedia-like. Anyone can edit the track listings in the discography. Anyone can edit the details of any tune. Anyone can edit the details of any session or event. So it made sense to add one more thing that anyone can edit.

With that functionality in place, I put out the call:

If everyone were to take just one or two sessions or events and add alt text to the photos, it would really, really help make the site more accessible.

The community went to work and did a pretty good job.

But there are a lot images. I’d like to have a least some kind of alt text for all of them, even if it’s just a placeholder until someone gets around to adding something better.

I was going to have to use generative “AI”, wasn’t I?

Holding my nose, I investigated some alt-text-as-a-service APIs out there. I signed up for some trials and kicked the tyres. They were rubbish. I suspect most of them were vibe-coded.

The more I thought about it, the more I realised that I probably didn’t need the latest and greatest energy-guzzling large langauge models. Some good old-fashioned machine learning could do the trick here. I’m aiming to do a relatively straightforward transformation—image to text.

Check out the COCO project: Common Objects in Context. It’s a few years old now, but it’s basically a dataset that’s been trained on images.

Ah, but where did the training data come from?

All images in COCO were sourced from Flickr, a photo-sharing platform where users upload images under various Creative Commons licenses.

Works for me!

I found a model on Hugging Face that was created by Microsoft from the COCO data. Confusingly the model is called GIT. It’s nothing to do with version control. It stands for GenerativeImage2Text.

I downloaded the model and set to work creating a script to trawl through all those images and generate alt text if the image doesn’t already have one.

I should mention: the way that I store the alt text is not in a database, but in the file system. Every image has its own folder. Inside that folder there can also be a file called alt.txt.

So the script needed to loop through lots and lots of folders, generate alt text where needed, and save it into a text file in the same folder.

Python is the go-to language for working with models like GIT. But Python is not my strong suit, to put it mildly. And this was going to be a throwaway script that I was only going to use once. So I held my nose again and turned on Copilot in VSCode (I usually keep it switched off).

With the right instructions I was able to get a script that—crucially—I could read and understand. Then I switched off Copilot and had a shower to try to wash the shame away.

Long story short, the script worked.

The results are mostly fine. The alt text is functional. Sometimes it’s wrong, but not disastrously so. A human-generated image description will always be preferable, so any member of The Session can over-ride the placeholder alt text.

It took a few hours to loop through all those folders and generate all those text files. My laptop got hot. But doing it locally sure beats paying for tokens from the baddies.

Like Scott says:

While the utility is there, the current landscape of these frontier corporate models comes with massive ethical and environmental baggage. This is not a long term solution!

That’s exactly why my hope is that ethically trained open-weight models will eventually catch up and that in the next couple of years, we’ll have something with this level of capability that can run locally. That feels like a much better place to be with this technology.

Tuesday, July 14th, 2026

Your ‘App’ Could Have Been a Webpage (so I fixed it for you…) – Dan Q

I can’t understand how we got to this place with “app culture”! Software companies are happy to make their lives harder (and more expensive: deploying to the big app stores isn’t free!), in order to deliver HTML content to fewer people and with fewer features than if they just published directly to the Web in the first place!

HTMX and Web Components Instead of React

So instead of asking “why not React?” we asked: Which of our actual problems would React solve? We went through the list. There were none.

Also, this is good advice when you’re about to make a web component:

Every component starts with the question “does a semantic element already exist for this?”, and remarkably often the answer is yes.

Friday, July 10th, 2026

The Descent — What Happened to the Frontend While You Weren’t Watching

A history of front-end development that culminates here:

The frontier of 2026, the stuff the sharpest people are most excited about, is render the HTML on the server, ship almost no JavaScript, and use the web platform instead of fighting it.

Wednesday, July 8th, 2026

Abject Praise - Infrequently Noted

Alex takes issue with my post giving kudos to Apple for concentrating on bugfixes in the latest version of Safari, and he brings receipts. He makes a very compelling case, backed up with data.

But when it comes to Chrome’s shipping of the half-baked prompt API, I’m not sure he gets just how badly it has soured the developer community’s feelings towards Google. This isn’t something to be countered with data; it’s much more visceral than that. Alex says:

So if Jeremy has a problem with specific features, I hope he’ll come to us with a critique of their qualities, rather than their optics.

In this case though, the optics are really, really, really bad.

Thursday, June 18th, 2026

The golden rule of Customizable Select | WebKit

This is excellent advice and I’m glad to see this getting addressed nice and early in the era of customisable select elements:

always provide text content or accessible text attributes for your option elements.

Tuesday, June 16th, 2026

Enhancing with CSS Grid Lanes

CSS Grid Lanes has started to ship in browsers. It’s in Safari and behind a flag in Chrome and Edge.

It enables masonry layouts, where items get packed together in the most efficient way possible.

Unsurprisingly, I’m a fan of a layout tool where the browser does all the hard work. It very much aligns with the idea of declarative design; you specify the boundary conditions, and then browser does the maths and heavy lifting.

There’s a handy website called The Field Guide to Grid Lanes where you can play around with possibilities.

At the most recent CSS Day, Patrick Brosset gave a great talk showing what you could do with Grid Lanes. I immediately started playing around with it, and I spotted what I think could be a useful pattern…

Over on The Session, I added a little enhancement to the events and sessions listings recently. I make a call to the Google Places API to see if I can find a match for the venue, and if I do, pull in some photos.

Sidenote: right now there’s a major issue with this. None of the photos come with text descriptions. This is something I need to fix, and I’ve got some ideas on how to do that.

Anyway, these photos are just nice-to-haves so I’ve tucked them away into a details element with a simple summary like “Ten photos” or “Twenty photos”. If you open up that details element you get the photos in a horizontal swipable row. A carousel, if you will.

This works fine, but on larger screens I think it would be okay to show all the photos at once. That’s where Grid Lanes comes in.

Take a look at an event or a session in Safari to see what I mean.

Here’s the CSS that creates a carousel:

.gallery {
    display: flex;
    align-items: center;
    inline-size: fit-content;
    max-inline-size: 100%;
    overflow-inline: auto;
    scroll-snap-type: inline mandatory;
    overscroll-behavior-inline: contain;
    scroll-behavior: smooth;
    scrollbar-gutter: stable;
}
.gallery > * {
    flex-shrink: 0;
    scroll-snap-align: center;
}

And here’s the media query that turns it into a masonry layout:

@supports (display: grid-lanes) {
    @media all and (min-width: 56em) {
        .gallery {
            all: initial;
            display: grid-lanes;
            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
            gap: 0.5em;
        }
        .gallery > * {
            inline-size: 100%;
        }
    }
}

I’m using all: initial to unset the previous styles, which is a bit of a sledgehammer but it works.

I think this could be a useful responsive design pattern. Masonry layouts are great for large screens but kind of rubbish for small screens where you end up with just a single column. Carousels aren’t much cop on large screens but maybe have their place on small screens where real estate is at a premium.

Oh, and needless to say, this is a progressive enhancement. If a browser doesn’t yet understand display: grid-lanes it continues to get the carousel layout.

Monday, June 15th, 2026

How building an HTML-first site doubled our users overnight

This is a great case study featuring a really useful HTML web component called validation-enhancer.

The results? When we launched, the number of people completing the form doubled. The analytics people didn’t even know where these users were coming from. Of course, your javascript-based analytics package doesn’t see the users you are bouncing because of javascript failures. It was a flood!

Saturday, June 13th, 2026

A tale of two browsers

I give Apple a hard time. That’s mostly due to how they treat the web on their own mobile devices.

Though iOS ostensibly supports the ability for websites to be added to the homescreen, they make it so difficult for users to do, the functionality is practically worthless. It’s dispiriting to see the web so hamstrung by that decision.

The Webkit team has come in for other criticism too. For a while there, Safari was lagging so far behind in features that people were calling it the new Internet Explorer. Ouch!

But credit where credit is due. The upcoming version 27 of Safari is looking very good.

That’s not because it’s at the cutting edge of the latest web standards. Quite the opposite. Most of the changes listed for this release are bug fixes. That’s what I want to acknowledge and applaud.

Far too often a browser will rush out an implementation of an exciting new web standard that gets plenty of attention. But that initial implementation is rarely 100% correct. Then the next release rolls around and the focus has moved on to a different new web standard. The result is an ever-growing backlog of almost-but-not-quite-supported features.

Clearly the focus for Safari 27 was on that backlog. I bet that wasn’t an easy decision. Like I said, the kudos and recognition tends to go to the browser that ships new stuff, not the browser that goes back to fix long-standing issues.

Don’t get me wrong, there’s some exciting new stuff in Safari 27 too, like styleable select, but it’s great to see the focus on maintenance and repair:

If you look through the lists of features and fixes in Safari 27, you’ll notice that, although there are 58 brand-new features and 525 fixes — the largest pile of fixes in any Safari release in recent memory — most of what is released is not about new things.

Most of this work has been about existing features behaving more correctly, handling more edge cases, and fitting together with other features the way you’d expect.

This in sharp contrast to the most recent release of Chrome that shipped support for the prompt API despite opposition from other browsers and no positive signals from developers. I hope some Googler got a nice promotion for shoving a proprietary technology into a web browser, but they should be aware of the damage they’ve done.

At this year’s CSS Day, the represenatatives from Google Chrome were once again there to talk to developers and ask what we wanted them to prioritise. Those requests rang very hollow. Why should we waste our time and energy telling a browser team what we need if they’re just going to ship whatever crap they want?

The truth is that the folks from Google who were canvassing opinions from the attendees at CSS Day are not the same people who torpedoed the browser with unwanted proprietary tech. This team has spent years doing excellent outreach, documenting web standards, and meeting with developers. They built up an impressive amount of trust, respect, and goodwill.

That stock has now plummeted.

So well done to the Webkit team for Safari 27. And shame on the Chrome team for Chrome 148.