Jeremy Keith

Jeremy Keith

Making websites. Writing books. Hosting a podcast. Speaking at events. Living in Brighton. Working at Clearleft. Playing music. Taking photos. Answering email.

Journal 3154 Links 10609 Articles 87 Notes 7779

Friday, May 16th, 2025

Thursday, May 15th, 2025

Awareness

Today is Global Accessibility Awareness Day:

The purpose of GAAD is to get everyone talking, thinking and learning about digital access and inclusion, and the more than One Billion people with disabilities/impairments.

Awareness is good. It’s necessary. But it’s not sufficient.

Accessibility, like sustainability and equality, is the kind of thing that most businesses will put at the end of sentences that begin “We are committed to…”

It’s what happens next that matters. How does that declared commitment—that awareness—turn into action?

In the worst-case scenario, an organisation might reach for an accessibility overlay. Who can blame them? They care about accessibility. They want to do something. This is something.

Good intentions alone can result in an inaccessible website. That’s why I think there’s another level of awareness that’s equally important. Designers and developers need to be aware of what they can actually do in service of accessibility.

Fortunately that’s not an onerous expectation. It doesn’t take long to grasp the importance of having good colour contrast or using the right HTML elements.

An awareness of HTML is like a superpower when it comes to accessibility. Like I wrote in the foreword to the Web Accessibility Cookbook by O’Reilly:

It’s supposed to be an accessibility cookbook but it’s also one of the best HTML tutorials you’ll ever find. Come for the accessibility recipe; stay for the deep understanding of markup.

The challenge is that HTML is hidden. Like Cassie said in the accessibility episode of The Clearleft Podcast:

You get JavaScript errors if you do that wrong and you can see if your CSS is broken, but you don’t really have that with accessibility. It’s not as obvious when you’ve got something wrong.

We are biased towards what we can see—hierarchy, layout, imagery, widgets. Those are the outputs. When it comes to accessibility, what matters is how those outputs are generated. Is that button actually a button element or is it a div? Is that heading actually an h1 or is it another div?

This isn’t about the semantics of HTML. This is about the UX of HTML:

Instead of explaining the meaning of a certain element, I show them what it does.

That’s the kind of awareness I’m talking about.

One way of gaining this awareness is to get a feel for using a screen reader.

The name is a bit of a misnomer. Reading the text on screen is the least important thing that the software does. The really important thing that a screen reader does is convey the structure of what’s on screen.

Friend of Clearleft, Jamie Knight very generously spent an hour of his time this week showing everyone the basics of using VoiceOver on a Mac (there’s a great short video by Ethan that also covers this).

Using the rotor, everyone was able to explore what’s under the hood of a web page; all the headings, the text of all the links, the different regions of the page.

That’s not going to turn anyone into an accessibility expert overnight, but it gave everyone an awareness of how much the HTML matters.

Mind you, accessibility is a much bigger field than just screen readers.

Fred recently hosted a terrific panel called Is neurodiversity the next frontier of accessibility in UX design?—well worth a watch!

One of those panelists—Craig Abbott—is speaking on day two of UX London next month. His talk has the magnificent title, Accessibility is a design problem:

I spend a bit of time covering some misconceptions about accessibility, who is responsible for it, and why it’s important that we design for it up front. It also includes real-world examples where design has impacted accessibility, before moving onto lots of practical guidance on what to be aware of and how to design for many different accessibility issues.

Get yourself a ticket and get ready for some practical accessibility awareness.

Wednesday, May 14th, 2025

Craig Mod on the Creative Power of Walking ‹ Literary Hub

When I’m not talking, just walking (which is most of the time), I try to cultivate the most bored state of mind imaginable. A total void of stimulation beyond the immediate environment. My rules: No news, no social media, no podcasts, no music. No “teleporting,” you could say. The phone, the great teleportation device, the great murderer of boredom. And yet, boredom: the great engine of creativity. I now believe with all my heart that it’s only in the crushing silences of boredom—without all that black-mirror dopamine — that you can access your deepest creative wells. And for so many people these days, they’ve never so much as attempted to dip in a ladle, let alone dive down into those uncomfortable waters made accessible through boredom.

Page Embedded Permission Control (` permission ` element)

This is an interesting proposal for a declarative way of triggering permission dialogs, although it seems to overlap with the work being done on invokers (command and commandfor).

What really disgusts me is to see Google referring to this element as though it’s a done deal. It’s not. It’s a proposal …a proposal that Apple rejects and Mozilla rejects.

Words matter. Call your proposal a proposal, Google.

Update: They fixed it!

The beauty ain’t in the necklace. It’s in the neck.

Maybe that’s my problem with AI-generated prose: it’s all necklace, no neck.

— Adam Mastroianni

Tuesday, May 13th, 2025

A tiny taxonomy of meetings

Meetings can be frustrating. But they don’t have to be.

A lot of the frustration comes from unmet expectations. You go into the meeting expecting one outcome, and when it doesn’t materialise, you declare the meeting a waste of time. But had you gone into that same meeting with different expectations, perhaps you would emerge from it in a happier state.

We were talking about this at Clearleft recently and I suggested that a simple little taxonomy of meetings might be a good starting point for avoiding frustration.

Divergent meetings

In a divergent meeting the goal is to generate ideas. These meetings often happen early in a project.

Quantity matters more than quality. Plenty of “yes, and…” rather than “no, but…” to create lots of suggestions. This is not the meeting to point out potential problems with the suggestions.

Convergent meetings

In a convergent meeting the goal is to come to a decision.

The meeting might begin with lots of options on the table. They need to be winnowed down. Poke at them. Dissect them. Ideally dismiss lots of them.

This is not the time to introduce new ideas—save that for a divergent meeting.

Just having those two categories alone could save you a lot of grief. The last thing you want is someone participating in a convergent meeting who thinks it’s a divergent meeting (or the other way around).

Those two categories account for the majority of meetings, but there’s one more category to consider…

Chemistry meetings

In a chemistry meeting there is no tangible output. The goal is to get to know one another.

In a large organisation this might be when multiple departments are going to work together on a project. At an agency like Clearleft, a chemistry meeting between us and the client team is really useful at the beginning of our partnership.

Again, the key thing is expectations. If there are people in a chemistry meeting who are expecting to emerge with a framework or a list or any kind of output, they’re going to be frustrated. But if everyone knows it’s a chemistry meeting there’s no expectation that any decisions are going to be made.

There you have it. A tiny taxonomy of meetings:

  1. divergent
  2. convergent
  3. chemistry

This tiny taxonomy won’t cover every possible kind of meeting, but it probably covers 90% of them.

Ideally every meeting should be categorised in advance so that everyone’s going in with the same expectations.

If you find yourself trying to categorise a meeting and you think “Well, it’s mostly convergent, but there’s also this divergent aspect…” then you should probably have two separate shorter meetings instead.

And if you’re trying to categorise a meeting and you find yourself thinking, “This meeting is mostly so I can deliver information” …that meeting should be an email.

Monday, May 12th, 2025

Sunday, May 11th, 2025

Saturday, May 10th, 2025

Friday, May 9th, 2025

Thursday, May 8th, 2025

The closing talks at UX London 2025

It’s just over one month until UX London. You should grab a ticket if you haven’t already!

The format of UX London is quite special. While the focus of each day is different—discovery, design, and delivery—each day unfolds like this…

There are four talks in the morning. You get your brain filled with ideas and learn from fantastic speakers. It’s a single track—everyone’s getting the same shared experience.

Then after a lunch, you choose from one of four workshops. Whatever you choose, it’s going to be hands-on. You can leave your laptop at home.

A day of listening to talks could get exhausting. A workshop that lasts all day could be even more exhausting. But somehow by splitting the day between both activities, the energy level is just right!

That said, we don’t want the day to end with everyone spread across four different workshop rooms. That’s why there’s one final talk at the end of each day.

These closing talks are a bit different to the morning talks. Whereas the focus of the morning talks is on practical skills that you can apply straight away, the closing talks are an opportunity to sit back and have your mind expanded. They’ll be fun and thought-provoking.

Paula Zuccotti is closing out day one with a talk about two of her projects: Every Thing We Touch and Future Archeology:

This talk invites audiences to reconsider the meaning of the objects they encounter every day and reflect on what their possessions might reveal about who we are and what we value, both now and in the years to come.

Sarah Hyndman will wrap up day two with a fun interactive talk about your senses:

Join a live expedition into our inner world to explore why we see, feel and remember.

Finally, Rachel Coldicutt is going to finish UX London with a rallying cry:

Introducing the Society of Hopeful Technologists and discussing how, in modern technology development, your practice is probably more political than you realise.

I can’t wait! Get yourself a ticket for a day or for all three days.

And as a little thank you for tolerating my excitement, use the discount code JOINJEREMY to get 20% off your ticket.

CSS snippets

I’ve been thinking about the kind of CSS I write by default when I start a new project.

Some of it is habitual. I now use logical properties automatically. It took me a while to rewire my brain, but now seeing left or top in a style sheet looks wrong to me.

When I mentioned this recently, I had some pushback from people wondering why you’d bother using logical properites if you never planned to translate the website into a language with a different writing system. I pointed out that even if you don’t plan to translate a web page, a user may still choose to. Using logical properties helps them. From that perspective, it’s kind of like using user preference queries.

That’s something else I use by default now. If I’ve got any animations or transitions in my CSS, I wrap them in prefers-reduced-motion: no-preference query.

For instance, I’m a huge fan of view transitions and I enable them by default on every new project, but I do it like this:

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

I’ll usually have a prefers-color-scheme query for dark mode too. This is often quite straightforward if I’m using custom properties for colours, something else I’m doing habitually. And now I’m starting to use OKLCH for those colours, even if they start as hexadecimal values.

Custom properties are something else I reach for a lot, though I try to avoid premature optimisation. Generally I wait until I spot a value I’m using more than two or three times in a stylesheet; then I convert it to a custom property.

I make full use of clamp() for text sizing. Sometimes I’ll just set a fluid width on the html element and then size everything else with ems or rems. More often, I’ll use Utopia to flow between different type scales.

Okay, those are all features of CSS—logical properties, preference queries, view transitions, custom properties, fluid type—but what about actual snippets of CSS that I re-use from project to project?

I’m not talking about a CSS reset, which usually involves zeroing out the initial values provided by the browser. I’m talking about tiny little enhancements just one level up from those user-agent styles.

Here’s one I picked up from Eric that I apply to the figcaption element:

figcaption {
  max-inline-size: max-content;
  margin-inline: auto;
}

That will centre-align the text until it wraps onto more than one line, at which point it’s no longer centred. Neat!

Here’s another one I start with on every project:

a:focus-visible {
  outline-offset: 0.25em;
  outline-width: 0.25em;
  outline-color: currentColor;
}

That puts a nice chunky focus ring on links when they’re tabbed to. Personally, I like having the focus ring relative to the font size of the link but I know other people prefer to use a pixel size. You do you. Using the currentColor of the focused is usually a good starting point, thought I might end up over-riding this with a different hightlight colour.

Then there’s typography. Rich has a veritable cornucopia of starting styles you can use to improve typography in CSS.

Something I’m reaching for now is the text-wrap property with its new values of pretty and balance:

ul,ol,dl,dt,dd,p,figure,blockquote {
  hanging-punctuation: first last;
  text-wrap: pretty;
}

And maybe this for headings, if they’re being centred:

h1,h2,h3,h4,h5,h6 {
  text-align: center;
  text-wrap: balance;
}

All of these little snippets should be easily over-writable so I tend to wrap them in a :where() selector to reduce their specificity:

:where(figcaption) {
  max-inline-size: max-content;
  margin-inline: auto;
}
:where(a:focus-visible) {
  outline-offset: 0.25em;
  outline-width: 0.25em;
  outline-color: currentColor;
}
:where(ul,ol,dl,dt,dd,p,figure,blockquote) {
  hanging-punctuation: first last;
  text-wrap: pretty;
}

But if I really want them to be easily over-writable, then the galaxy-brain move would be to put them in their own cascade layer. That’s what Manu does with his CSS boilerplate:

@layer core, third-party, components, utility;

Then I could put those snippets in the core layer, making sure they could be overwritten by the CSS in any of the other layers:

@layer core {
  figcaption {
    max-inline-size: max-content;
    margin-inline: auto;
  }
  a:focus-visible {
    outline-offset: 0.25em;
    outline-width: 0.25em;
    outline-color: currentColor;
  }
  ul,ol,dl,dt,dd,p,figure,blockquote {
    hanging-punctuation: first last;
    text-wrap: pretty;
  }
}

For now I’m just using :where() but I think I should start using cascade layers.

I also want to start training myself to use the lh value (line-height) for block spacing.

And although I’m using the :has() selector, I don’t think I’ve yet trained my brain to reach for it by default.

CSS has sooooo much to offer today—I want to make sure I’m taking full advantage of it.

Wednesday, May 7th, 2025

Older »