UX

The anatomy of visually-hidden

Visually-hidden styles are used to hide content from most users, while keeping it accessible to assistive technology users.

It works because the content is technically visible and displayed — it appears in the accessibility tree and the render tree, both of which are used by assistive technologies — it’s just that the rendered size is zero.

Our industry has largely settled on a standard CSS pattern for this, refined over years of testing and iteration, by many people. This pattern:

Code language: CSS

.visually-hidden {
    clip: rect(0 0 0 0);
    clip-path: inset(50%);
    height: 1px;
    overflow: hidden;
    position: absolute;
    white-space: nowrap;
    width: 1px;
}

[…]

This article is not about when or why you would use visually-hidden content. There’s a number of excellent articles that discuss these questions in detail, notably Scott O’Hara’s Inclusively Hidden. But most of them don’t go into much detail about the specific CSS involved — why do we use this particular pattern, with these specific properties? So today I’m going to dissect it, looking at each of the properties in turn, why it’s there, and why it isn’t something else.

Accessible Text Labels For All

When you navigate this page using VoiceOver, and use the Form Controls menu, you’ll get a list of all form controls on the page, including the Add to Cart buttons.

Quickly scanning these buttons you can tell that they provide very little value, as there is no way to tell which product each button corresponds to. How does a user know which button they want to go to and press if they don’t know which product it corresponds to?

[…]

A popular example of Voice recognition software used to browse the Web is Dragon Naturally Speaking.

[…]

Seeing it in action is the best way to get an idea of how it’s used. So, to quickly demonstrate how it is used on the Web, Level Access created a video demoing Dragon Naturally Speaking to fill out a form on a page. The following video is a short clip from their video which you can find and watch in full on [YouTube].

 

When the dragon user (in the video) wants to select a form control, he speaks out the visual text label of that control. This is one of many reasons why visual labels are important in user interfaces.

So when we have a series of Add to Cart buttons, a dragon user will speak the label of the button in order to interact with it. This is why adding text in the middle of the string makes it inaccessible. The content in the middle of the string would break the visible label. The user would be telling dragon to interact with a button whose label is not what it visually appears to be.

[…]

So whenever you need to add additional text to a visible label, it best come after what’s visually shown.

Similarly, always ensure the accessible name (announced by screen readers) matches the visual label as much as possible. This means that you’ll also want to avoid adding a label using aria-label that does not match the text label that is shown on a control.

Focus rings on Discord

This is a fascinating deep dive by the people at Discord on their development of a focus ring component and all the problems they had to overcome:

Browsers implement default focus rings that apply to all elements, but the ability to style these is (currently) very limited. These rings, while they have recently improved greatly in Chrome and Edge, are also not very pleasant when integrated with the rest of Discord’s design, and other browsers like Firefox are almost entirely invisible in most cases due to the thinness and low contrast of their styles.

As such, we want to implement a custom focus ring style. At a glance, this seems relatively simple, but when dealing with the variety of use cases Discord has for these rings, the list of requirements quickly grows, and the options for implementations shrink.

Ideally, we want to match the browser’s focus ring behavior exactly. Within Discord, this means that a comprehensive focus ring implementation needs to:

  • Perfectly map to the element that has focus (with exceptions listed below).
  • Follow elements as they move when containers scroll.
  • Follow elements as they animate and transition within the document.
  • Not be clipped off when the focused element is bounded by overflow: hidden or other bounding techniques.
  • Respect occlusion of overlapping elements, but not be occluded by an element’s own z-index.

Additionally, to be able to implement pleasant and overall better focus styles for various elements in the app, we have additional requirements to be able to:

  • Apply the focus ring on a different element than the actual focused element
  • Provide positional offsets to adjust ring placement around the element.
  • Adjust ring styles to match the look and feel of the surrounding context (could include changing border radius, color, shape, and more)
  • Specify a style for when focus is within an element, for example to indicate the bounds of a widget.

See the source link for the rest.

Accessibility issues with toasts and how to mitigate them

You may have recently read Adrian Roselli’s Scraping Burned Toast, Chris Coyier’s summary of the current “toast conversation”. Or maybe you’ve browsed the GitHub repository for A Standard ‘Toast’ UI Element and its WICG discussion thread.

Or maybe you’re familiar with the concept of toasts from Android development and Material Design.

But regardless of how familiar you are with the concept of a “toast”, work has been progressing on try to pave the existing cow paths different UI library definitions have set for said potential component. Unfortunately, the level of concern given to the accessibility and inclusive UX of a toast component varies quite a bit, depending on which component library you review.

[…]

Defining a toast

[…]

At a high level, toasts should be used to indicate the completion of a task or process initiated by the user or the application itself. For instance, a notification verifying the saving of a file, that a message had been properly sent, or a that a meeting was about to start.

If someone were to ignore, or miss a toast message, due to its timed display, there should be no negative impact on their current activities or the status that the message conveyed. Using the previous examples, ignoring a toast message would still mean that a file was saved, that a message was sent, or that a meeting was about to start.

[…]

Inclusive UX of a toast

A toast component should be considered a type of status message, and thus should be given a role="status". This will ensure that when a toast is displayed on screen, its contents will be, politely, communicated to assistive technologies, such as screen readers.

Ideally, a toast component should contain no interactive controls, as by doing so an immediate divergence of inclusive UX is introduced.

 

See the source link for a list of issues and some ways to mitigate them.

The self-fulfilling prophecy of poor mobile performance

There are plenty of stories floating around about how some organization improved performance and suddenly saw an influx of traffic from places they hadn’t expected. This is why. We build an experience that is completely [unusable] for them, and is completely invisible to our data. We create, what Kat Holmes calls, a “mismatch”. So we look at the data and think, “Well, we don’t get any of those low-end Android devices so I guess we don’t have to worry about that.” A self-fulfilling prophecy.

I’m a big advocate for ensuring you have robust performance monitoring in place. But just as important as analyzing what’s in the data, is considering what’s not in the data, and why that might be.

Setting Height And Width On Images Is Important Again

An example layout with a title and two paragraphs, where the second paragraph has to shift down to make space for an image.

Layout shift after image loads.

tl;dr: browsers now prevent layout shifting when images load using the inline width and height values, provided that you use the correct CSS properties when making images responsive.

Layout shifts are very disrupting to the user, especially if you have already started reading the article and suddenly you are thrown off by a jolt of movement, and you have to find your place again. This also puts extra work on the browser to recalculate the page layout as each image arrives across the internet. On a complex page with a lot of images this can place a considerable load on the device at a time when it’s probably got a lot of better things to deal with!

The traditional way to avoid this was to provide width and height attributes in the <img> markup so even when the browser has just the HTML, it is still able to allocate the appropriate amount of space[:]

Code language: HTML

<h1>Your title</h1>
<p>Introductory paragraph.</p>
<img src="hero_image.jpg" alt=""
   width="400" height="400">
<p>Lorem ipsum dolor sit amet, consectetur…</p>

Then the render [should happen] like below, where the appropriate amount of space is set aside for the image when it arrives, and there is no jarring shift of the text as the image is downloaded:

An example layout mockup with a title, a paragraph, space for an image and then a second paragraph, where the text does not shift when the image loads.

Text should not shift if image dimensions are provided so appropriate space can be allocated.

Even ignoring the annoying impact to the user in content jumping around (which you shouldn’t!), the impact on the CPU [of layout shifts] can also be quite substantial.

[…]

So, once we add the dimensions and [max-width: 100%; height: auto;], we get the best of both worlds, right? No layout shifts, but also the ability to resize images using CSS? Well until very recently you might have been surprised to find out the answer was in fact: no (I was — hence why I decided to write this article).

[…]

This affects any page where we constrain the image size in a responsive manner — i.e. small screen mobile devices. These are likely to be the very users suffering with network constraints and limited processing power that will suffer most from layout shifts! Of course, we ideally should be delivering appropriately sized images for the screen size, but you cannot cover every device size, so often images will need some resizing by the browser, particularly on mobile.

[…]

[I]f the following four conditions are true, then the correct image dimensions could be calculated without needing to wait for the images to download, and so without the need of a content layout shift:

  • height is set on the element in HTML
  • width is set on the element in HTML
  • height (or width) is set in the CSS — including using percentage values like max-width: 100%;
  • width (or height) is set to auto in the CSS.

If any one of these were not set, then the calculation would not be possible, and so would fail and be ignored and have to wait for the image to be downloaded.

[…]

So instead [of waiting for a new CSS property], [browsers] could implement the equivalent logic deep in rendering code rather than exposing it via the user-agent stylesheet, but the effect is the same.

[…]

Firefox went ahead and did this as an experiment and then turned it on by default for Firefox 71. Once that was released, then your site may well have just got faster for free — thanks Mozilla!

[…]

After Firefox’s successful experimentation, Chrome also decided to implement this (again using the layout coded method for now rather than default user-agent stylesheet), and rolled it out by default in Chrome 79. This also took care of the other chromium-based browsers (Edge, Opera and Brave, for example). More recently, in January 2020, Apple added it to their Tech Preview edition of Safari, meaning it should hopefully be coming to the production version of Safari soon, and with that, the last of the major browsers will have implemented this and the web will become better and less jolty for a huge number of sites.