Journal tags: design

304

Codestin Search App

The datalist element on iOS 26

The datalist element is all fucked up on iOS. Again.

I haven’t “upgraded” my iPhone to iOS 26 and I have no plans to. The whole Liquid Glass thing is literally offputting. So I wouldn’t have known about the latest regression in Safari if a friend hadn’t texted me about the problem.

He was trying to do a search on The Session. He was looking for the tune, The Road To Town. He started typing this into the form on the home page of the site. He got as far as “The Road To”. That’s when the entire input was obscured by a suggestion from the associated datalist.

A screenshot of The Session on an iPhone during a search on the homepage. The search input is completely obscured by the text: The Road To Lisdoonvarna.

This is incredibly annoying and seems to be a pattern of behaviour for Safari. Features are supported …technically. But the implementation is so buggy as to be unusable.

I’ll probably have to do some user-agent sniffing, which I hate. And it won’t be enough to just sniff for Safari on iOS 26. Remember that every browser on iOS is just Webkit in a trenchcoat.

Time to file a bug and then wait God knows how long for an update to get rolled out.

Update: I filed a bug, but in the meantime it looks like user-agent sniffing is going to be impossible.

Tunes and typefaces

In an Irish session, tunes are almost never played in isolation. They’re played in sets.

A set of tunes might be as few as two. More usually, it’s three or more.

It’s unusual to change from one tune type into another. You tend to get a set of jigs, or a set of reels, or a set of hornpipes. But it’s very common to change key within a set. In fact, that’s often where a good set really stands out. There can be a real joy at that moment of switching. You might get a “Hup!” from someone listening to the session at that changeover.

So how do you decide what tunes to play in a set?

There are no real rules to this. Some people make up the set on the fly. Or you might try playing a set that you’ve heard other people play, maybe on a recording you like.

On the one hand, you’re looking for contrast. You probably don’t want to play three tunes all in the same key. On the other hand, it’s nice when there’s some kind of connection between the tunes—something about the phrasing or emphasis perhaps.

Pairing tunes for sets always reminds me of pairing typefaces. You don’t want the body copy and the headlines to be too similar, but you do want them to share some quality.

In his classic book, On Web Typography, Jason says:

When it comes to choosing and pairing typefaces, I keep two things in mind: distinction and harmony. To keep the system you’ve created for visual communication properly balanced, you need to choose typefaces that don’t compete too much with each other, but aren’t so similar as to be indistinguishable.

The same could be said for pairing tunes in sets!

Jason also says:

As another approach, opt for typefaces that share the same maker.

That can work for sets of tunes too. While most tunes are traditional, with no known composer, the really good composed tunes have entered the canon.

I’ve taken Jason’s advice for typefaces and applied to sets by playing a set of tunes by Junior Crehan or a set of tunes by Vincent Broderick.

Mostly though, there’s no real system to it. Or at least, not one that can be easily articulated. Like Jason says:

And we’re back to that old chestnut about rules: there are many right answers, and no answers are really wrong; there are just different degrees of good.

Skip intro

There’s the old adage “nobody gets fired for buying IBM”. Or to put it more broadly, “everyone else is doing it.”

It’s dispiriting how often this explanation is given as justification for a dubious design decision, from home-page carousels to cookie banners.

Nic Chan has written a great post about designing a contact form and how the process was derailed by the client pointing to other people’s contact forms …even when they’ve got very, very different user needs.

It’s especially depressing when “everyone else is doing it” is used a substitute for any kind of accountability.

Building an email service that’s going to track when people click on links in an email? That sounds dodgy. On the other hand, everyone else is doing it.

Building a straightforward website, but making it a single-page app with client-side React that will be barely work on some devices and networks? That seems over-engineered. On the other hand, everyone else is doing it.

Sometimes the “everyone else is doing it” phenomenon leads to a chain reaction where nobody even knows why anyone ever did it in the first place.

Remember Flash? Remember when almost every website had a Flash intro? Everyone knew they were annoying and uneccessary, but everyone else was doing it.

Instead of getting rid of the intros, we got “skip intro” links instead. This link was guaranteed to have a 100% clickthrough rate.

I’ve noticed something similar with conference talks. So many of them begin with a little spiel about the speaker, their background, and their work experience.

This might be interesting information, but this isn’t the right time or place for it. It’s already on the conference website, in the conference programme, and has probably just been reiterated by the conference host who just introduced the speaker.

When I’ve asked why people do this, the responses generally come down to “everyone else is doing it.” It’s become an expected part of the conference talk, just like a Flash intro used to be an expected part of a website.

When I’m curating a conference, I like to send speakers some information to help them prepare their talk. Some of this is practical stuff, like the tech set-up. Some of it is guidance for the slides, like ensuring sufficient colour contrast. And then there’s this:

Please don’t begin your talk with an introduction about yourself and your work history. You’ll be introduced on stage so it would be a shame to just repeat all that again. Also, it just gets in the way of the actual content of your talk. No need to provide your bona-fides.

Personally, I just find it super cringe. That’s why I don’t do it if I’m giving a talk myself.

As a host however, it’s a big part of my job. It’s way less cringe to have someone else big you up before the talk then doing it yourself.

The premature sheen

I find Brian Eno to be a fascinating chap. His music isn’t my cup of tea, but I really enjoy hearing his thoughts on art, creativity, and culture.

I’ve always loved this short piece he wrote about singing with other people. I’ve passed that link onto multiple people who have found a deep joy in singing with a choir:

Singing aloud leaves you with a sense of levity and contentedness. And then there are what I would call “civilizational benefits.” When you sing with a group of people, you learn how to subsume yourself into a group consciousness because a capella singing is all about the immersion of the self into the community. That’s one of the great feelings — to stop being me for a little while and to become us. That way lies empathy, the great social virtue.

Then there’s the whole Long Now thing, a phrase that originated with him:

I noticed that this very local attitude to space in New York paralleled a similarly limited attitude to time. Everything was exciting, fast, current, and temporary. Enormous buildings came and went, careers rose and crashed in weeks. You rarely got the feeling that anyone had the time to think two years ahead, let alone ten or a hundred. Everyone seemed to be passing through. It was undeniably lively, but the downside was that it seemed selfish, irresponsible and randomly dangerous. I came to think of this as “The Short Now”, and this suggested the possibility of its opposite - “The Long Now”.

I was listening to my Huffduffer feed recently, where I had saved yet another interview with Brian Eno. Sure enough, there was plenty of interesting food for thought, but the bit that stood out to me was relevant to, of all things, prototyping:

I have an architect friend called Rem Koolhaas. He’s a Dutch architect, and he uses this phrase, “the premature sheen.” In his architectural practice, when they first got computers and computers were first good enough to do proper renderings of things, he said everything looked amazing at first.

You could construct a building in half an hour on the computer, and you’d have this amazing-looking thing, but, he said, “It didn’t help us make good buildings. It helped us make things that looked like they might be good buildings.”

I went to visit him one day when they were working on a big new complex for some place in Texas, and they were using matchboxes and pens and packets of tissues. It was completely analog, and there was no sense at all that this had any relationship to what the final product would be, in terms of how it looked.

It meant that what you were thinking about was: How does it work? What do we want it to be like to be in that place? You started asking the important questions again, not: What kind of facing should we have on the building or what color should the stone be?

I keep thinking about that insight: “It didn’t help us make good buildings. It helped us make things that looked like they might be good buildings.”

Substitute the word “buildings” for whatever output is supposedly being revolutionised by generative models today. Websites. Articles. Public policy.

Bóthar

England is criss-crossed by routes that were originally laid down by the Romans. When it came time to construct modern roads, it often made sense to use these existing routes rather than trying to designate entirely new ones. So some of the roads in England are like an early kind of desire path.

Desire paths are something of a cliché in the UX world. They’re the perfect metaphor for user-centred design; instead of trying to make people take a pre-defined route, let them take the route that’s easiest for them and then codify that route.

This idea was enshrined into the very design principles of HTML as “pave the cowpaths”:

When a practice is already widespread among authors, consider adopting it rather than forbidding it or inventing something new.

Ireland never had any Roman roads. But it’s always had plenty of cowpaths.

The Irish word for cow is .

The Irish word for road is bóthar, which literally means “cowpath”.

The cowpaths were paved in both the landscape and the language.

Research

Suppose somebody is using a blade. Perhaps they’re in the bathroom, shaving. Or maybe they’re in the kitchen, preparing food.

Suppose they cut themselves with that blade. This might have happened because the blade was too sharp. Or perhaps the blade was too dull.

Either way, it’s going to be tricky to figure out the reason just by looking at the wound.

But if you talk to the person, not only will you find out the reason, you’ll also understand their pain.

Underlines and line height

I was thinking about something I wrote yesterday when I was talking about styling underlines on links:

For a start, you can adjust the distance of the underline from the text using text-underline-offset. If you’re using a generous line-height, use a generous distance here too.

For some reason, I completely forgot that we’ve got a line-height unit in CSS now: lh. So if you want to make the distance of your underline proportional to the line height of the text that the link is part of, it’s easy-peasy:

text-underline-offset: 0.15lh;

The greater the line height, the greater the distance between the link text and its underline.

I think this one is going into my collection of CSS snippets I use on almost every project.

Style your underlines

We shouldn’t rely on colour alone to indicate that something is interactive.

Take links, for example. Sure, you can give them a different colour to the surrounding text, but you shouldn’t stop there. Make sure there’s something else that distinguishes them. You could make them bold. Or you could stick with the well-understood convention of underlying links.

This is where some designers bristle. If there are a lot of links on a page, it could look awfully cluttered with underlines. That’s why some designers would rather remove the underline completely.

As Manu observed:

I’ve done a lot of audits in the first half of this year and at this point a believe that designing links without underlines is a kink. The idea that users don’t understand that links are clickable arouses some designers. I can’t explain it any other way.

But underlining links isn’t the binary decision it once was. You can use CSS to style those underlines just as you’d style any other part of your design language.

Here’s a regular underlined link.

For a start, you can adjust the distance of the underline from the text using text-underline-offset. If you’re using a generous line-height, use a generous distance here too.

Here’s a link with an offset underline.

If you’d rather have a thinner or thicker underline, use text-decoration-thickness.

Here’s a link with a thin underline.

The colour of the underline and the colour of the link don’t need to be the same. Use text-decoration-color to make them completely different colours or make the underline a lighter shade of the link colour.

Here’s a link with a translucent underline.

That’s quite a difference with just a few CSS declarations:

text-underline-offset: 0.2em;
text-decoration-thickness: 1px;
text-decoration-color: oklch(from currentColor l c h / 50%);

If that still isn’t subtle enough for you, you could even use text-decoration-style to make the underline dotted or dashed, but that might be a step too far.

Here’s a link with a dotted underline.

Whatever you decide, I hope you’ll see that underlines aren’t the enemy of good design. They’re an opportunity.

You should use underlines to keep your links accessible. But you should also use CSS to make those underlines beautiful.

The landing zone

Also sprach Wittgenstein:

Die Grenzen meiner Sprache bedeuten die Grenzen meiner Welt.

Or in English, thus spoke Wittgenstein:

The limits of my language mean the limits of my world.

Language and thinking are intertwined. I’m not saying there’s anything to the strong form of the Sapir-Whorf hypothesis but I think George Lakoff is onto something when he talks about political language.

There’s literal political language like saying “tax relief”—framing taxation as something burdensome that needs to be relieved. But our everyday language has plenty of framing devices that might subconsciously influence our thinking.

When it comes to technology, our framing of new technologies often comes from previous technologies. As a listener to a show, you might find yourself being encouraged to “tune in again next week” when you may never have turned a radio dial in your entire life.

In the early days of the web we used a lot of language from print. John Allsopp wrote about this in his classic article A Dao Of Web Design:

The web is a new medium, although it has emerged from the medium of printing, whose skills, design language and conventions strongly influence it. Yet it is often too shaped by that from which it sprang.

One outdated piece of language on the web is a framing device in two senses: “above the fold”. It’s a conceptual framing device that comes straight from print where newspapers were literally folded in half. It’s a literal framing device that puts the important content at the top of the page.

But there is no fold. We pretended that everyone’s screens were 640 by 480 pixels. Then we pretended that everyone’s screens were 800 by 600 pixels. But we never really knew. It was all a consensual hallucination. Even before mobile devices showed up there was never a single fold.

Even if you know that there’s no literal page fold on the web, using the phrase “above the fold” is still insidiously unhelpful.

So what’s the alternative? Well, James has what I think is an excellent framing:

The landing zone.

It’s the bit of the page where people first show up. It doesn’t have a defined boundary. The landing zone isn’t something separate to the rest of the page; the content landing zone merges into the rest of the content.

You don’t know where the landing zone ends, and that’s okay. It’s better than okay. It encourages you design in a way that still prioritises the most important content but without fooling yourself into thinking there’s some invisible boundary line.

Next time you’re discussing the design of a web page—whether it’s with a colleague or a client—try talking about the landing zone.

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.

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.

UX London flash sale

In exactly six weeks time, UX London is happening!

I am ridiculously excited about this year’s line-up—I can’t wait to see the talks and get hands-on in the workshops.

If you haven’t yet got your ticket, now is the time. There’s a flash sale this week: use the discount code FLASH20 to get a whopping 20% of any ticket. Do it before the end of Friday!

Whether you’re coming for all three days or choosing one focused day, you’re in for a treat.

  • Day one on Tuesday, 10 June is discovery day.
  • Day two on Wednesday, 11 June is design day.
  • Day three on Thursday, 12 June is deliver day.

Head on over to the website to get all the details and then get your discounted ticket.

See you there!

Design processing

Dan wrote an interesting post with a somewhat clickbaity title; This Competition Exposed How AI is Reshaping Design:

I watched two designers go head-to-head in a high-speed battle to create the best landing page in 45 minutes. One was a seasoned pro. The other was a non-designer using AI.

If you can ignore the title (and the fact that Dan still actively posts on Twitter; something I find very hard to ignore), then there’s a really thoughtful analysis in there.

It’s less about one platform or tool vs. another more than it is a commentary on how design happens, and whether or not that’s changing in a significant way.

In particular, there’s a very revealing graph that shows the pros and cons of both approaches.

There’s no doubt about it, using a generative large language model helped a non-designer to get past the blank page. But it was less useful in subsequent iterations that rely on decision-making:

I’ve said it before and I’ll say it again: design is deciding. The best designers are the best deciders.

Dan finishes by saying that what he’d really like to see is an experienced designer/decider using these tools to turbo-boost their process:

AI raises the floor for non-designers. But can it raise the ceiling for designers?

Meanwhile, Matt has been writing about Vibe-designing. Matt is an experienced designer, but he’s not experienced with Figma. He’s found that he can work around that using a large language model:

Where in the past 30 years I might have had to cajole a more technically adept colleague into making something through sketches, gesticulating and making sound effects – I open up a Claude window and start what-iffing.

The “vibe” part of the equation often defaults to the mean, which is not a surprise when you think about what you’re asking to help is a staggeringly-massive machine for producing generally-unsurprising satisfactory answers quickly. So, you look at the output as a basis for the next sketch, and the next sketch and quickly, together, you move to something more novel as a result.

Interesting! Just as Dan insisted, the important work is making the decision and moving on to the next stage. If the actual outputs at each stage are mediocre, that seems to be okay, as long as they’re just good enough to inform a go/no-go decision.

This certainly seems more centaur-like than the usual boring uses of large language models to simply do what people are already doing.

Rich gets at something similar when he talks about using large language models for prototyping, where it’s okay if the code is kind of shitty:

If all you need is crappy code to try out a concept or a solution, then an LLM might well enable you (the designer) to do that.

Mind you, even if you do end up finding useful and appropriate ways to use these tools, you’re still using a tool built on exploitation and unfairness:

It’s hard (and reckless) to ignore the heartfelt and cogent perspective laid out by Miriam on the role of AI companies in the current geopolitical crisis:

When eugenics-obsessed billionaires try to sell me a new toy, I don’t ask how many keystrokes it will save me at work. It’s impossible for me to discuss the utility of a thing when I fundamentally disagree with the purpose of it.

The line-up for UX London 2025

Check it out—here’s the line-up for UX London 2025!

A woman with long dark straight hair wearing dark clothing in front of a bookshelf. Studio portrait of a smiling fair-haired woman wearing a green and white cardigan with her arms folded. A smiling curly-haired woman wearing a shiny top resting her chin on the palm of hand. A smiling woman with short dark hair in profile turns her head towards us. A woman with long dark hair sitting down looking directly at us. Close up of the face of a smiling woman wearing a baseball cap outdoors. A shaven-headed bearded man with a camoflauge shirt in front of a light background. A dark-haired smiling woman wearing a sparkly black top. A smiling woman with straight dark hair outdoors wearing a black top with a sparkly shoulderpiece. A smiling woman with long fair hair and glasses wearing a black and grey top in front of a yellow backdrop. Cut-out of a smiling bearded man wearing a purple scarf against a yellow background. A smiling woman with wearing jeans and a white T-shirt sitting forward on a chair. A woman with glasses and shoulder-length dark hair wearing a necklace and a yellow top sitting down. A shaven-headed man with a light shirt in front of a black background. Close up of a woman's face with shoulder-length hair in front of a background of somewhere bright and sunny outside. The smiling face of a man with short dark hair and beard. A smiling woman with long dark straight hair wearing a dark T-shirt. A smiling woman with long dark hair in leafy corridor. A smiling woman with short blonde hair wearing a white top in front of a pale background.

This is going to be so good! Grab a ticket if you haven’t got one yet.

UX London takes place over three days, from June 10th to 12th at a fantastic venue in the heart of the city. To get the full experience, you should come for all three days. But you can also get a ticket for individual days. Each day has a focus, and when you put them all together, the whole event mirrors the design process:

  1. Day one: Discovery
  2. Day two: Design
  3. Day three: Delivery

Each day features a morning of talks, followed by an afternoon of workshops. The talks are on a single track; four consecutive half-hour presentations to get you inspired. Then after lunch, you choose from one of four workshops. All the workshops are two and half hours long and very hands-on. No laptop required.

On discovery day you’ll have talks in the morning about research, content design, strategy and evaluating technology, followed by workshops on discovery and definition and behavioural design.

On design day there’ll be talks on interface design, a healthcare case study, inclusive design, and typography, followed by workshops in the afternoon on data visualisation and ethics.

Finally on delivery day you’ll get talks on conversion design, cross-team collaboration, convincing stakeholders, and improving design critiques, followed by workshops on facilitating workshops and getting better at public speaking.

Every workshop is repeated on another day so you’ll definitely get the chance to attend the one you want.

Oh, and at the end of every day there’ll be a closing keynote. Those are yet to be revealed, but I can guarantee they’re going to be top-notch!

Right now you can get early-bird tickets for all three days, or individual days. That changes from March 15th, when the regular pricing kicks in—a three-day ticket will cost £200 more. So I’d advise you to get your ticket now.

If you need to convince your boss, show them this list of reasons to attend.

See you there!

The web on mobile

Here’s a post outlining all the great things you can do in mobile web browsers today: Your App Should Have Been A Website (And Probably Your Game Too):

Today’s browsers are powerhouses. Notifications? Check. Offline mode? Check. Secure payments? Yep, they’ve got that too. And with technologies like WebAssembly and WebGPU, web games are catching up to native-level performance. In some cases, they’re already there.

This is all true. But this post from John Gruber is equally true: One Bit of Anecdata That the Web Is Languishing Vis-à-Vis Native Mobile Apps:

I won’t hold up this one experience as a sign that the web is dying, but it sure seems to be languishing, especially for mobile devices.

As John points out, the problems aren’t technical:

There’s absolutely no reason the mobile web experience shouldn’t be fast, reliable, well-designed, and keep you logged in. If one of the two should suck, it should be the app that sucks and the website that works well. You shouldn’t be expected to carry around a bundle of software from your utility company in your pocket. But it’s the other way around.

He’s right. It makes no sense, but this is the reality.

Ten or fifteen years ago, the gap between the web and native apps on mobile was entirely technical. There were certain things that you just couldn’t do in web browsers. That’s no longer the case now. The web caught up quite a while back.

But the experience of using websites on a mobile device is awful. Never mind the terrible performance penalties incurred by unnecessary frameworks and libraries like React and its ilk, there’s the constant game of whack-a-mole with banners and overlays. What’s just about bearable in a large desktop viewport becomes intolerable on a small screen.

This is not a technical problem. This doesn’t get solved by web standards. This is a cultural problem.

First of all, there’s the business culture. If your business model depends on tracking people or pushing newsletter sign-ups, then it’s inevitable that your website will be shite on mobile.

Mind you, if your business model depends on tracking people, you’re more likely to try push people to download your native app. Like Cory Doctorow says:

50% of web users are running ad-blockers. 0% of app users are running ad-blockers, because adding a blocker to an app requires that you first remove its encryption, and that’s a felony (Jay Freeman calls this ‘felony contempt of business-model’).

Matt May brings up the same point in his guide, How to grey-rock Meta:

Remove Meta apps from your devices and use only the mobile web versions. Mobile apps have greater access to your personal data, provided the app requests those privileges, and Facebook and Instagram in particular (more so than WhatsApp, another Meta property) request the vast majority of those privileges. This includes precise GPS data on where you are, whether or not you are using the app.

Ironically, it’s the strength of the web—and web browsers—that has led to such shitty mobile web experiences. The pretty decent security model on the web means that sites have to pester you.

Part of the reason why you don’t see the same egregious over-use of pop-ups and overlays in native apps is that they aren’t needed. If you’ve installed the app, you’re already being tracked.

But when I describe the dreadful UX of most websites on mobile as a cultural problem, I don’t just mean business culture.

Us, the people who make websites, designers and developers, we’re responsible for this too.

For all our talk of mobile-first design for the last fifteen years, we never really meant it, did we? Sure, we use media queries and other responsive techniques, but all we’ve really done is make sure that a terrible experience fits on the screen.

As developers, I’m sure we can tell ourselves all sorts of fairy tales about why it’s perfectly justified to make users on mobile networks download React, Tailwind, and megabytes more of third-party code.

As designers, I’m sure we can tell ourselves all sorts of fairy tales about why intrusive pop-ups and overlays are the responsibility of some other department (as though users make any sort of distinction).

Worst of all, we’ve spent the last fifteen years teaching users that if they want a good experience on their mobile device, they should look in an app store, not on the web.

Ask anyone about their experience of using websites on their mobile device. They’ll tell you plenty of stories of how badly it sucks.

It doesn’t matter that the web is the perfect medium for just-in-time delivery of information. It doesn’t matter that web browsers can now do just about everything that native apps can do.

In many ways, I wish this were a technical problem. At least then we could lobby for some technical advancement that would fix this situation.

But this is not a technical problem. This is a people problem. Specifically, the people who make websites.

We fucked up. Badly. And I don’t see any signs that things are going to change anytime soon.

But hey, websites on desktop are just great!

Making the new Salter Cane website

With the release of a new Salter Cane album I figured it was high time to update the design of the band’s website.

Here’s the old version for reference. As you can see, there’s a connection there in some of the design language. Even so, I decided to start completely from scratch.

I opened up a text editor and started writing HTML by hand. Same for the CSS. No templates. No build tools. No pipeline. Nothing. It was a blast!

And lest you think that sounds like a wasteful way of working, I pretty much had the website done in half a day.

Partly that’s because you can do so much with so little in CSS these days. Custom properties for colours, spacing, and fluid typography (thanks to Utopia). Logical properties. View transitions. None of this takes much time at all.

Because I was using custom properties, it was a breeze to add a dark mode with prefers-color-scheme. I think I might like the dark version more than the default.

The final stylesheet is pretty short. I didn’t bother with any resets. Browsers are pretty consistent with their default styles nowadays. As long as you’ve got some sensible settings on your body element, the cascade will take care of a lot.

There’s one little CSS trick I think is pretty clever…

The background image is this image. As you can see, it’s a rectangle that’s wider than it is tall. But the web pages are rectangles that are taller than they are wide.

So how I should I position the background image? Centred? Anchored to the top? Anchored to the bottom?

If you open up the website in Chrome (or Safari Technical Preview), you’ll see that the background image is anchored to the top. But if you scroll down you’ll see that the background image is now anchored to the bottom. The background position has changed somehow.

This isn’t just on the home page. On any page, no matter how tall it is, the background image is anchored to the top when the top of the document is in the viewport, and it’s anchored to the bottom when you reach the bottom of the document.

In the past, this kind of thing might’ve been possible with some clever JavaScript that measured the height of the document and updated the background position every time a scroll event is triggered.

But I didn’t need any JavaScript. This is a scroll-driven animation made with just a few lines of CSS.

@keyframes parallax {
    from {
        background-position: top center;
    }
    to {
        background-position: bottom center;
    }
}
@media (prefers-reduced-motion: no-preference) {
        html {
            animation: parallax auto ease;
            animation-timeline: scroll();
        }
    }
}

This works as a nice bit of progressive enhancement: by default the background image stays anchored to the top of the viewport, which is fine.

Once the site was ready, I spent a bit more time sweating some details, like the responsive images on the home page.

But the biggest performance challenge wasn’t something I had direct control over. There’s a Spotify embed on the home page. Ain’t no party like a third party.

I could put loading="lazy" on the iframe but in this case, it’s pretty close to the top of document so it’s still going to start loading at the same time as some of my first-party assets.

I decided to try a little JavaScript library called “lazysizes”. Normally this would ring alarm bells for me: solving a problem with third-party code by adding …more third-party code. But in this case, it really did the trick. The library is loading asynchronously (so it doesn’t interfere with the more important assets) and only then does it start populating the iframe.

This made a huge difference. The core web vitals went from being abysmal to being perfect.

I’m pretty pleased with how the new website turned out.

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.

Making the website for Research By The Sea

UX London isn’t the only event from Clearleft coming your way in 2025. There’s a brand new spin-off event dedicated to user research happening in February. It’s called Research By The Sea.

I’m not curating this one, though I will be hosting it. The curation is being carried out most excellently by Benjamin, who has written more about how he’s doing it:

We’ve invited some of the best thinkers and doers from from in the research space to explore how researchers might respond to today’s most gnarly and pressing problems. They’ll challenge current perspectives, tools, practices and thinking styles, and provide practical steps for getting started today to shape a better tomorrow.

If that sounds like your cup of tea, you should put February 27th 2025 in your calendar and grab yourself a ticket.

Although I’m not involved in curating the line-up for the event, I offered Benjamin my swor… my web dev skillz. I made the website for Research By The Sea and I really enjoyed doing it!

These one-day events are a great chance to have a bit of fun with the website. I wrote about how enjoyable it was making the website for this year’s Patterns Day:

I felt like I was truly designing in the browser. Adjusting spacing, playing around with layout, and all that squishy stuff. Some of the best results came from happy accidents—the way that certain elements behaved at certain screen sizes would lead me into little experiments that yielded interesting results.

I took the same approach with Research By The Sea. I had a design language to work with, based on UX London, but with more of a playful, brighter feel. The idea was that the website (and the event) should feel connected to UX London, while also being its own thing.

I kept the typography of the UX London site more or less intact. The page structure is also very similar. That was my foundation. From there I was free to explore some other directions.

I took the opportunity to explore some new features of CSS. But before I talk about the newer stuff, I want to mention the bits of CSS that I don’t consider new. These are the things that are just the way things are done ‘round here.

Custom properties. They’ve been around for years now, and they’re such a life-saver, especially on a project like this where I’m messing around with type, colour, and spacing. Even on a small site like this, it’s still worth having a section at the start where you define your custom properties.

Logical properties. Again, they’ve been around for years. At this point I’ve trained my brain to use them by default. Now when I see a left, right, width or height in a style sheet, it looks like a bug to me.

Fluid type. It’s kind of a natural extension of responsive design to me. If a website’s typography doesn’t adjust to my viewport, it feels slightly broken. On this project I used Utopia because I wanted different type scales as the viewport increased. On other projects I’ve just used on clamp declaration on the body element, which can also get the job done.

Okay, so those are the things that feel standard to me. So what could I play around with that was new?

View transitions. So easy! Just point to an element on two different pages and say “Hey, do a magic move!” You can see this in action with the logo as you move from the homepage to, say, the venue page. I’ve also added view transitions to the speaker headshots on the homepage so that when you click through to their full page, you get a nice swoosh.

Unless, like me, you’re using Firefox. In that case, you won’t see any view transitions. That’s okay. They are very much an enhancement. Speaking of which…

Scroll-driven animations. You’ll only get these in Chromium browsers right now, but again, they’re an enhancement. I’ve got multiple background images—a bunch of cute SVG shapes. I’m using scroll-driven animations to change the background positions and sizes as you scroll. It’s a bit silly, but hopefully kind of cute.

You might be wondering how I calculated the movements of each background image. Good question. I basically just messed around with the values. I had fun! But imagine what an actually-skilled interaction designer could do.

That brings up an interesting observation about both view transitions and scroll-driven animations: Figma will not help you here. You need to be in a web browser with dev tools popped open. You’ve got to roll up your sleeves get your hands into the machine. I know that sounds intimidating, but it’s also surprisingly enjoyable and empowering.

Oh, and I made sure to wrap both the view transitions and the scroll-driven animations in a prefers-reduced-motion: no-preference @media query.

I’m pleased with how the website turned out. It feels fun. More importantly, it feels fast. There is zero JavaScript. That’s the main reason why it’s very, very performant (and accessible).

Smooth transitions across pages; smooth animations as you scroll: it’s great what you can do with just HTML and CSS.

Announcing UX London 2025

Is it too early to start planning for 2025 already? Perhaps. But you might want to add some dates to your calender:

June 10th, 11th, and 12th, 2025.

That’s when UX London will return!

It’ll be be back in CodeNode. That’s the venue we tried for the first time this year and it worked out really well.

You can look forward to three days of UX talks and workshops:

  1. Tuesday, June 10th is Discovery Day—user research, content strategy, and planning.
  2. Wednesday, June 11th is Design Day—interaction design, accessibility, and interface design.
  3. Thursday, June 12th is Delivery Day—iteration, design ops, and cross-team collaboration.

I realise that the alliteration of discovery, design, and delivery is a little forced but you get the idea. The flow of the event will follow the process of a typical design project.

The best way to experience UX London is to come for all three days, but each day also works as a standalone event.

I’m now starting the process of curating the line-up for each day: a mix of inspiring talks and hands-on workshops. If you trust me, you can get your ticket already at the super early-bird price.

If you reckon you’d be a good addition to the line-up, here’s a form you can fill out.

Now, I’ll be up-front here: if you’re a typical white dude like me, you’re not going to be top of the pile. My priority for UX London is creating a diverse line-up of speakers.

So if you’re not a typical white dude like me and you’ve ever thought about giving a conference talk, fill out that form!

If you don’t fancy speaking, but you want to see your company represented at UX London, check out our sponsorship options.

If you don’t want to speak and you don’t want to sponsor, but you want to be at the best design conference of 2025, get your ticket now.

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.