Reading List

The most recent articles from a list of feeds I subscribe to.

“AI” content and user centered design

Large language models (LLMs), like ChatGPT and Bard, can be used to generate sentences based on statistical likeliness. While the results of these tools can look very impressive (they're designed to), I can't think of cases where the use of LLM-generated content actually improves an end user's experience. Even if not all of the time, LLM output is often nonsensical, false, unclear and boring. Hence, when organisations force LLM-output on users instead of paying people to create their content, they don't center users.

User centered design means we make the user our main concern when we design. When I recently told a friend about this concept, explaining my new job is at a government department focused on centering users, they laughed in surprise. “This is a thing?”, they asked. “What else would you make the main concern when you design?” It made little sense to them that users had to be specifically centered.

If you work in tech, you probably saw projects center other things than users. Business needs, the profit margin, search engines, that one designer's personal preference, the desire to look as cool as a tech brand you love… and so on. Sadly, projects center them instead of users all the time. Most arguments I heard for using LLMs in the content production process quoted at least one of these non-user-centric reasons.

Organisations are starting to use or at least experiment with LLMs to create content for web projects. The hype is real and I worry that, by increasing nonsense, falsehoods and boredom, LLM-generated content is going to worsen user experiences across the board. Why force this content on users? And what about the impact of LLM-generated content beyond individual websites and user experiences: it's also going to pollute the web as a whole and make search worse (as well as itself).

None of this is new, we've had robot-like interactions way before LLMs. When the tax office sends a letter that means you need to pay or receive money, that information is often buried in civil servant speak. When Silicon Valley startup founders announce they were bought, they will mention their “incredible journey”. When lawyers describe employment, customer service phone lines pronounce “your call is important to us” (a great read, BTW)… this is all to say that, even without LLMs, we're used to people that sound more robotic and less human. They speak a lingo.

Lingo gets in the way of clarity. Not just because it feels impersonal and boring, it is also made-up, however brilliantly our prompts will be ‘engineered’. Yes, even if it's sourced—or stolen, in many cases—from original content. That makes it like the lingo humans produce, but much worse. Sure, LLM-generated content could give users clarity, except in a way that's only helpful if the user already knows a lot about the thing that is clarified (so that they can spot falsehoods). This is the crux and why the practical applicability of LLMs isn't nearly as wide as their makers claim.

I can see how a doctor's practice / government department / bank / school could save money and time by putting a chatbot between themselves and the people. There are benefits to one-click-content-creation for organisations. But I don't see how end users could benefit, at all. Who would prefer reading convincing-but-potentially-false chatbot-advice to a conversation with their doctor (or force the bot on others). Zooming out from specific use cases to the wider ecosystem… aren't even those who shrug at ideals like centering humans worried that LLMs-generated content wipes out the very “value” capitalists wants to extract from the web (by enshittification)? I certainly hope so.

Addendum: I didn't know writing this post that OpenAI's CEO Sam Altman literally wrote he looked forward to “AI medical advisors for people who can't afford care”. From his thread on 19 February 2023:

the adaptation to a world deeply integrated with AI tools is probably going to happen pretty quickly; the benefits (and fun!) have too much upside.

these tools will help us be more productive (can't wait to spend less time doing email!), healthier (AI medical advisors for people who can’t afford care), smarter (students using ChatGPT to learn), and more entertained (AI memes lolol).

(…)

we think showing these tools to the world early, while still somewhat broken, is critical if we are going to have sufficient input and repeated efforts to get it right. the level of individual empowerment coming is wonderful, but not without serious challenges.

He talks about “individual empowerment [that] is wonderful”, I think it's incredibly dystopian.


Originally posted as “AI” content and user centered design on Hidde's blog.

Reply via email

Joining CSSWG

This week I joined the CSS Working Group (CSSWG) as an Invited Expert. I'm super grateful for this chance to try and make myself useful in a group whose outputs shaped so much of my professional interests (they make CSS!).

I'm somewhat nervous about this, but also not completely new to CSS or web standards. My background with CSS is that I've been a long time fanboy of the language, and a keen follower of new developments through events (9 times CSS Day attendee of which 2 as a speaker). The CSSWG folks I've met so far are very friendly, no exceptions. My background with standards is that I've participated in the Open UI Community Group for just over two years, and worked as W3C Staff to promote accessibility standards, help simplify developer documentation and build standard-related tooling like the ATAG and WCAG-EM Report Tools. As such, I am experienced with some of the W3C process.

Despite not being completely new, I've yet to figure out my focus and where I could help. The CSSWG does a daunting amount of work (see the charter), and there are certain specs and features I'm especially interested in, like the ones close to Open UI. I think I will start with attending the telecons, listen and learn. Ultimately, I hope to make myself actually useful, maybe help with demos and content (like explainers or explanatory blog posts or talks), or by sharing a web developer's perspective. And opinions, maybe!

I'm excited for this opportunity, many thanks to Tantek, Miriam and others for their encouragement. I look forward to involve in standards outside accessibility and, yeah, try and make myself useful 🙃


Originally posted as Joining CSSWG on Hidde's blog.

Reply via email

Positioning anchored popovers

Popovers are commonly positioned relative to their invoker (if they have one). When we use the popover attribute, anchoring is tricky, as these popovers are in the top layer, away from the context of their invoker. What options do we have?

See also: Hidde's talk on popovers, and other posts about popover accessibility, positioning popovers and the difference with dialogs and other components.

Basically, there are two ways to position popovers: one you can use today and one that will be available in the future. I'll detail them below, but first, let's look at why we can't use absolute positioning relative to a container shared by the invoker and the popover.

Not all popovers are anchored, but I expect anchored popovers to be among the most common ones. For popovers that are not anchored, such as toast-like elements, “bottom sheets” or keyboard-triggered command palettes, these positioning constraints do not apply.

Examples of anchored popovers: map toggletip (Extinction Rebellion), date picker (European Sleeper), colour picker (Microsoft Word web app)

See also my other posts on popovers:

Top layer elements lose their positioning context

One of the unique characteristics of popovers (again, the ones made with the popover attribute, not just any popover from a design system), is that they get upgraded to the top layer. The top layer is a feature drafted in CSS Positioning, Level 4. The top layer is a layer adjacent to the main document, basically like a bit like a sibling of <html>.

Some specifics on the top layer:

  • It's above all z-indexes in your document, top layer elements can't use z-index. Instead, elements are stacked in the order they are added to the top layer.
  • As developers, we can't put elements in the top layer directly, as it is browser controlled. We can only use certain elements and APIs that then trigger the browser to move an element to the top layer: the Full Screen API, <dialog>s with showModal() and popover'ed elements, currently.
  • Top layer elements, quoting the specification, “don't lay out normally based on their position in the document”.

When I positioned my first popover, I tried (and failed): I put both the popover and its invoking element in one element with position: relative. Then I applied position: absolute to the popover, which I hoped would let me position relative to the container. It didn't, and I think the last item above explains why.

In summary, elements lose their position context when they are upgraded to the top layer. And that's okay, we have other options.

Option 1: position yourself (manually or with a library)

The first option is to position the popover yourself, with script. Because the fact that the top layer element doesn't know about the non-top layer element's position in CSS, doesn't mean you can't store the invoker's position and calculate a position for the popover itself.

There are some specifics to keep in mind, just like with popovers that are built without the popover attribute: what happens when there's no space or when the popover is near the window? Numerous libraries can help with this, such as Floating UI, an evolution of the infamous Popper library.

Let's look at a minimal example using Floating UI. It assumes you have a popover in your HTML that is connected to a button using popovertarget:

<button popovertarget="p">Toggle popover</button>
<div id="p" popover>… popover contents go here</div>

By default, browsers show the open popover in the center of the viewport:

dev tools colors marking space surrounding popover The popover is centered

The reason that this happens is that the UA stylesheet applies margin: auto to popovers. This will reassign any whitespace around the popover equally to all sides as margins. That checks out: if there's the same amount of whitespace left and right, it element will effectively be in the center horizontally (same for top and bottom, but vertically).

For anchored popovers, we want the popover to be near the button that invoked it, not in the center. Let's look at a minimal code example.

In your JavaScript, first import the computePosition function from @floating-ui:

import { computePosition } from '@floating-ui/dom';

Then, find the popover:

const popover = document.querySelector('[popover]');

Popovers have a toggle event, just like the <details> element, which we'll listen to:

popover.addEventListener('toggle', positionPopover); 

In our positionPopover function, we'll find the invoker, and then, if the newState property of the event is open, we'll run the computePosition function and set the results of its computation as inline styles.

function positionPopover(event) {
  const invoker = document.querySelector(`[popovertarget="${popover.getAttribute('id')}"`);

  if (event.newState === 'open') {
    computePosition(invoker, popover).then(({x, y}) => {
      Object.assign(popover.style, {
        left: `${x}px`,
        top: `${y}px`,
      });
    });
  }
}

To make this work, I also applied these two style declarations to the popover:

  • margin: 0, because the UA's auto margin's whitespace gets included in the calculation, with 0 we remove that whitespace
  • position: absolute, because popovers get position: fixed from the user agent stylesheet and I don't want that on popovers that are anchored to a button

It then looks something like this:

popover displays underneath button, it is centered relative to the button

See it in action: Codepen: Positioning a popover with Floating UI.

In the Codepen, I also use some Floating UI config to position the popover from the left. In reality, you probably want to use more of Floating UI's features, to deal with things like resizing (see their tutorial).

Option 2: with Anchor Positioning

To make all of this a whole lot easier (and leave the maths to the browser), a new CSS specification is on the way: Anchor Positioning, Level 1. It exists so that:

a positioned element can size and position itself relative to one or more "anchor elements" elsewhere on the page

This, as they say, is rad, because it will let the browser do your sizing and positioning maths (even automatically- update 4 May 2024: looks like automatic anchoring was removed). It is also exciting, because it doesn't care where your elements are. They can be anywhere in your DOM. And, important for popovers, it also works across the top layer and root element.

Though popovers would get implicit anchoring, you can connect a popover with its invoker via CSS. To find out how all of this works in practice, I recommend Jhey Tompkins's great explainer on Chrome Developers (but note it's currently somewhat outdated, the editor's draft spec changed since that post, and has new editors). Roman Komarov covers his experiments and some interesting use cases in Future CSS: Anchor Positioning, and also wrote Anchor Positioning on 12 days of web.

The Anchor Positioning spec was recently updated, and is currently in the process of being implemented in browsers, hence the Option 1 in this article. But, excitingly, it is in the works. Chromium has already issued an intent to ship anchor positioning, and so did Mozilla/Gecko. The recent updates are still pending TAG review.

Wrapping up

So, in summary: if your popover needs to be anchored to something, like a button or a form field, you can't “just” use absolute positioning. Instead, you can use JavaScript (today), or, excitingly, anchor positioning (in the near-ish future, an Editor's Draft in CSS was published last year and a new version of that with new editors was released in April 2024.


Originally posted as Positioning anchored popovers on Hidde's blog.

Reply via email

Semantics and the popover attribute: which role to use when?

With the new popover attribute in HTML, we can put elements in the top layer and allow them to disappear with ‘light dismiss’. This attribute adds behaviour, not semantics: you're supposed to add your own role when it makes sense. In this post, we'll look at different roles that could make sense for your popover-behaved elements.

See also: Hidde's talk on popovers, and other posts about popover accessibility, positioning popovers and the difference with dialogs and other components.

Semantics?

Accessibility semantics are roles, states and properties that are exposed by by browsers for many HTML features, and then passed on to assistive technologies.

The ‘role’ of an element establishes what kind of element it is. Roles are built-in (‘implicit’) to some elements: a h1 has the heading role, an a has the link role and so forth. Roles can also be added with a role attribute explicitly. For some roles, that is the only way: there exists no corresponding element. If there's an element and a value for ‘role’, it doesn't really matter for end users which you use, but generally you don't want to overwrite implicit role. As mentioned, your user's browser or assistive technology may use the role to provide a UI. For instance, a screenreader may generate a list of links or headings, a reader mode may render list items with bullets.

Popovers have no default role

Whenever we add the popover attribute to an element, it continues to be that element semantically, just with some specific behaviours. Menus remain menus, dialogs remain dialogs, and so on. The popover attribute does not change an element's role. It's a bit like the contenteditable attribute in that sense. In addition to choosing that you want the popover behaviour, you need to decide if you add a role and, if so, which role.

The most basic example of a popover:

<button 
  type="button" 
  popovertarget="my-popover">
    Toggle popover
</button>
<div popover id="my-popover">
  ... 
</div>

This is how it works:

  • the div will be invisible on page load, because it has a popover attribute and popovers are closed on page load by default
  • the div will also be toggleable via the button, as the button points to the div's ID in its popovertarget attribute

Potential roles for your popover

Let's now look at common roles for popovers: menu, dialog and listbox, and consider what to do about tooltips.

Menus: the menu role

Let's start with menus. The menu role is what you'd use when your component offers a list of choices to the user, specifically choices that are actions. (Note: menu is not for a list of links, like a navigation, it is only for a list of actions).

A menu with popover behaviour can be built with a menu role:

<button 
  type="button" 
  popovertarget="my-menu">
    Toggle menu
</button>
<div role="menu" popover id="my-menu">
    <button 
      onclick="doThing()" 
      role="menuitem" 
      tabindex="-1" 
      autofocus>Do thing</button>
    <button 
      onclick="doAnotherThing()" 
      role="menuitem"
      tabindex="-1">Do another thing</button></div>

In a menu widget, there are also some keyboard and focus expectations. For instance, that users can use their arrow keys to cycle through the different buttons. As a developer, this is something you'd add with JavaScript yourself. The first button is focused when it opens (hence autofocus), the second and after would get focused moved to them when they're the next one and an arrow key is pressed (hence tabindex="-1": this takes the buttons out of tab order, because you make them reachable with arrow keys instead).

(Note: The menu role is not to be confused with the menu element, which has a list role and is “a semantic alternative to <ul>”)

Examples of when you would use role="menu":

CMS screenshot with a field called authors that shows one author and an opened menu with options for Remove, Duplicate, Add item before, Add item after Your CMS manages a list of authors. The user can open a menu for each author with some actions (each action has a menuitem role)

CMS screenshot with a field called authors that shows one author and an opened menu with options for Remove, Duplicate, Add item before, Add item after You're building a word processor. The “File” menu is a menu, the options (New, Open, etc) are menuitems._

See also: Marco Zehe on the menu role and “Menu control type” in Windows Accessibility Features documentation

Dialogs: the dialog role

A dialog role is what you add when an element is like a smaller window on top of the main web page. It can block interaction with the rest of the page or leave the rest of the page as it is, either way it is somewhat separate from the page, both in purpose and visually.

The <dialog> element implicitly has a dialog role, and comes with dialog methods and behaviours (like you can run element.showModal() to show it as a modal). You can also add the dialog role manually with role="dialog", but then you have to add the behaviours manually too.

A dialog with popover behaviour can be built like this:

<button 
  type="button" 
  popovertarget="my-dialog">
    Toggle dialog
</button>
<dialog id="my-dialog" popover>
  ... 
</dialog>

You see, there's no explicit role attribute, because the dialog role comes with the <dialog> element.

If not using a button with popovertarget, you could open this dialog with script using the showPopover() method that works on any element that is a popover (by having a popover attribute present).

Note: because this specific popover example uses the <dialog> element, two other methods are also available (through the HTMLDialogElement): show() and showModal(). They have slightly different behaviours than showPopover() would. I recommend against using these two methods on dialogs that are popovers. In other words, if you're inclined to use them, you probably don't want the popover attribute, as that attribute's purpose would basically be defeated by show()/showModal() (also, in some cases you might get a console error if you try to run showModal() on a popover). Popover is really for non-modal dialogs; see also my post on dialogs vs popovers).

Other examples of elements that could have popover behaviour and a dialog role are:

  • teaching UI
  • pickers, like for a date, multiple dates, prices
  • “mega navs” and other large navigational structures that cover a lot of the page (note: these should not use role="menu", a navigation with links is semantically different from a menu with buttons)

booking form that shows train selected from bologna to berlin, with passengers dialog opened that allows selection of how many adults and how many bicycles and includes a Done button A dialog that allows the user to specify their travel group and amount of bicycles

paragraph of text, in the middle is an audio player with heading “listen to this story”; overlaid is a dialog that says Listen to this story; Save time by listening to our audio articles as you multitask with an OK button underneath and a button with a close icon in the top right corner A dialog that teaches what the audio player is for

travel website with three nav items: discover, travel infromation and customer service; on hover of the nav items a dialog opens with headings and links over multiple columns opens A “meganav” that covers other content (note: this is a dialog, not a menu)

Listboxes / autocompletes: the listbox role

A listbox is for elements where the user gets to choose from one or more options, like a <select>. They can exist as single select (user can select one option) or multi select (user can select multiple options).

Listboxes are often part of an autocomplete or combobox widget, they are the part that contains the actual options. Like in this example:

a bank transfer screen where the cursor moves to select a currency from a list Select menus also use listboxes to allow users to pick an option from a list

For instance, in the following example, there is a component that pops over the page's content. It contains filter and sorting buttons, as well as a listbox with actual options. The element with popover is probably a dialog (and you could give it a dialog role), while the element that contains options would need a role of listbox:

search field as part of an interface's top bar, two characters are entered and a list of possible things to search for pops over in a box that also contains filters and sorting options A listbox as part of a combobox

Tooltips/toggletips: tooltip (with caveats) or dialog

In their simplest form, tooltips are like the title element in HTML, that browers display on hover. These browser built-in tooltips are problematic in many ways, including that in most browsers, there is no way to get to the contents of title with just a keyboard. Let's call them “plain text tooltips”. They are often customised by developers, for instance to change their visual styles (currently from scratch, maybe via CSS in the future).

two screenshots of tooltips on the left a thumbs up reaction emoji with a tooltip that shows four people who left that reaction, on the right a tooltip in a wysiwyg-style editor that explains that the link icon is to add a link Plain text tooltips that display on hover or focus of a triggering element, which they describe

Sometimes they are also found underneath input fields, to explain what that input does or what is expected, like some of Scott O'Hara's custom tooltips examples.

These custom “plain text tooltips” are what the tooltip role seems to be meant for. Note that role="tooltip" doesn't do much in terms of screen reader announcements as Sarah Higley explains in Tooltips in the time of WCAG 2.1, though there are cases where ARIA-provided labels and descriptions don't work across browsers and assistive technologies without the role (if they aren't interactive, iframe or img elements and also don't have a landmark or widget role). What is useful for accessibility of that kind of tooltip, going beyond roles for a moment: use aria-describedby to link up a tooltip that describes a thing with that thing, and never place essential content in them. Also ensure that the tooltip (1) stays visible when its content is hovered, (2) is dismissable (with Escape) and (3) persists until hover/focus removed, dismissed or irrelevant (all required to meet WCAG 1.4.13).

My advice would be that whenever tooltips contain more than just plain text, a non-modal dialog would be more appropriate (even if elements with tooltip role were apparently meant to also allow for interactive elements). Non-modal dialog tooltips could contain semantic elements (like a heading) or interactive elements (like a link or a button). In most cases it would be best to display them on click instead of hover + focus, in which case they are really “toggletips”. Of course, if there is interactive content, that also means you'll want to consider focus order.

Conclusion

In this post, we've covered some of the most common semantics you could choose to use with the popover behaviour: menu, dialog and listbox, plus looked at using tooltip for plain text tooltips or dialog for tooltips that contain anything more than plain text. Are you building components that don't really fall into any of these categories? I'm curious to learn more, slide in my DMs or email!


Originally posted as Semantics and the popover attribute: which role to use when? on Hidde's blog.

Reply via email

Back to freelance

I have returned to working as an independent front-end / accessibility / devrel person. My first project will be at the Dutch government's NL Design System team.

Leaving Sanity

I recently left Sanity, where I worked in the developer relations team. After doing some “developer relations”-like work at the W3C/WAI, this was my first full-time role in the space. I loved the variety: I could create tutorial videos, improve onboarding, facilitate content design workshops, help with meetups, inspire people to structure their content (more abstract than HTML) and just generally try to make complex stuff easier to understand. Among people I liked and bonded well with… how lucky I got!

It was also an opportunity for me to leave accessibility as my primary focus, at least for a while, and broaden my horizons. Well, leave accessibility as my primary focus… though my manager at WAI had warned me about this, calling it a bit of a Hotel California situation. He was, of course, correct. At Sanity, I did spend more time in the React community, learned lots about modern tooling and challenges like real-time content management. But I also ended up as the resident accessibility go-to person and did a preliminary accessibility conformance evaluation of the core product. It was appreciated, and I, in turn, appreciated having curious and dedicated colleagues to work with.

New beginnings

Having said that, my job at Sanity stopped existing. After some explorations, I'm going back to be a freelancer / independent. I've worked in that capacity for about 15 years, it feels like a comfort zone. I also have a very exciting project to start with, that manages to combine a number of my previous interests: developer relations, web accessibility and designs systems.

NL Design System

This month, I'm joining the NL Design System core team. This project doesn't just create a design system for use by Dutch government, it creates a space for collaboration on front-end components in the open. This is the sensible thing to do, because there are a lot of Dutch government websites and services (in the tens of thousands). Many of those have their own design systems, suppliers and ways of working. But they all need to meet the same accessibility standards and there is a lot of overlap in user experience needs. Collaboration in these areas should be super beneficial. Of course, it comes with challenges, too, and the team is ready… well, as far as one can be.

screenshot of nldesignsystem.nl The NL Design System website

I'm looking forward to help with:

  1. accessibility: of components, in documentation (I have opinions) and in applying standards well
  2. developer relations: technical writing, outreach between the core team and collaborating teams (current or future), improving the product based on developer feedback

This is a team that people have wanted for a long time serving needs that have gone unserved for a long time, too. There's a lot of realism to be had, because, of course, one design system or team cannot magically make all the websites better, but I strongly believe in design systems (and specifically this project) as a multiplier for accessibility efforts. I am, in other words, thrilled to become part of this particular team.

Workshops / talks

In addition, I will continue to do full day workshops and other public speaking about the web and web accessibility. Two things in particular:

  • a full-day workshop called “Accessibility for design system teams”, which I've started to deliver to in-house teams that are keen to use their design system as a way to increase accessibility in their product(s) and want to understand what that means in theory and practice
  • a talk on popovers and dialogs that I'll present at various conferences this year, the first one at CSS Day in Amsterdam, which is pretty much my favourite front-end event

me in front of a slide that says accessibility and design systemsWorkshopping at Sanoma Learning

Audits

Lastly, I also plan to do a small amount of accessibility conformance audits, focused on helping teams figure out which accessibility barriers their site has and how to fix them (I call this issue oriented reporting) (and sorry, that also means I will probably say no to teams whose only goal is a report).

Wrapping up

That's all. I hope my new freelance life will also allow me to do some more blogging on this website. The drafts folder isn't the issue, I guess 😁. For now, thanks for reading!


Originally posted as Back to freelance on Hidde's blog.

Reply via email