In a way, I find these pictures—taken by someone from the ground with regular equipment—just as awe-inspiring as the images from the James Webb Space Telescope.
Monday, November 7th, 2022
Thursday, September 8th, 2022
A no-nonsense checklist of good performance advice from Karolina.
Sunday, June 19th, 2022
I’m standing on a huge stage in a giant hangar-like room already filled with at least a thousand people. More are arriving. I’m due to start speaking in a few minutes. But there’s a problem with my laptop. It connects to the external screen, then disconnects, then connects, then disconnects. The technicians are on the stage with me, quickly swapping out adaptors and cables as they try to figure out a fix.
This is a pretty standard stress dream for me. Except this wasn’t a dream. This was happening for real at the giant We Are Developers World Congress in Berlin last week.
In the run-up to the event, the organisers had sent out emails about providing my slide deck ahead of time so it could go on a shared machine. I understand why this makes life easier for the people running the event, but it can be a red flag for speakers. It’s never quite the same as presenting from your own laptop with its familiar layout of the presentation display in Keynote.
Fortunately the organisers also said that I could present from my own laptop if I wanted to so that’s what I opted for.
One week before the talk in Berlin I was in Amsterdam for CSS Day. During a break between talks I was catching up with Michelle. We ended up swapping conference horror stories around technical issues (prompted by some of our fellow speakers having issues with Keynote on the brand new M1 laptops).
Michelle told me about a situation where she was supposed to be presenting from her own laptop, but because of last-minute technical issues, all the talks were being transferred to a single computer via USB sticks.
“But the fonts!” I said. “Yes”, Michelle responded. Even though she had put the fonts on the USB stick, things got muddled in the rush. If you open the Keynote file before installing the fonts, Keynote will perform font substitution and then it’s too late. This is exactly what happened with Michelle’s code examples, messing them up.
“You know”, I said, “I was thinking about having a back-up version of my talks that’s made entirely out of images—export every slide as an image, then make a new deck by importing all those images.”
“I’ve done that”, said Michelle. “But there isn’t a quick way to do it.”
I was still thinking about our conversation when I was on the Eurostar train back to England. I had plenty of time to kill with spotty internet connectivity. And that huge Berlin event was less than a week away.
I opened up the Keynote file of the Berlin presentation. I selected
Then I created a new blank deck ready for the painstaking work that Michelle had warned me about. I figured I’d have to drag in each image individually. The presentation had 89 slides.
But I thought it was worth trying a shortcut first. I selected all of the images in Finder. Then I dragged them over to the far left column in Keynote, the one that shows the thumbnails of all the slides.
Each image was now its own slide. I selected all 89 slides and applied my standard transition: a one second dissolve.
That was pretty much it. I now had a version of my talk that had no fonts whatsoever.
If you’re going to try this, it works best if don’t have too many transitions within slides. Like, let’s say you’ve got three words that you introduce—by clicking—one by one. You could have one slide with all three words, each one with its own build effect. But the other option is to have three slides: each one like the previous slide but with one more word added. If you use that second technique, then the exporting and importing will work smoothly.
Oh, and if you have lots and lots of notes, you’ll have to manually copy them over. My notes tend to be fairly minimal—a few prompts and the occasional time check (notes that say “5 minutes” or “10 minutes” so I can guage how my pacing is going).
Back to that stage in Berlin. The clock is ticking. My laptop is misbehaving.
One of the other speakers who will be on later in the day was hoping to test his laptop too. It’s Håkon. His presentation includes in-browser demos that won’t work on a shared machine. But he doesn’t get a chance to test his laptop just yet—my little emergency has taken precedent.
“Luckily”, I tell him, “I’ve got a backup of my presentation that’s just images to avoid any font issues.” He points out the irony: we spent years battling against the practice of text-as-images on the web and now here we are using that technique once again.
My laptop continues to misbehave. It connects, it disconnects, connects, disconnects. We’re going to have to run the presentation from the house machine. I’m handed a USB stick. I put my images-only version of the talk on there. I’m handed a clicker (I can’t use my own clicker with the house machine). I’m quickly ushered backstage while the MC announces my talk, a few minutes behind schedule.
It works. It feels a little strange not being able to look at my own laptop, but the on-stage monitors have the presentation display including my notes. The unfamiliar clicker feels awkward but hopefully nobody notices. I deliver my talk and it seems to go over well.
I think I’ll be making image-only versions of all my talks from now on. Hopefully I won’t ever need them, but just knowing that the backup is there is reassuring.
Mind you, if you’re the kind of person who likes to fiddle with your slides right up until the moment of presenting, then this technique won’t be very useful for you. But for me, not being able to fiddle with my slides after a certain point is a feature, not a bug.
Monday, May 30th, 2022
Saturday, May 28th, 2022
Prompted by my recent post on
alt text, Geoff shares some resources on the right length for
Wednesday, May 25th, 2022
I made the website for this year’s UX London by hand.
So it’s minium viable static site generation rather than actual static files. It’s still very hands-on though and I enjoy that a lot; editing HTML and CSS directly without intermediary tools.
When I update the site, it’s usually to add a new speaker to the line-up (well, not any more now that the line up is complete). That involves marking up their bio and talk description. I also create a couple of different sized versions of their headshot to use with
srcset. And of course I write an
alt attribute to accompany that image.
By the way, Jake has an excellent article on writing
alt text that uses the specific example of a conference site. It raises some very thought-provoking questions.
I enjoy writing
alt text. I recently described how I updated my posting interface here on my own site to put a
alt text front and centre for my notes with photos. Since then I’ve been enjoying the creative challenge of writing useful—but also evocative—
Some recent examples:
- Time to go play some songs with @SalterCane.
A close-up of a microphone in a practice room. In the background, a guitar player tunes up and a bass player waits to start.
- Brighton in the sun.
People sitting around in the dappled sunshine on the green grass in a park with the distinctive Indian-inspired architecture of the Brighton Pavilion in the background, all under a clear blue sky.
- Duck leg on white beans with sage, garlic, rosemary and olives.
Looking down on the crispy browned duck leg contrasting with the white beans, all with pieces of green fried herbs scattered throughout.
But when I was writing the
alt text for the headshots on the UX London site, I started to feel a little disheartened. The more speakers were added to the line-up, the more I felt like I was repeating myself with the
alt text. After a while they all seemed to be some variation on “This person looking at the camera, smiling” with maybe some detail on their hair or clothing.
- Videha Sharma
The beaming bearded face of Videha standing in front of the beautiful landscape of a riverbank.
- Candi Williams
Candi working on her laptop, looking at the camera with a smile.
- Emma Parnell
Emma smiling against a yellow background. She’s wearing glasses and has long straight hair.
- John Bevan
A monochrome portrait of John with a wry smile on his face, wearing a black turtleneck in the clichéd design tradition.
- Laura Yarrow
Laura smiling, wearing a chartreuse coloured top.
- Adekunle Oduye
A profile shot of Adekunle wearing a jacket and baseball cap standing outside.
The more speakers were added to the line-up, the harder I found it not to repeat myself. I wondered if this was all going to sound very same-y to anyone hearing them read aloud.
But then I realised, “Wait …these are kind of same-y images.”
By the very nature of the images—headshots of speakers—there wasn’t ever going to be that much visual variation. The experience of a sighted person looking at a page full of speakers is that after a while the images kind of blend together. So if the
alt text also starts to sound a bit repetitive after a while, maybe that’s not such a bad thing. A screen reader user would be getting an equivalent experience.
That doesn’t mean it’s okay to have the same
alt text for each image—they are all still different. But after I had that realisation I stopped being too hard on myself if I couldn’t come up with a completely new and original way to write the
And, I remind myself, writing
alt text is like any other kind of writing. The more you do it, the better you get.
Sunday, May 15th, 2022
Image previews with the FileReader API
I added a “notes” section to this website eight years ago. I set it up so that notes could be syndicated to Twitter. Ever since then, that’s the only way I post to Twitter.
A few months later I added photos to my notes. Again, this would get syndicated to Twitter.
Something’s bothered me for a long time though. I initially thought that if I posted a photo, then the accompanying text would serve as a decription of the image. It could effectively act as the
alt text for the image, I thought. But in practice it didn’t work out that way. The text was often a commentary on the image, which isn’t the same as a description of the contents.
I needed a way to store
alt text for images. To make it more complicated, it was possible for one note to have multiple images. So even though a note was one line in my database, I somehow needed a separate string of text with the description of each image in a single note.
I eventually settled on using the file system instead of the database. The images themselves are stored in separate folders, so I figured I could have an accompanying
alt.txt file in each folder.
Take this note from yesterday as an example. Different sizes of the image are stored in the folder
/images/uploaded/19077. Here’s a small version of the image and here’s the original. In that same folder is the
This means I’m reading a file every time I need the
alt text instead of reading from a database, which probably isn’t the most performant way of doing it, but it seems to be working okay.
Here’s another example:
In order to add the
alt text to the image, I needed to update my posting interface. By default it’s a little
textarea, followed by a file upload
input, followed by a toggle (a checkbox under the hood) to choose whether or not to syndicate the note to Twitter.
The interface now updates automatically as soon as I use that
input type="file" to choose any images for the note. Using the
FileReader API, I show a preview of the selected images right after the file input.
Here’s the code if you ever need to do something similar. I’ve abstracted it somewhat in that gist—you should be able to drop it into any page that includes
input type="file" accept="image/*" and it will automatically generate the previews.
I was pleasantly surprised at how easy this was. The
FileReader API worked just as expected without any gotchas. I think I always assumed that this would be quite complex to do because once upon a time, it was quite complex (or impossible) to do. But now it’s wonderfully straightforward. Story of the web.
My own version of the script does a little bit more; it also generates another little
textarea right after each image preview, which is where I write the accompanying
I’ve also updated my server-side script that handles the syndication to Twitter. I’m using the
/media/metadata/create method to provide the
alt text. But for some reason it’s not working. I can’t figure out why. I’ll keep working on it.
In the meantime, if you’re looking at an image I’ve posted on Twitter and you’re judging me for its lack of
alt text, my apologies. But each tweet of mine includes a link back to the original note on this site and you will most definitely find the
alt text for the image there.
Tuesday, April 12th, 2022
Addy takes a deep dive into making sure your images are performant. There’s a lot to cover here—that’s why I ended up splitting it in two for the responsive design course: one module on responsive images and one on the
Friday, February 11th, 2022
To mark the start of the Dark Skies Festival today, here are some fantastic photographics taken not that far from Brighton.
Tuesday, January 4th, 2022
In which Rob takes a deep dive into isometric projection and then gets generative with it.
Saturday, December 11th, 2021
More writing on web.dev
Last month I wrote about writing on web.dev. At that time, the first five parts of a fourteen-part course on responsive design had been published. I’m pleased to say that the next five parts are now available. They are:
It wasn’t planned, but these five modules feel like they belong together. The first five modules were concerned with layout tools—media queries, flexbox, grid, and even container queries. The latest five modules are about the individual elements of design—type, colour, and images. But those elements are examined through the lens of responsiveness; responsive typography with
clamp, responsive colour with
prefers-color-scheme, and responsive images with
The final five modules should be available later this month. In the mean time, I hope you like the first ten modules.
Thursday, September 30th, 2021
Want to take a deep dive into tiling images? Like, a really deep dive. Rob has you covered.
Sunday, September 26th, 2021
A non-profit foundation dedicated to long-term digital preservation.
Imagine if we could place ourselves 100 years into the future and still have access to the billions of photos shared by millions of people on Flickr, one of the best documented, broadest photographic archives on the planet.
The Flickr Foundation represents our commitment to stewarding this digital, cultural treasure to ensure its existence for future generations.
Its first act is the renewal of the Flickr Commons.
Monday, September 20th, 2021
Here’s a nifty little service from Zach: pass in a URL and it returns an image of the site’s icon.
Think of it as the indie web alternative to showing Twitter avatars.
Thursday, September 16th, 2021
A nice little collection of very simple—and very lightweight—SVGs to use as background patterns.
Tuesday, September 14th, 2021
I was doing some accessibility work with a client a little while back. It was mostly giving their site the once-over, highlighting any issues that we could then discuss. It was an audit of sorts.
While I was doing this I started to realise that not all accessibility issues are created equal. I don’t just mean in their severity. I mean that some issues can—and should—be caught early on, while other issues can only be found later.
Take colour contrast. This is something that should be checked before a line of code is written. When designs are being sketched out and then refined in a graphical editor like Figma, that’s the time to check the ratio between background and foreground colours to make sure there’s enough contrast between them. You can catch this kind of thing later on, but by then it’s likely to come with a higher cost—you might have to literally go back to the drawing board. It’s better to find the issue when you’re at the drawing board the first time.
Then there’s the HTML. Most accessibility issues here can be caught before the site goes live. Usually they’re issues of ommission: form fields that don’t have an explicitly associated
label element (using the
id attributes); images that don’t have
alt text; pages that don’t have sensible heading levels or landmark regions like
nav. None of these are particularly onerous to fix and they come with the biggest bang for your buck. If you’ve got sensible forms, sensible headings,
alt text on images, and a solid document structure, you’ve already covered the vast majority of accessibility issues with very little overhead. Some of these checks can also be automated:
alt text for images;
labels for inputs.
So if you commission an accessibility audit, you should hope to get feedback that’s mostly in that third category—interactive widgets.
If you get feedback on document structure and other semantic issues with the HTML, you should fix those issues, sure, but you should also see what you can do to stop those issues going live again in the future. Perhaps you can add some steps in the build process. Or maybe it’s more about making sure the devs are aware of these low-hanging fruit. Or perhaps there’s a framework or content management system that’s stopping you from improving your HTML. Then you need to execute a plan for ditching that software.
If you get feedback about colour contrast issues, just fixing the immediate problem isn’t going to address the underlying issue. There’s a process problem, or perhaps a communication issue. In that case, don’t look for a technical solution. A design system, for example, will not magically fix a workflow issue or route around the problem of designers and developers not talking to each other.
When you commission an accessibility audit, you want to make sure you’re getting the most out of it. Don’t squander it on issues that you can catch and fix yourself. Make sure that the bulk of the audit is being spent on the specific issues that are unique to your site.
Wednesday, April 28th, 2021
Beautifully restored high-resolution photographs of the Earth taken by Apollo astronauts.
Tuesday, April 6th, 2021
Tuesday, March 23rd, 2021
Visualising the growth of the internet.
Wednesday, December 2nd, 2020
There’s no browser support yet but that doesn’t mean we can’t start adding
prefers-reduced-data to our media queries today. I like the idea of switching between web fonts and system fonts.