Journal tags: os

191

sparkline

Progressive web apps

There was a time when you needed to make a native app in order to take advantage of specific technologies. That time has passed.

Now you can do all of these things on the web:

  • push notifications,
  • offline storage,
  • camera access,
  • and more.

Take a look at the home screen on your phone. Looking at the apps you’ve downloaded from an app store, ask yourself how many of them could’ve been web apps.

Social media apps, airline apps, shopping apps …none of them are using technologies that aren’t widely available on the web.

“But”, you might be thinking, “it feels different having a nice icon on my homescreen that launches a standalone app compared to navigating to a bookmark in my web browser.”

I agree! And you can do that with a web app. All it takes the addition of one manifest file that lists which icons and colours to use.

If that file exists for a website, then once the user adds the website to their homescreen it will behave just like native app.

Try it for yourself. Go to instagram.com in your mobile browser and it to your homescreen (on the iPhone, you get to the “add to home screen” option from the sharing icon—scroll down the list of options to find it).

See how it’s now an icon on your home screen just like all your other apps? Tap that icon to see how it launches just like a native app with no browser chrome around it.

This doesn’t just work on mobile. Desktop browsers like Chrome, Edge, and Safari also allow you to install web apps straight from the browser and into your dock.

About half of the icons in my dock are actually web apps and I honestly can’t tell which is which. Mastodon, Instagram, Google Calendar, Google Docs …I’m sure most of those services are available as downloadable desktop apps, but why would I bother doing that when I get exactly the same experience by adding the sites to my dock?

From a business perspective, it makes so much sense to build a web app (or simply turn your existing website into a web app with the addition of a manifest file). No need for separate iOS or Android developer teams. No need to play the waiting game with updates to your app in the app store—on the web, updates are instant.

You can even use an impressive-sounding marketing term for this approach: progressive web apps:

A Progressive Web App (PWA) is a web app that uses progressive enhancement to provide users with a more reliable experience, uses new capabilities to provide a more integrated experience, and can be installed. And, because it’s a web app, it can reach anyone, anywhere, on any device, all with a single codebase. Once installed, a PWA looks like any other app, specifically:

  • It has an icon on the home screen, app launcher, launchpad, or start menu.
  • It appears when you search for apps on the device.
  • It opens in a standalone window, wholly separated from a browser’s user interface.
  • It has access to higher levels of integration with the OS, for example, URL handling or title bar customization.
  • It works offline.

But there’s still one thing that native apps do better than the web. If you want to be able to monitor and track users to an invasive degree, the web can’t compete with the capabilities of native apps. That’s why you’ll see so many websites on your mobile device that implore to install their app from the app store.

If that’s not a priority for you, then you can differentiate yourself from your competitors by offering your users a progressive web app. Instead of having links to Apple and Google’s app stores, you can link to a page on your own site with installation instructions.

I can guarantee you that users won’t be able to tell the difference between a native app they installed from an app store and a web app they’ve added to their home screen.

Uses

I don’t use large language models. My objection to using them is ethical. I know how the sausage is made.

I wanted to clarify that. I’m not rejecting large language models because they’re useless. They can absolutely be useful. I just don’t think the usefulness outweighs the ethical issues in how they’re trained.

Molly White came to the same conclusion:

The benefits, though extant, seem to pale in comparison to the costs.

Rich has similar thoughts:

What I do know is that I find LLMs useful on occasion, but every time I use one I die a little inside.

I genuinely look forward to being able to use a large language model with a clear conscience. Such a model would need to be trained ethically. When we get a free-range organic large language model I’ll be the first in line to use it. Until then, I’ll abstain. Remember:

You don’t get companies to change their behaviour by rewarding them for it. If you really want better behaviour from the purveyors of generative tools, you should be boycotting the current offerings.

Still, in anticipation of an ethical large language model someday becoming reality, I think it’s good for me to have an understanding of which tasks these tools are good at.

Prototyping seems like a good use case. My general attitude to prototyping is the exact opposite to my attitude to production code; use absolutely any tool you want and prioritise speed over quality.

When it comes to coding in general, I think Laurie is really onto something when he says:

Is what you’re doing taking a large amount of text and asking the LLM to convert it into a smaller amount of text? Then it’s probably going to be great at it. If you’re asking it to convert into a roughly equal amount of text it will be so-so. If you’re asking it to create more text than you gave it, forget about it.

In other words, despite what the hype says, these tools are far better at transforming than they are at generating.

Iris Meredith goes deeper into this distinction between transformative and compositional work:

Compositionality relies (among other things) on two core values or functions: choice and precision, both of which are antithetical to LLM functioning.

My own take on this is that transformative work is often the drudge work—take this data dump and convert it to some other format; take this mock-up and make a disposable prototype. I want my tools to help me with that.

But compositional work that relies on judgement, taste, and choice? Not only would I not use a large language model for that, it’s exactly the kind of work that I don’t want to automate away.

Transformative work is done with broad brushstrokes. Compositional work is done with a scalpel.

Large language models are big messy brushes, not scalpels.

Denial

The Wikimedia Foundation, stewards of the finest projects on the web, have written about the hammering their servers are taking from the scraping bots that feed large language models.

Our infrastructure is built to sustain sudden traffic spikes from humans during high-interest events, but the amount of traffic generated by scraper bots is unprecedented and presents growing risks and costs.

Drew DeVault puts it more bluntly, saying Please stop externalizing your costs directly into my face:

Over the past few months, instead of working on our priorities at SourceHut, I have spent anywhere from 20-100% of my time in any given week mitigating hyper-aggressive LLM crawlers at scale.

And no, a robots.txt file doesn’t help.

If you think these crawlers respect robots.txt then you are several assumptions of good faith removed from reality. These bots crawl everything they can find, robots.txt be damned.

Free and open source projects are particularly vulnerable. FOSS infrastructure is under attack by AI companies:

LLM scrapers are taking down FOSS projects’ infrastructure, and it’s getting worse.

You try to do the right thing by making knowledge and tools freely available. This is how you get repaid. AI bots are destroying Open Access:

There’s a war going on on the Internet. AI companies with billions to burn are hard at work destroying the websites of libraries, archives, non-profit organizations, and scholarly publishers, anyone who is working to make quality information universally available on the internet.

My own experience with The Session bears this out.

Ars Technica has a piece on this: Open source devs say AI crawlers dominate traffic, forcing blocks on entire countries .

So does MIT Technology Review: AI crawler wars threaten to make the web more closed for everyone.

When we talk about the unfair practices and harm done by training large language models, we usually talk about it in the past tense: how they were trained on other people’s creative work without permission. But this is an ongoing problem that’s just getting worse.

The worst of the internet is continuously attacking the best of the internet. This is a distributed denial of service attack on the good parts of the World Wide Web.

If you’re using the products powered by these attacks, you’re part of the problem. Don’t pretend it’s cute to ask ChatGPT for something. Don’t pretend it’s somehow being technologically open-minded to continuously search for nails to hit with the latest “AI” hammers.

If you’re going to use generative tools powered by large language models, don’t pretend you don’t know how your sausage is made.

Style legend

There’s a new proposal for giving developers more control over styling form controls. I like it.

It’s clearly based on the fantastic work being done by the Open UI group on the select element. The proposal suggests that authors can opt-in to the new styling possibilities by declaring:

appearance: base;

So basically the developer is saying “I know what I’m doing—I’m taking the controls.” But browsers can continue to ship their default form styles. No existing content will break.

The idea is that once the developer has opted in, they can then style a number of pseudo-elements.

This proposal would apply to pretty much all the form controls you can think of: all the input types, along with select, progress, meter, buttons and more.

But there’s one element more that I wish were on the list:

legend

I know, technically it’s not a form control but legend and fieldset are only ever used within forms.

The legend element is notoriously annoying to style. So a lot of people just don’t bother using it, which is a real shame. It’s like we’re punishing people for doing the right thing.

Wouldn’t it be great if you, as a developer, had the option of saying “I know what I’m doing—I’m taking the controls”:

legend {
  appearance: base;
}

Imagine if that nuked the browser’s weird default styles, effectively turning the element into a span or div as far as styling is concerned. Then you could style it however you wanted. But crucially, if browsers shipped this, no existing content would break.

The shitty styling situation for legend (and its parent fieldset) is one of those long-standing annoyances that seems to have fallen down the back of the sofa of browser vendors. No one’s going to spend time working on it when there are more important newer features to ship. That’s why I’d love to see it sneak in to this new proposal for styling form controls.

I was in Amsterdam last week. Just like last year I was there to help out Vasilis’s students with a form-based assignment:

They’re given a PDF inheritance-tax form and told to convert it for the web.

Yes, all the excitement of taxes combined with the thrilling world of web forms.

(Side note: this time they were told to style it using the design system from the Dutch railway because the tax office was getting worried that they were making phishing sites.)

I saw a lot of the same challenges again. I saw how students wished they could specify a past date or a future date in a date picker without using JavaScript. And I saw them lamenting the time they spent styling legends that worked across all browsers.

Right now, Mason Freed has an open issue on the new proposal with his suggestion to add some more elements to consider. Both legend and fieldset are included. That gets a thumbs-up from me.

Curating UX London 2025

I’ve had my head down for the past six months putting the line-up for UX London together. Following the classic design cliché, the process was first divergent, then convergent.

I spent months casting the net wide, gathering as many possible candidates as I could, as well as accepting talk proposals (of which there were lots). It was fun—this is when the possibility space is wide open.

Then it was crunch time and I had to start zeroing in on the final line-up. It wasn’t easy. There were so many times I agonised over who’d be the right person to deliver the right talk.

But as the line-up came together, I started getting very excited. And now when I step back and look at the line-up, I’m positively vibrating with excitement—roll on June!

I think it was really useful to have a mix of speakers that I reached out to, as well as talk proposals. If I was only relying on my own knowledge and networks, I’m sure I’d miss a lot. But equally, if I was only relying on talk proposals, it would be like searching for my keys under the streetlight.

Putting the line-up on the website wasn’t quite the end of the work. We got over 100 proposals for UX London this year. I made sure to send an email back to each and every one of them once the line-up was complete. And if anyone asked for more details as to why their proposal didn’t make it through, I was happy to provide that feedback.

After they went to the trouble of submitting a proposal, it was the least I could do.

Oh, and don’t forget: early-bird tickets for UX London are only available until Friday. Now’s the time to get yours!

Hosted

Research By The Sea was last Thursday. I’m still digesting it all.

In short, it was excellent. The venue, how smoothly every thing was organised, the talks …oh boy, the talks!

Benjamin did a truly superb job curating this line-up. Everyone really brought their A-game.

As predicted, this wasn’t a day of talks just for researchers. It was far more like a dConstruct. This was big, big picture stuff. Themes of hope, community, nature, technology, inclusion and resilience.

I overheard more than one person in the breaks saying “this was not what I was expecting!” They were saying it in a very positive way, though I wouldn’t be surprised if there were a silent minority in the audience who were miffed that they weren’t getting a day of practical research techniques devoid of politics.

As host, I had the easiest job of the day. All I had to do was say a few words of introduction for each speaker, then sit back down and enjoy every minute of every talk.

The one time when I had to really work was the panel discussion at the end of the day. I really enjoy moderating panels. I’ve seen enough bad panels to know what does and doesn’t work. But this one was tough. The panelists were all great, but because the themes were soooo big, I was worried about it all getting a bit too high-falutin’. People seemed to enjoy it though.

All in all, it was a superb day. If you came along, thank you!

Gotta be honest, #ResearchByTheSea is one of the best conferences I’ve been to in yeeeeeears. So many good, useful, inspiring, thoughtful, provocative talks. Much more about ethics and power and possibility than I’d expected.

Loved it. Thank you, @clearleft.com!

@visitmy.website

Research By The Sea

I’m going to be hosting Research By The Sea on Thursday, February 27th right here in Brighton. I’m getting very excited and nervous about it.

The nervousness is understandable. I want to do a good job. Hosting a conference is like officiating a wedding. You want to put people at ease and ensure everything goes smoothly. But you don’t want to be the centre of attention. People aren’t there to see you. This is not your day.

As the schedule has firmed up, my excitement has increased.

See, I’m not a researcher. It would be perfectly understandable to expect this event to be about the ins and outs of various research techniques. But it’s become clear that that isn’t what Benjamin has planned.

Just as any good researcher or designer goes below the surface to explore the root issues, Research By The Sea is going to go deep.

I mean, just take a look at what Steph will be covering:

Steph discusses approaches in speculative fiction, particularly in the Solarpunk genre, that can help ground our thinking, and provide us—as researchers and designers—tenets to consider our work, and, as humans, to strive towards a better future.

Sign me up!

Michael’s talk covers something that’s been on my mind a lot lately:

Michael will challenge the prevailing belief that as many people as possible must participate in our digital economies.

You just know that a talk called In defence of refusal isn’t going to be your typical conference fare.

Then there are talks about accessibility and intersectionality, indigenous knowledge, designing communities, and navigating organisational complexity. And I positively squeeled with excitement when I read Cennydd’s talk description:

The world is crying out for new visions of the future: worlds in which technology is compassionate, not just profitable; where AI is responsible, not just powerful.

See? It’s very much not just for researchers. This is going to be a fascinating day for anyone who values curiosity.

If that’s you, you should grab a ticket. To sweeten the deal, use the discount code JOINJEREMY to get a chunky 20% of the price — £276 for a conference ticket instead of £345.

Be sure to nab your ticket before February 15th when the price ratchets up a notch.

And if you are a researcher, well, you really shouldn’t miss this. It’s kind of like when I’ve run Responsive Day Out and Patterns Day; sure, the talks are great, but half the value comes from being in the same space as other people who share your challenges and experiences. I know that makes it sound like a kind of group therapy, but that’s because …well, it kind of is.

Conference line-ups

When I was looking back at 2024, I mentioned that I didn’t give a single conference talk (though I did host three conferences—Patterns Day, CSS Day, and UX London).

I almost spoke at a conference though. I was all set to speak at an event in the Netherlands. But then the line-up was announced and I was kind of shocked at the lack of representation. The schedule was dominated by white dudes like me. There were just four women in a line-up of 30 speakers.

When I raised my concerns, I was told:

We did receive a lot of talks, but almost no women because there are almost no women in this kind of jobs.

Yikes! I withdrew my participation.

I wish I could say that it was one-off occurrence, but it just happened again.

I was looking forward to speaking at DevDays Europe. I’ve never been to Vilnius but I’ve heard it’s lovely.

Now, to be fair, I don’t think the line-up is finalised, but it’s not looking good.

Once again, I raised my concerns. I was told:

Unfortunately, we do not get a lot of applications from women and have to work with what we have.

Even though I knew I was just proving Brandolini’s law, I tried to point out the problems with that attitude (while also explaining that I’ve curated many confernce line-ups myself):

It’s not really conference curation if you rely purely on whoever happens to submit a proposal. Surely you must accept some responsibility for ensuring a good diverse line-up?

The response began with:

I agree that it’s important to address the lack of diversity.

…but then went on:

I just wanted to share that the developer field as a whole tends to be male-dominated, not just among speakers but also attendees.

At this point, I’m face-palming. I tried pointing out that there might just be a connection between the make-up of the attendees and the make-up of the speaker line-up. Heck, if I feel uncomfortable attending such a homogeneous conference, imagine what a woman developer would think!

Then they dropped the real clanger:

While we always aim for a diverse line-up, our main focus has been on ensuring high-quality presentations and providing the best experience for our audience.

Double-yikes! I tried to remain calm in my response. I asked them to stop and think about what they were implying. They’re literally setting up a dichotomy between having a diverse line-up and having a good line-up. Like it’s inconceivable you could have both. As though one must come at the expense of the other. Just think about the deeply embedded bias that would enable that kind of worldview.

Needless to say, I won’t be speaking at that event.

This is depressing. It feels like we’re backsliding to what conferences were like 15 years ago.

I can’t help but spot the commonalaties between the offending events. Both of them have multiple tracks. Both of them have a policy of not paying their speakers. Both of them seem to think that opening up a form for people to submit proposals counts as curation. It doesn’t.

Don’t get me wrong. Having a call for proposals is great …as long as it’s part of an overall curation strategy that actually values diversity.

You can submit a proposal to speak at FFconf, for example. But Remy doesn’t limit his options to what people submit. He puts a lot of work into creating a superb line-up that is always diverse, and always excellent.

By the way, you can also submit a proposal for UX London. I’ve had lots of submissions so far, but again, I’m not going to limit my pool of potential speakers to just the people who know about that application form. That would be a classic example of the streetlight effect:

The streetlight effect, or the drunkard’s search principle, is a type of observational bias that occurs when people only search for something where it is easiest to look.

It’s quite depressing to see this kind of minimal-viable conference curation result in such heavily skewed line-ups. Withdrawing from speaking at those events is literally the least I can do.

I’m with Karolina:

What I’m looking for: at least 40% of speakers have to be women speaking on the subject of their expertise instead of being invited to present for the sake of adjusting the conference quotas. I want to see people of colour too. In an ideal scenario, I’d like to see as many gender identities, ethnical backgrounds, ages and races as possible.

2024 in photos

Here’s one photo from each month in 2024

Thank you to @wienerlibrary@zwezo.o-k-i.net for last night’s screening of The Zone Of Interest with director Jonathan Glazer. Pasta Piedmontese Thank you so much to the wonderful speakers and team that made #PatternsDay3 so good! Wednesday session Strolling through the Black Forest. Listening to the brilliant Maggie Appleton at #UXlondon. Flyboys I’m sure my on-stage behaviour at Frostapalooza was total cringe, but I don’t care because I was having a great time! Cairo in Lawrence Of Arabia, Naboo in Attack Of The Clones, Minos’s palace in Kaos. Angels in the architecture Spent the morning rocking out with Salter Cane. Galway session

Choosing a geocoding provider

Yesterday when I mentioned my paranoia of third-party dependencies on The Session, I said:

I’ve built in the option to switch between multiple geocoding providers. When one of them inevitably starts enshittifying their service, I can quickly move on to another. It’s like having a “go bag” for geocoding.

(Geocoding, by the way, is when you provide a human-readable address and get back latitude and longitude coordinates.)

My paranoia is well-founded. I’ve been using Google’s geocoding API, which is changing its pricing model from next March.

You wouldn’t know it from the breathlessly excited emails they’ve been sending about it, but this is not a good change for me. I don’t do that much geocoding on The Session—around 13,000 or 14,000 requests a month. With the new pricing model that’ll be around $15 to $20 a month. Currently I slip by under the radar with the free tier.

So it might be time for me to flip that switch in my code. But which geocoding provider should I use?

There are plenty of slop-like listicles out there enumerating the various providers, but they’re mostly just regurgitating the marketing blurbs from the provider websites. What I need is more like a test kitchen.

Here’s what I did…

I took a representative sample of six recent additions to the sessions section of thesession.org. These examples represent places in the USA, Ireland, England, Scotland, Northern Ireland, and Spain, so a reasonable spread.

For each one of those sessions, I’m taking:

  • the venue name,
  • the town name,
  • the area name, and
  • the country.

I’m deliberately not including the street address. Quite often people don’t bother including this information so I want to see how well the geocoding APIs cope without it.

I’ve scored the results on a simple scale of good, so-so, and just plain wrong.

  • A good result gets a score of one. This is when the result gives back an accurate street-level result.
  • A so-so result gets a score of zero. This when it’s got the right coordinates for the town, but no more than that.
  • A wrong result gets a score of minus one. This is when the result is like something from a large language model: very confident but untethered from reality, like claiming the address is in a completely different country. Being wrong is worse than being vague, hence the difference in scoring.

Then I tot up those results for an overall score for each provider.

When I tried my six examples with twelve different geocoding providers, these were the results:

Geocoding providers
Provider USA England Ireland Spain Scotland Northern Ireland Total
Google 1111117
Mapquest 1111117
Geoapify 0110103
Here 1101003
Mapbox 11011-13
Bing 1000001
Nominatim 0000-110
OpenCage -11000-1-1
Tom Tom -1-100-11-2
Positionstack 0-10-11-1-2
Locationiq -10-100-1-3
Map Maker -10-1-1-1-1-5

Some interesting results there. I was surprised by how crap Bing is. I was also expecting better results from Mapbox.

Most interesting for me, Mapquest is right up there with Google.

So now that I’ve got a good scoring system, my next question is around pricing. If Google and Mapquest are roughly comparable in terms of accuracy, how would the pricing work out for each of them?

Let’s say I make 15,000 API requests a month. Under Google’s new pricing plan, that works out at $25. Not bad.

But if I’ve understood Mapquest’s pricing correctly, I reckon I’ll just squeek in under the free tier.

Looks like I’m flipping the switch to Mapquest.

If you’re shopping around for geocoding providers, I hope this is useful to you. But I don’t think you should just look at my results; they’re very specific to my needs. Come up with your own representative sample of tests and try putting the providers through their paces with your data.

If, for some reason, you want to see the terrible PHP code I’m using for geocoding on The Session, here it is.

Syndicating to Bluesky

Last year I described how I syndicate my posts to different social networks.

Back then my approach to syndicating to Bluesky was to piggy-back off my micro.blog account (which is really just the RSS feed of my notes):

Micro.blog can also cross-post to other services. One of those services is Bluesky. I gave permission to micro.blog to syndicate to Bluesky so now my notes show up there too.

It worked well enough, but it wasn’t real-time and I didn’t have much control over the formatting. As Bluesky is having quite a moment right now, I decided to upgrade my syndication strategy and use the Bluesky API.

Here’s how it works…

First you need to generate an app password. You’ll need this so that you can generate a token. You need the token so you can generate …just kidding; the chain of generated gobbledegook stops there.

Here’s the PHP I’m using to generate a token. You’ll need your Bluesky handle and the app password you generated.

Now that I’ve got a token, I can send a post. Here’s the PHP I’m using.

There’s something extra code in there to spot URLs and turn them into links. Bluesky has a very weird way of doing this.

It didn’t take too long to get posting working. After some more tinkering I got images working too. Now I can post straight from my website to my Bluesky profile. The Bluesky API returns an ID for the post that I’ve created there so I can link to it from the canonical post here on my website.

I’ve updated my posting interface to add a toggle for Bluesky right alongside the toggle for Mastodon. There used to be a toggle for Twitter. That’s long gone.

Now when I post a note to my website, I can choose if I want to send a copy to Mastodon or Bluesky or both.

One day Bluesky will go away. It won’t matter much to me. My website will still be here.

FFConf 2024

I went to FFConf on Friday. It did me the world of good.

To be honest, I haven’t much felt like venturing out over the past few days since my optimism took a big hit. But then when I do go and interact with people, I’m grateful for it.

Like, when I went out to my usual Wednesday evening traditional Irish music session I was prepared the inevitable discussion of Trump’s election. I was ready to quite clearly let people know that I didn’t want to talk about it. But I didn’t have to. Maybe because everyone else was feeling much the same, we just played and played. It was good.

The session on Thursday was good too. When we chatted, it was about music.

Still, I was ready for the weekend and I wasn’t really feeling psyched up for FFConf on Friday. But once I got there, I was immediately uplifted.

It was so nice to see so many people I hadn’t seen in quite a while. I had the chance to reconnect with people that I had only been hearing from through my RSS reader:

Terence, I’m really enjoying your sci-fi short stories!”

Kirsty, I was on tenterhooks when you were getting Mabel!”

(Mabel is an adorable kitty-cat. In hindsight I probably should’ve also congratulated her on getting married. To a human.)

The talks were really good this year. They covered a wide variety of topics.

There was only one talk about “AI” (unlike most conferences these days, where it dominates the agenda). Léonie gave a superb run-down of the different kinds of machine learning and how they can help or hinder accessibility.

Crucially, Léonie began her talk by directly referencing the exploitation and energy consumption inherent in today’s large language models. It took all of two minutes, but it was two minutes more than the whole day of talks at UX Brighton. Thank you, Léonie!

Some of the other talks covered big topics. Life. Death. Meaning. Purpose.

I enjoyed them all, though I often find something missing from discussions about meaning and purpose. Just about everyone agrees that having a life enfused with purpose is what provides meaning. So there’s an understandable quest to seek out what it is that gives you purpose.

But we’re also constantly reminded that every life has intrinsic meaning. “You are enough”, not “you are enough, as long as there’s some purpose to your life.”

I found myself thinking about Winne Lim’s great post on leading a purposeless life. I think about it a lot. It gives me comfort. Instead of assuming that your purpose is out there somewhere and you’ve got to find it, you can entertain the possibility that your life might not have a purpose …and that’s okay.

I know this all sounds like very heavy stuff, but it felt good to be in a room full of good people grappling with these kind of topics. I needed it.

Dare I say it, perhaps my optimism is returning.

Docks and home screens

Back in June I documented a bug on macOS in how Spaces (or whatever they call they’re desktop management thingy now) works with websites added to the dock.

I’m happy to report that after upgrading to Sequoia, the latest version of macOS, the bug has been fixed! Excellent!

Not only that, but there’s another really great little improvement…

Let’s say you’ve installed a website like The Session by adding it to the dock. Now let’s say you get an email in Apple Mail that includes a link to something on The Session. It used to be that clicking on that link would open it in your default web browser. But now clicking on that link opens it in the installed web app!

It’s a lovely little enhancement that makes the installed website truly feel like a native app.

Websites in the dock also support the badging API, which is really nice!

Like I said at the time:

I wonder if there’s much point using wrappers like Electron any more? I feel like they were mostly aiming to get that parity with native apps in having a standalone application launched from the dock.

Now all you need is a website.

The biggest issue remains discovery. Unless you already know that it’s possible to add a website to the dock, you’re unlikely to find out about it. That’s why I’ve got a page with installation instructions on The Session.

Still, the discovery possibilities on Apples’s desktop devices are waaaaay better than on Apple’s mobile devices.

Apple are doing such great work on their desktop operating system to make websites first-class citizens. Meanwhile, they’re doing less than nothing on their mobile operating system. For a while there, they literally planned to break all websites added to the homescreen. Fortunately they were forced to back down.

But it’s still so sad to see how Apple are doing everything in their power to prevent people from finding out that you can add websites to your homescreen—despite (or perhaps because of) the fact that push notifications on iOS only work if the website has been added to the home screen!

So while I’m really happy to see the great work being done on installing websites for desktop computers, I’m remain disgusted by what’s happening on mobile:

At this point I’ve pretty much given up on Apple ever doing anything about this pathetic situation.

The datalist element on iOS

The datalist element is good. It was a bit bumpy there for a while, but browser implementations have improved over time. Now it’s by far the simplest and most robust way to create an autocompleting combobox widget.

Hook up an input element with a datalist element using the list and id attributes and you’re done. You can even use a bit of Ajax to dynamically update the option elements inside the datalist in response to the user’s input. The browser takes care of all the interaction. If you try to roll your own combobox implementation, it’s almost certainly going to involve a lot of JavaScript and still probably won’t account for all use cases.

Safari on iOS—and therefore all browsers on iOS—didn’t support datalist for quite a while. But once it finally shipped, it worked really nicely. The options showed up just like automplete suggestions above the keyboard.

But that broke a while back.

The suggestions still appeared, but if you tapped on one of them, nothing happened. The input element didn’t get updated. You had to tap on a little downward arrow inside the input in order to see the list of options.

That was really frustrating for anybody on iOS using The Session. By far the most common task on the site is searching for a tune, something that’s greatly (progressively) enhanced with a dynamically-updating datalist.

I just updated to iOS 18 specifically to see if this bug has been fixed, and it has:

Fixed updating the input value when selecting an option from a datalist element.

Hallelujah!

But now there’s some additional behaviour that’s a little weird.

As well as showing the options in the autocomplete list above the keyboard, Safari on iOS—and therefore all browsers on iOS—also pops up the options as a list (as if you had tapped on that downward arrow). If the list is more than a few options long, it completely obscures the input element you’re typing into!

I’m not sure if this is a bug or if it’s the intended behaviour. It feels like a bug, but I don’t know if I should file something.

For now, I’ve updated the datalist elements on The Session to only ever hold three option elements in order to minimise the problem. Seeing as the autosuggest list above the keyboard only ever shows a maximum of three suggestions anyway, this feels like a reasonable compromise.

What price?

I’ve noticed a really strange justification from people when I ask them about their use of generative tools that use large language models (colloquially and inaccurately labelled as artificial intelligence).

I’ll point out that the training data requires the wholesale harvesting of creative works without compensation. I’ll also point out the ludicrously profligate energy use required not just for the training, but for the subsequent queries.

And here’s the thing: people will acknowledge those harms but they will justify their actions by saying “these things will get better!”

First of all, there’s no evidence to back that up.

If anything, as the well gets poisoned by their own outputs, large language models may well end up eating their own slop and getting their own version of mad cow disease. So this might be as good as they’re ever going to get.

And when it comes to energy usage, all the signals from NVIDIA, OpenAI, and others are that power usage is going to increase, not decrease.

But secondly, what the hell kind of logic is that?

It’s like saying “It’s okay for me to drive my gas-guzzling SUV now, because in the future I’ll be driving an electric vehicle.”

The logic is completely backwards! If large language models are going to improve their ethical shortcomings (which is debatable, but let’s be generous), then that’s all the more reason to avoid using the current crop of egregiously damaging tools.

You don’t get companies to change their behaviour by rewarding them for it. If you really want better behaviour from the purveyors of generative tools, you should be boycotting the current offerings.

I suspect that most people know full well that the “they’ll get better!” defence doesn’t hold water. But you can convince yourself of anything when everyone around is telling you that this is the future baby, and you’d better get on board or you’ll be left behind.

Baldur reminds us that this is how people talked about asbestos:

Every time you had an industry campaign against an asbestos ban, they used the same rhetoric. They focused on the potential benefits – cheaper spare parts for cars, cheaper water purification – and doing so implicitly assumed that deaths and destroyed lives, were a low price to pay.

This is the same strategy that’s being used by those who today talk about finding productive uses for generative models without even so much as gesturing towards mitigating or preventing the societal or environmental harms.

It reminds me of the classic Ursula Le Guin short story, The Ones Who Walk Away from Omelas that depicts:

…the utopian city of Omelas, whose prosperity depends on the perpetual misery of a single child.

Once citizens are old enough to know the truth, most, though initially shocked and disgusted, ultimately acquiesce to this one injustice that secures the happiness of the rest of the city.

It turns out that most people will blithely accept injustice and suffering not for a utopia, but just for some bland hallucinated slop.

Don’t get me wrong: I’m not saying large language models aren’t without their uses. I love seeing what Simon and Matt are doing when it comes to coding. And large language models can be great for transforming content from one format to another, like transcribing speech into text. But the balance sheet just doesn’t add up.

As Molly White put it: AI isn’t useless. But is it worth it?:

Even as someone who has used them and found them helpful, it’s remarkable to see the gap between what they can do and what their promoters promise they will someday be able to do. The benefits, though extant, seem to pale in comparison to the costs.

Belfast, Brighton, Cork, Boston, Pittsburgh, Saint Augustine

I’ve been on a sabbatical from work for the past six weeks.

At Clearleft, you’re eligible for a sabbatical after five years. For some reason I haven’t taken one until now, 19 years into my tenure at the agency. I am an idiot.

My six-week sabbatical has been lovely, alternating between travel and homebodying.

Belfast

The first week was spent in Belfast at the excellent Belfast Trad Fest. There were workshops in the morning, sessions in the afternoon, and concerts in the evening. Non-stop music!

This year’s event was a little bit special for me. The festival runs an excellent bursary sponsorship programme for young people who otherwise wouldn’t be able to attend:

The bursary secures a place for a young musician to attend and experience a week-long intensive and immersive summertime learning course of traditional music, song and dance and can be transformative.

Back in April, I did a month-long funding drive on The Session:

Starting from today, and for the whole month of April, any donations made to The Session, which normally go towards covering the costs of running the site, will instead go towards sponsoring bursary places for this year’s Belfast Summer school.

I was really hoping to hit £1000, which would cover bursary sponsorship for eight students. In the end though, the members of The Session contributed a whopping £3000!

Needless to say, I was thrilled! The Trad Fest team were very happy too—they very kindly gave me a media pass for the duration of the event, which meant I could go to any of the concerts for free. I made full use of this.

That said, one of the absolute highlights of the week wasn’t a concert, but a session. Piper Mick O’Connor and fiddler Sean Smyth led a session out at the American Bar one evening that was absolutely sublime. There was a deep respect for the music combined with a lovely laidback vibe.

Brighton

There were no shortage of sessions once Jessica returned from Belfast to Brighton. In fact, when we got the train back from Gatwick we hopped in a cab straight to a session instead of going home first. Can’t stop, won’t stop.

The weather hadn’t been great in Belfast, which was fine because we were mostly indoors. But once we got back to Brighton we were treated to a week of glorious sunshine.

Needless to say, Jessica did plenty of swimming. I even went in the ocean myself on one of the hottest days.

I also went into the air. Andy took me up in a light aircraft for a jolly jaunt over the south of England. We flew from Goodwood over the New Forest, and around the Isle of Wight where we landed for lunch. Literally a flying visit.

I can attest that Andy is an excellent pilot. No bumpy landings.

Cork

Our next sojourn took us back to the island of Ireland, but this time we were visiting the Republic. We spent a week in the mightiest of all the Irish counties, Cork.

Our friends Dan and Sue came over from the States and a whole bunch of us went on a road trip down to west Cork, a beautiful part of the country that I shamefully hadn’t visited before. Sue did a magnificent job navigating the sometimes tiny roads in a rental car, despite Dan being a nervous Nellie in the passenger seat.

We had a lovely couple of days in Glengarriff, even though the weather wasn’t great. On the way back to Cork city, we just had to stop off in Baltimore—Dan and Sue live in the other Baltimore. I wasn’t prepared for the magnificent and rugged coastline (quite different to its Maryland counterpart).

Boston

We were back in Brighton for just one day before it was time for us to head to our next destination. We flew to Boston and spent a few days hanging around in Cambridge with our dear friends Ethan and Liz. It was a real treat to just pass the time with good people. It had been far too long.

I did manage to squeeze in an Irish music session in the legendary Druid pub. ’Twas a good night.

Pittsburgh

From Boston we went on to Pittsburgh for Frostapalooza. I’ve already told you all about how great that was:

It was joyous!

Saint Augustine

After all the excitement of Frostapalooza, Jessica and I went on to spend a week decompressing in Saint Augustine, Florida.

We went down to the beach every day. We went in the water most days. Sometimes the water was a bit too choppy for a proper swim, but it was still lovely and warm. And there was one day when the water was just perfectly calm.

When we weren’t on the beach, we were probably eating shrimp.

It was all very relaxing.

Brighton

I’ve spent the sixth and final week of my sabbatical back in Brighton. The weather has remained good so there’s been plenty of outdoor activities, including a kayaking trip down the river Medway in Kent. I may have done some involuntary wild swimming at one point.

I have very much enjoyed these past six weeks. Music. Travel. Friends. It’s all been quite lovely.

Me dressed in denim playing my red mandolin in a pub flanked by two women playing fiddle. A selfie of me in a cockpit with a headset on sitting next to Andy Budd who is flying, complete with aviator sunglasses. Me standing near a sign in the woods with a robin redbreast perched on it. Tiny figures in the distance at the bottom of a tapered tower on a cliff top. Checked in at Harvard Yard. Parkin the cah* in the Hahvahd Yahd (* butt) — with Jessica A man playing banjo and a woman playing bass ukulele on lawn furniture outdoors. A profile shot of me on stage with my mandolin singing with one arm extended. A woman stands holding her shoes on a sandy beach under a dramatic cloudy sky.

Frostapalooza

So Frostapalooza happened on Saturday.

It was joyous!

It all started back in July of last year when I got an email from Brad:

Next summer I’m turning 40, and I’m going to use that milestone as an excuse to play a big concert with and for all of my friends and family. It’ll sorta be like The Last Waltz, but with way more web nerds involved.

Originally it was slated for July of 2024, which was kind of awkward for me because it would clash with Belfast Trad Fest but I said to mark me down as interested. Then when the date got moved to August of 2024, it became more doable. I knew that Jessica and I would be making a transatlantic trip at some point anyway to see her parents, so we could try to combine the two.

In fact, the tentative plans we had to travel to the States in April of 2024 for the total solar eclipse ended up getting scrapped in favour of Brad’s shindig. That’s right—we chose rock’n’roll over the cosmic ballet.

Over the course of the last year, things began to shape up. There were playlists. There were spreadsheets. Dot voting was involved.

Anyone with any experience of playing live music was getting nervous. It’s hard enough to rehearse and soundcheck for a four piece, but Brad was planning to have over 40 musicians taking part!

We did what we could from afar, choosing which songs to play on, recording our parts and sending them onto Brad. Meanwhile Brad was practicing like hell with the core band. With Brad on bass and his brother Ian on drums for the whole night, we knew that the rhythm section would be tight.

A few months ago we booked our flights. We’d fly into to Boston first to hang out with Ethan and Liz (it had been too long!), then head down to Pittsburgh for Frostapalooza before heading on to Florida to meet up with Jessica’s parents.

When we got to Pittsburgh, we immediately met up with Chris and together we headed over to Brad’s for a rehearsal. We’d end up spending a lot of time playing music with Chris over the next couple of days. I loved every minute of it.

The evening before Frostapalooza, Brad threw a party at his place. It was great to meet so many of the other musicians he’d roped into this.

Then it was time for the big day. We had a whole afternoon to soundcheck, but we needed it. Drums, a percussion station, a horn section …not to mention all the people coming and going on different songs. Fortunately the tech folks at the venue were fantastic and handled it all with aplomb.

We finished soundchecking around 5:30pm. Doors were at 7pm. Time to change into our rock’n’roll outfits and hang out backstage getting nervous and excited.

Right before showtime, Brad gave a heartfelt little speech.

Then the fun really began.

I wasn’t playing on the first few songs so I got to watch the audience’s reaction as they realised what was in store. Maybe they thought this would be a cute gathering of Brad and his buddies jamming through some stuff. What they got was an incredibly tight powerhouse of energy from a seriously awesome collection of musicians.

I had the honour of playing on five songs over the course of the night. I had an absolute blast! But to be honest, I had just as much fun being in the audience dancing my ass off.

Oh, I was playing mandolin. I probably should’ve mentioned that.

Me on stage with my mandolin.

The first song I played on was The Weight by The Band. There was a real Last Waltz vibe as Brad’s extended family joined him on stage, along with me and and Chris.

The Band - The Weight Later I hopped on stage as one excellent song segued into another—Maps by Yeah Yeah Yeahs.

Yeah Yeah Yeahs - Maps (Official Music Video)

I’ve loved this song since the first time I heard it. In the dot-voting rounds to figure out the set list, this was my super vote.

You know the way it starts with that single note tremelo on the guitar? I figured that would work on the mandolin. And I know how to tremelo.

Jessica was on bass. Jessi Hall was on vocals. It. Rocked.

I stayed on stage for Radiohead’s The National Anthem complete with horns, musical saw, and two basses played by Brad and Jessica absolutely killing it. I added a little texture over the singing with some picked notes on the mandolin.

The National Anthem

Then it got truly epic. We played Wake Up by Arcade Fire. So. Much. Fun! Again, I laid down some tremelo over the rousing chorus. I’m sure no one could hear it but it didn’t matter. Everyone was just lifted along by the sheer scale of the thing.

Arcade Fire - Wake Up (Official Audio)

That was supposed to be it for me. But during the rehearsal the day before, I played a little bit on Fleetwood Mac’s The Chain and Brad said, “You should do that!”

The Chain (2004 Remaster)

So I did. I think it worked. I certainly enjoyed it!

With that, my musical duties were done and I just danced and danced, singing along to everything.

At the end of the night, everyone got back on stage. It was a tight fit. We then attempted to sing Bohemian Rhapsody together. It was a recipe for disaster …but amazingly, it worked!

That could describe the whole evening. It shouldn’t have worked. It was far too ambitious. But not only did it work, it absolutely rocked!

What really stood out for me was how nice and kind everyone was. There was nary an ego to be found. I had never met most of these people before but we all came together and bonded over this shared creation. It was genuinely special.

Days later I’m still buzzing from it all. I’m so, so grateful to Brad and Melissa for pulling off this incredible feat, and for allowing me to be a part of it.

They’ve had a shitty few years. I know we all had a shitty time over the past few years, but the shit kept on coming for them:

And then in the middle of this traumatic medical emergency, our mentally-unstable neighbor across the street began accosting my family, flipping off our toddler and nanny, racially harassing my wife, and making violent threats. We fled our home for fear of our safety because he was out in the street exposing himself, shouting belligerence, and threatening violence.

After that, Brad started working with Project Healthy Minds. In fact, all the proceeds from Frostapalooza go to that organisation along with NextStep Pittsburgh.

Just think about that. Confronted with intimidation and racism, Brad and Melissa still managed to see the underlying systemic inequality, and work towards making things better for the person who drove them out of their home.

Good people, man. Good people.

I sincererly hope they got some catharsis from Frostapalooza. I can tell you that I felt frickin’ great after being part of an incredible event filled with joy and love and some of the best music I’ve ever heard.

There’s a write-up of Frostapalooza on CSS Tricks and Will Browar has posted his incredible photographs from the night—some seriously superb photography!

Web App install API

My bug report on Apple’s websites-in-the-dock feature on desktop has me thinking about how starkly different it is on mobile.

On iOS if you want to add a website to your home screen, good luck. The option is buried within the “share” menu.

First off, it makes no sense that adding something to your homescreen counts as sharing. Secondly, how is anybody supposed to know that unless they’re explicitly told.

It’s a similar situation on Android. In theory you can prompt the user to install a progressive web app using the botched BeforeInstallPromptEvent. In practice it’s a mess. What it actually does is defer the installation prompt so you can offer it a more suitable time. But it only works if the browser was going to offer an installation prompt anyway.

When does Chrome on Android decide to offer the installation prompt? It’s a mix of required criteria—a web app manifest, some icons—and an algorithmic spell determined by the user’s engagement.

Other browser makers don’t agree with this arbitrary set of criteria. They quite rightly say that a user should be able to add any website to their home screen if they want to.

What we really need is an installation API: a way to programmatically invoke the add-to-homescreen flow.

Now, I know what you’re going to say. The security and UX implications would be dire. But this should obviously be like geolocation or notifications, only available in secure contexts and gated by user interaction.

Think of it like adding something to the clipboard: it’s something the user can do manually, but the API offers a way to do it programmatically without opening it up to abuse.

(I’d really love it if this API also had a declarative equivalent, much like I want button type="share" for the Web Share API. How about button type="install"?)

People expect this to already exist.

The beforeinstallprompt flow is an absolute mess. Users deserve better.

Space dock

Apple announced some stuff about artificial insemination at their WorldWide Developer Conference, none of which interests me one whit. But we did get a twitch of the webkit curtains to let us know what’s coming in Safari. That does interest me.

I’m really pleased to see that on desktop, websites that have been added to the dock will be able to intercept links for that domain:

Now, when a user clicks a link, if it matches the scope of a web app that the user has added to their Dock, that link will open in the web app instead of their default web browser.

Excellent! This means that if I click on a link to thesession.org from, say, my Mastodon site-in-the-dock, it will open in The Session site-in-the-dock. Make sure you’ve got the scope property set in your web app manifest.

I have a few different sites added to my dock: The Session, Mastodon, Google Calendar. Sure beats the bloat of Electron apps.

I have encountered a small bug. I’ll describe it here because I have no idea where to file it.

It’s to do with Spaces, Apple’s desktop management thingy. Maybe they don’t call it Spaces anymore. Maybe it’s called Mission Control now. Or Stage Manager. I can’t keep track.

Anyway, here are the steps to reproduce:

  1. In Safari on Mac, go to a website like adactio.com
  2. From either the File menu or the share icon, select Add to dock.
  3. Click on the website’s icon in the dock to open it.
  4. Using Apple’s desktop management (Spaces?) available through the F3 key, drag that window to a desktop other than desktop 1.
  5. Right click on the site’s icon in the dock and select Options, then Assign To, then This Desktop.
  6. Quit the app/website.
  7. Return to desktop 1.

Expected behaviour: when I click on the icon in the dock to open the site, it will open in the desktop that it has been assigned to.

Observed behaviour: focus moves to the desktop that the site has been assigned to, but it actually opens in desktop 1.

If someone from Apple is reading, I hope that’s useful.

On the one hand, I hope this isn’t one of those bugs that only I’m experiencing because then I’ll feel foolish. On the other hand, I hope this is one of those bugs that only I’m experiencing because then others don’t have to put up with the buggy behaviour.

CSS Day 2024

My stint as one of the hosts of CSS Day went very well indeed. I enjoyed myself and people seemed to like the cut of my jib.

During the event there was a real buzz on Mastodon, which was heartening to see. I was beginning to worry that hashtagging events was going to be collatoral damage from Elongate, but there was plenty of conference-induced FOMO to be experienced on the fediverse.

The event itself was, as always, excellent. Both in terms of content and organisation.

Some themes emerged during CSS Day, which I always love to see. These emergent properties are partly down to curation and partly down to serendipity.

The last few years of CSS Day have felt like getting a firehose of astonishing new features being added to the language. There was still plenty of cutting-edge stuff this year—masonry! anchor positioning!—but there was also a feeling of consolidation, asking how to get all this amazing new stuff into our workflows.

Matthias’s opening talk on day one and Stephen’s closing talk on the same day complemented one another perfectly. Both managed to inspire while looking into the nitty-gritty practicalities of the web design process.

It was, astoundingly, Matthias’s first ever conference talk. I have no doubt it won’t be the last—it was great!

I gave Stephen a good-natured roast in my introduction, partly because it was his birthday, partly because we’re old friends, but mostly because it was enjoyable for me to watch him squirm. Of course his talk was, as always, superb. Don’t tell him, but he might be one of my favourite speakers.

The topic of graphic design tools came up more than once. It’s interesting to see how the issues with them have changed. It used to be that design tools—Photoshop, Sketch, Figma—were frustrating because they were writing cheques that CSS couldn’t cash. Now the frustration is the exact opposite. Our graphic design tools aren’t capable of the kind of fluid declarative design we can now accomplish in web browsers.

But the biggest rift remains not with tools or technologies, but with people and mindsets. Our tools can reinforce mindsets but the real divide happens in how different people approach CSS.

Both Josh and Kevin get to the heart of this in their tremendous tutorials, and that was reflected in their talks. They showed the difference between having the bare minimum understanding of CSS in order to get something done as quickly as possible, and truly understanding how CSS works in order to open up a world of possibilities.

For people in the first category, Sarah Dayan was there to sing the praises of utility-first CSS AKA atomic CSS. I commend her bravery!

During the Q&A, I restrained myself from being too Paxmanish. But I did have l’esprit d’escalier afterwards when I realised that the entire talk—and all the answers afterwards—depended on two mutually-incompatiable claims:

  1. The great thing about atomic CSS is that it’s a constrained vocabulary so your team has to conform, and
  2. The other great thing about it is that it’s utility-first, not utility-only so you can break out of it and use regular CSS if you want.

Insert .gif of character from The Office looking to camera.

Most of the questions coming in during the Q&A reflected my own take: how about we use utility classes for some things, but not all things. Seems sensible.

Anyway, regardless of what I or anyone else thinks about the substance of what Sarah was saying, there was no denying that it was a great presentation. They were all great presentations. That’s unusual, and I say that as a conference organiser as well as an attendee. Everyone brings their A-game to CSS Day.

Mind you, it is exhausting. I say it every year, but it always feels like one talk too many. Not that any individual talk wasn’t good, but the sheer onslaught of deep dives into the innards of CSS has my brain exploding before the day is done.

A highlight for me was getting to introduce Fantasai’s talk on the design principles of CSS, which was right up my alley. I don’t think most people realise just how much we owe her for her years of work on standards. The web would be in a worse place without the Herculean work she’s done behind the scenes.

Another highlight was getting to see some of the students I met back in March. They were showing some of their excellent work during the breaks. I find what they’re doing just as inspiring as the speakers on stage.

In fact, when I was filling in the post-conference feedback form, there was a question: “Who would you like to see speak at CSS Day next year?” I was racking my brains because everyone I could immediately think of has already spoken at some point. So I wrote, “It would be great to see some of those students speaking about their work.”

I think it would be genuinely fascinating to get their perspective on what we consider modern CSS, which to them is just CSS.

Either way I’ll back next year for sure.

It’s funny, but usually when a conference is described as “inspiring” it’s because it’s tackling big galaxy-brain questions. But CSS Day is as nitty-gritty as it gets and I found it truly inspiring. Like, I couldn’t wait to open up my laptop and start writing some CSS. That kind of inspiring.