Tags: interaction

211

sparkline

Wednesday, December 17th, 2025

NoLoJS: Reducing the JS Workload with HTML and CSS - Web Performance Calendar

You might not need (much) JavaScript for these common interface patterns.

While we all love the power and flexibility JS provides, we should also respect it, and our users, by limiting its use to only what it needs to do.

Yes! Client-side JavaScript should do what only client-side JavaScript can do.

Tuesday, August 26th, 2025

Developing an alt text button for images on my website | James’ Coffee Blog

I like the idea of adding this to personal websites:

Mastodon shows an “Alt” button in the bottom right of images that have associated alt text. This button, when clicked, shows the alt text the author has written for the image.

Wednesday, March 5th, 2025

Building WebSites With LLMS - Jim Nielsen’s Blog

And by LLMS I mean: (L)ots of (L)ittle ht(M)l page(S).

I really like this approach: using separate pages instead of in-page interactions. I remember Simon talking about how great this works, and that was a few years back, before we had view transitions.

I build separate, small HTML pages for each “interaction” I want, then I let CSS transitions take over and I get something that feels better than its JS counterpart for way less work.

Monday, December 23rd, 2024

Don’t Fuck With Scroll

  1. Violates User Expectations
  2. Causes Motion Sickness
  3. Reduces Accessibility for Disabled Users
  4. Inconsistent Performance Across Devices
  5. Impairs Usability for Power Users
  6. Increases Page Load Times
  7. Breaks Native Browser Features
  8. Makes Scroll Position Unclear
  9. Adds Maintenance Overhead
  10. Disrespects the User’s Control

Thursday, September 26th, 2024

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.

Friday, January 26th, 2024

Nuberodesign > Blog > In Praise of Buttons – Part One

I concur:

Just because a user interface uses 3D-buttons and some shading doesn’t mean that it has to look tacky. In fact, if you have to make the choice between tacky-but-usable and minimalistic-but-hard-to-use, tacky is the way to go. You don’t have to make that choice though: It’s perfectly possible to create something that is both good-looking and easy to use.

Wednesday, January 17th, 2024

Designing better target sizes

This is a wonderfully in-depth interactive explainer on touch target sizes, with plenty of examples.

Tuesday, September 26th, 2023

Bruce Lawson’s personal site  : HTML popover, videos and display:blackhole

Bruce raises an interesting question with media playing in popovers—shouldn’t the media pause when the popover is closed? I agree with Bruce that this is a common use case that should be covered declaratively.

Saturday, August 5th, 2023

Just normal web things.

A plea to let users do web things on websites. In other words, stop over-complicating everything with buckets of JavaScript.

Honestly, this isn’t wishlist isn’t asking for much, and it’s a damning indictment of “modern” frontend development that we’ve come to this:

  • Let me copy text so I can paste it.
  • If something navigates like a link, let me do link things.

Wednesday, March 22nd, 2023

Disclosure

You know how when you’re on hold to any customer service line you hear a message that thanks you for calling and claims your call is important to them. The message always includes a disclaimer about calls possibly being recorded “for training purposes.”

Nobody expects that any training is ever actually going to happen—surely we would see some improvement if that kind of iterative feedback loop were actually in place. But we most certainly want to know that a call might be recorded. Recording a call without disclosure would be unethical and illegal.

Consider chatbots.

If you’re having a text-based (or maybe even voice-based) interaction with a customer service representative that doesn’t disclose its output is the result of large language models, that too would be unethical. But, at the present moment in time, it would be perfectly legal.

That needs to change.

I suspect the necessary legislation will pass in Europe first. We’ll see if the USA follows.

In a way, this goes back to my obsession with seamful design. With something as inherently varied as the output of large language models, it’s vital that people have some way of evaluating what they’re told. I believe we should be able to see as much of the plumbing as possible.

The bare minimum amount of transparency is revealing that a machine is in the loop.

This shouldn’t be a controversial take. But I guarantee we’ll see resistance from tech companies trying to sell their “AI” tools as seamless, indistinguishable drop-in replacements for human workers.

Monday, July 25th, 2022

Control

In two of my recent talks—In And Out Of Style and Design Principles For The Web—I finish by looking at three different components:

  1. a button,
  2. a dropdown, and
  3. a datepicker.

In each case you could use native HTML elements:

  1. button,
  2. select, and
  3. input type="date".

Or you could use divs with a whole bunch of JavaScript and ARIA.

In the case of a datepicker, I totally understand why you’d go for writing your own JavaScript and ARIA. The native HTML element is quite restricted, especially when it comes to styling.

In the case of a dropdown, it’s less clear-cut. Personally, I’d use a select element. While it’s currently impossible to style the open state of a select element, you can style the closed state with relative ease. That’s good enough for me.

Still, I can understand why that wouldn’t be good enough for some cases. If pixel-perfect consistency across platforms is a priority, then you’re going to have to break out the JavaScript and ARIA.

Personally, I think chasing pixel-perfect consistency across platforms isn’t even desirable, but I get it. I too would like to have more control over styling select elements. That’s one of the reasons why the work being done by the Open UI group is so important.

But there’s one more component: a button.

Again, you could use the native button element, or you could use a div or a span and add your own JavaScript and ARIA.

Now, in this case, I must admit that I just don’t get it. Why wouldn’t you just use the native button element? It has no styling issues and the browser gives you all the interactivity and accessibility out of the box.

I’ve been trying to understand the mindset of a developer who wouldn’t use a native button element. The easy answer would be that they’re just bad people, and dismiss them. But that would probably be lazy and inaccurate. Nobody sets out to make a website with poor performance or poor accessibility. And yet, by choosing not to use the native HTML element, that’s what’s likely to happen.

I think I might have finally figured out what might be going on in the mind of such a developer. I think the issue is one of control.

When I hear that there’s a native HTML element—like button or select—that comes with built-in behaviours around interaction and accessibility, I think “Great! That’s less work for me. I can just let the browser deal with it.” In other words, I relinquish control to the browser (though not entirely—I still want the styling to be under my control as much as possible).

But I now understand that someone else might hear that there’s a native HTML element—like button or select—that comes with built-in behaviours around interaction and accessibility, and think “Uh-oh! What if there unexpected side-effects of these built-in behaviours that might bite me on the ass?” In other words, they don’t trust the browsers enough to relinquish control.

I get it. I don’t agree. But I get it.

If your background is in computer science, then the ability to precisely predict how a programme will behave is a virtue. Any potential side-effects that aren’t within your control are undesirable. The only way to ensure that an interface will behave exactly as you want is to write it entirely from scratch, even if that means using more JavaScript and ARIA than is necessary.

But I don’t think it’s a great mindset for the web. The web is filled with uncertainties—browsers, devices, networks. You can’t possibly account for all of the possible variations. On the web, you have to relinquish some control.

Still, I’m glad that I now have a bit more insight into why someone would choose to attempt to retain control by using div, JavaScript and ARIA. It’s not what I would do, but I think I understand the motivation a bit better now.

Tuesday, June 7th, 2022

Patterns | APG | WAI | W3C

This is a terrific resource! A pattern library of interactive components: tabs, switches, dialogs, carousels …all the usual suspects.

Each component has an example implementation along with advice and a checklist for ensuring its accessible.

It’s so great to have these all gathered together in one place!

Saturday, February 5th, 2022

How to progressively enhance a nav menu | Go Make Things

A lot of folks assume that progressive enhancement means having to write the same code twice, but often, it can be as simple as extending the pattern you already have once the JS loads.

Tuesday, July 6th, 2021

Tabs in HTML?

I’ve been having some really interesting chats with Brian about tabs, markup, progressive enhancement and accessibility. Here’s a braindump of his current thinking which is well worth perusing.

Tuesday, June 29th, 2021

Whatever Happened to UI Affordances? – Terence Eden’s Blog

Flat, minimalist, clean, material - whatever you want to call it - is an annoying antipattern. Computers are here to make life easier for humans. Removing affordances is just a nasty thing to do to your users.

Sunday, June 6th, 2021

Let’s talk about failure

Denise shares a cautionary tale of service design gone wrong.

Monday, December 14th, 2020

Cameras and Lenses – Bartosz Ciechanowski

This is a truly wonderful web page! It’s an explanation from first principles of how cameras and lenses work.

At its most basic, it uses words which you can read in any browser. It also uses images so if your browser supports images, you get that enhancement. And it uses interactive JavaScript widgets so that you get that layer of richness if your browser supports the technology.

Then you realise that every post ever published on this personal site is equally in-depth and uses the same content-first progressive enhancement approach.

Sunday, November 22nd, 2020

Static sites, slack and scrollytelling. | Clearleft

Cassie’s enthusiasm for fun and interesting SVG animation shines through in her writing!

Tuesday, November 10th, 2020

aria-live

I wrote a little something recently about using ARIA attributes as selectors in CSS. For me, one of the advantages is that because ARIA attributes are generally added via JavaScript, the corresponding CSS rules won’t kick in if something goes wrong with the JavaScript:

Generally, ARIA attributes—like aria-hidden—are added by JavaScript at runtime (rather than being hard-coded in the HTML).

But there’s one instance where I actually put the ARIA attribute directly in the HTML that gets sent from the server: aria-live.

If you’re not familiar with it, aria-live is extremely useful if you’ve got any dynamic updates on your page—via Ajax, for example. Let’s say you’ve got a bit of your site where filtered results will show up. Slap an aria-live attribute on there with a value of “polite”:

<div aria-live="polite">
...dynamic content gets inserted here
</div>

You could instead provide a value of “assertive”, but you almost certainly don’t want to do that—it can be quite rude.

Anyway, on the face it, this looks like exactly the kind of ARIA attribute that should be added with JavaScript. After all, if there’s no JavaScript, there’ll be no dynamic updates.

But I picked up a handy lesson from Ire’s excellent post on using aria-live:

Assistive technology will initially scan the document for instances of the aria-live attribute and keep track of elements that include it. This means that, if we want to notify users of a change within an element, we need to include the attribute in the original markup.

Good to know!

Tuesday, October 27th, 2020

ARIA in CSS

Sara tweeted something recently that resonated with me:

Also, Pro Tip: Using ARIA attributes as CSS hooks ensures your component will only look (and/or function) properly if said attributes are used in the HTML, which, in turn, ensures that they will always be added (otherwise, the component will obv. be broken)

Yes! I didn’t mention it when I wrote about accessible interactions but this is my preferred way of hooking up CSS and JavaScript interactions. Here’s old Codepen where you can see it in action:

[aria-hidden='true'] {
  display: none;
}

In order for the functionality to work for everyone—screen reader users or not—I have to make sure that I’m toggling the value of aria-hidden in my JavaScript.

There’s another advantage to this technique. Generally, ARIA attributes—like aria-hidden—are added by JavaScript at runtime (rather than being hard-coded in the HTML). If something goes wrong with the JavaScript, the aria-hidden value isn’t set to “true”, which means that the CSS never kicks in. So the default state is for content to be displayed. There’s no assumption that the JavaScript has to work in order for the CSS to make sense.

It’s almost as though accessibility and progressive enhancement are connected somehow…