Problem/Motivation

The current designs for buttons has some accessibility issue that could be improved in the focus state. After @modulist and @andrewmacpherson suggestions in #3021087 its was clear the current design needs to improve the focus state in all elements. The main issues were:

  • The focus element shouldn’t have the exact same color as its target.
  • If it’s a similar color (color shade) it should have an offset.
  • It should have a contrast > 3:1 with background.
  • Adding size/shape changes like the offset outline is an improvement.

Proposed resolution

We propose a new color for the palette: the turquoise #26A78D, which has a contrast ratio of 3.00:1.
We also add several form elements and it's implementation to see it working so we can get feedback in general (color) and per component (aka radios, tabs, buttons...).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

saschaeggi created an issue. See original summary.

saschaeggi’s picture

Issue summary: View changes
FileSize
315.69 KB

ckrina’s picture

Issue summary: View changes
FileSize
90.14 KB
12.05 KB

Updating issue summary & credit.

ckrina’s picture

Issue summary: View changes
FileSize
90.48 KB

Adding a page example for better context.

ckrina’s picture

FileSize
88.41 KB
90.52 KB

Something we were doubting with was how to handle active + focus states and in which devices/tools to navigate they're the same or not. So some advice here would be great too, specially to consider designing them in a way all can be combined.

ckrina’s picture

Issue summary: View changes
huzooka’s picture

What if the same outline-offset was applied on radios/checkboxes as the buttons have?

andrewmacpherson’s picture

Thanks for opening this. It would be great to aim for a uniform focus style, instead of managing a variety of different ones.

I like the proposals here a lot. For completeness, we should confirm how this looks for all components. There's enough here to imagine what they will look like - e.g. for a simple link, or the breadcrumbs, or the secondary tabs.

The big question: is there any component where the green offset outline won't fit in?

Some components are worth exploring a bit more:

  • Drop- buttons: they have multiple focusable controls in the same "button". The main operation, the arrow, and the rest of the operations. Outlining these involve drawing a line through the component as a whole.
  • Vertical tabs: these have styles to indicate the current tab, and the focus styles have to look distinct from that.
  • Others...?

I think the designs here (and all the work done on Claro so far) demonstrate that attractive general-purpose focus styles are achievable. There's a persistent myth that focus styles are ugly, and I think we're going to bust that myth with Claro. (We managed to achieve a unified focus style to a large degree in Umami, though there are a few tricky ones involving call-to-action links on the hero image.)

Adding a related discussion about doing this for Bartik, which has languished for ages It has a lot of focus style examples. Some of the comments are against focus styles, or say that none of the styles are nice enough to look at.

andrewmacpherson’s picture

Also some related issues about Seven's shortcomings with focus styles. Hopefully these are informative for Claro.

saschaeggi’s picture

@andrewmacpherson it took a bit longer than expected ;-) We tried different options but now have a final proposal:
Focus Examples

And how the will look within the UI:
Focus Examples

So we now have defined a dedicated color for everything relevant to focus (the new AA-compliant green). We're looking forward to hear your feedback.

andrewmacpherson’s picture

Issue tags: -Accessibility +accessibility

I love the latest version in #12. This is an amazing piece of work!

We've established that the green outline will have 3.08:1 contrast against a white background, but there are other backgrounds to consider:

  1. The grey background of the header region. This is for focus on the primary tabs (pictured in #12), breadcrumb links, etc
  2. The background of the open node metadata details (e.g. the focussed URL settings checkbox pictured in #12)
  3. The table header background colours in #3021388: Table style update, because these contain focusable sort buttons, and the select-all checkbox.
  4. The table row backgrounds, because rows can contain lots of focusable controls: bulk operations checkbox, links, drop-buttons, etc. The focus indicator needs to have sufficient contrast against the various row background colours, e.g. when a row is selected, the background is darker blue, but a user still needs to be able to discern focus on the bulk-operations checkbox, so they can un-select rows.
  5. Other background? e.g. vertical tab headers, links in message regions, the toolbar trays, ...

What does text 5.04:1 refer to in #12?

The proposed design for the focus indicator uses rounded corners, in some cases actually circular. There are some implementation aspects to complicate this:

  1. CSS borders get border-radius, but there is no corresponding outline-radius. So we can't achieve the rounded corners or circular style with outline-*.
  2. Outlines have an outline-offset available, but it doesn't work in IE, so we'd loose the white striping affordance there. There are some interesting workarounds involving selectors like :focus::before with an absolute position and using top/bottom/left/right to control the offset.
  3. Outline and border styles are respected in windows high contrast mode, but with colours overridden. This is where the offset will really help. However, note that transparent is a colour for purposes of windows high contrast mode, and will be overridden. So we can't use a transparent border for the un-focussed styles.
  4. Box-shadow is stripped out by Windows high-contrast mode. However a workaround for this is to use a :focus {outline: dotted 2px transparent; } which will become visible in windows high contrast when the box-shadow is stripped out.
lauriii’s picture

@andrewmacpherson I worked on a customized overlay with border-radius: http://jsfiddle.net/lauriii/y7qdghjm/. Could you check if this works accessibility wise?

saschaeggi’s picture

andrewmacpherson’s picture

#14
Yes, that's more or less what had in mind in #13.

However, I didn't intend to actually specify a white border explicitly like this: button:focus { border: 1px solid #fff; }. Instead, I imagined it would be the white page background showing through in between. In Windows high contrast mode, all foreground colours are overridden, but border style and width are preserved. So if the yellow-on-black WinHC theme is used, the 1px white border, and the 4px blue border would both be overridden as yellow, looking like a single 5px border. The visual gap between the button and focus ring would be lost. If we remove that 1px border, the black page background will show in between, and the separation between the button and focus ring is preserved.

button { 
  position: relative;
  /* ... etc. */
}

button:focus::after {
  position: absolute;
  content: '';
  display: block;
  height: calc(100% + 4px);
  /* background-color NOT specified, so the underlying page container background show through the gap */
  top: -4px;
  left: -4px;
  right: -4px;
  bottom: -4px;
  border: 2px solid #26A769;
  /* ... etc. */
}

The thing that bothers me is the element name in the selector - can we get away with :focus::after? Ideally there would be one general-purpose focus style, and minimize the need for focus styles per component. The circular focus ring on the pager would just be a border-radius override, say.

Also, if using position: absolute for the focus ring, that means that every focusable thing will need position: relative? That would also be good to do in the most generic way possible.

#15:
I'm very wary of these JS approaches to focus styling, especially when there are mouse or keyboard event listeners in the script.

A common misconception is that focus rings are only for keyboard users, and shouldn't be shown when a pointer is used. This usually follows from the other big misconception that focus styles are ugly/clutter. So the idea emerges that they should only be shown when necessary, i.e. for keyboard users. These scripts put users in silos based on input device.

The reality is more nuanced, and isn't just about motor impairments. It's true sighted keyboard-only users rely on the focus indicator to do anything at all, but focus indicators help users in several other ways too. Speech control users benefit from seeing form focus, and can say "next field". When clicking on a link in a list, the focus ring gives confirmation that you clicked the intended target (and an opportunity to cancel an unintended page request by pressing escape).

FocusHighlight: this makes the outright assumption that focus indicators should not be shown when using a mouse. It exploits the event firing sequence (mousedown, then focus, then mouseup) to determine that the focus event occurred as a result of a mouse click, and avoids showing the focus indicator.

Flying Focus: I tested this one on the ssb.ch website you mentioned in the Slack channel. It's certainly very noticable, but also seems fragile. Sometimes the focus indicator wasn't shown at all, but I couldn't deduce the exact steps to replicate the problem, even after studying the code on github. It seems that if you use a mouse to focus an element, then use swap to using the tab key, you don't see the focus outline until you press tab a couple of times. Then if you change back to using the mouse to focus something, the focus indicator follows for a while, but disappears after a couple of clicks. I think it might be trying to make the focus indicator into a keyboard-only thing, but it's based on when you last used a keyboard action, and whether the focus is currently shown. I couldn't fathom the logic, and it's very confusing for someone who makes mixed use of mouse and keyboard.

I'd greatly prefer to hang the focus styles off the :focus pseudoclass. It's a more reliable indicator of the focus state itself, instead of trying to figure out how the element got focus.

saschaeggi’s picture

FileSize
32.39 KB

@andrewmacpherson thanks for the answer!
So my idea was if we implement the :focus in blue for "regular" users and for a11y users we show an additional green focus outline.
Example:
a11y example

Looking forward to your reply :)

andrewmacpherson’s picture

Re. #17

What constitutes an "a11y user" vs. a "regular" user? More importantly, who decides what the user's needs are? This is (a) discrimination. and (b) impossible to determine. We cannot, and must not, put users into silos like this.

One day when technology permits, we will hopefully be able to write code which respects a user's preference for strong focus indicators. The web isn't there yet though. I'll support the use of the forthcoming :focus-visible pseudo-class IF a majority of browsers provide a way for users to say they always want strong focus indicators. However, browsers aren't required to do that in the current focus-visible draft, and if they don't then the pseudoclass is going to be a disservice to some users. The W3C focus-visible polyfill does not provide a way for users to choose strong focus styles.

Until then, use the same strong focus style for everyone.

saschaeggi’s picture

@andrewmacpherson I must apologize/clarify I didn't wanted to put users into silos. Maybe my words weren't chosen wisely. My goal was to provide a better experience to users who need assistance. Sorry if that sounded somewhat wrong. I totally agree with what you said. I just wanted to ask if we could use something like flying focus with this new proposal for focus.

I just checked the :focus-visible pseudo class as I wasn't aware that this proposal exists, thanks for pointing out.

saschaeggi’s picture

@andrewmacpherson we could use :focus-visible already with the @supports detection for browsers who already have support for it

andrewmacpherson’s picture

I just wanted to ask if we could use something like flying focus with this new proposal for focus.

Animations can help as part of focus styles, where a brief motion conveys "over here now". Yes, I think that's worth exploring.

The Flying Focus approach is to show it while moving from one place to another, which is done by managing an overlay div (which is not the thing that has focus itself). Personally, I think it's a bit too loud, although it does a good job of drawing attention in scenarios where the next control is far away in a different part of the page. It's also over-engineering things somewhat, and in testing I found it was a bit fragile.

Simpler approaches to animation use a CSS transition, so there's an brief animation around the item as it gains focus, but without showing the indicator "flying" from one control to another. This is much easier to implement with declarative CSS, and it can be suppressed with a prefers-reduced-motion media query too.

we could use :focus-visible already with the @supports detection for browsers who already have support for it

That that's a pipe dream for now, because:

  • CSS @supports doesn't detect support for pseudoclasses. Meh.
  • Currently no browser supports :focus-visible
  • And crucially, we have no idea whether browsers will support a user preference, for users who want :focus-visible to always behave like :focus does. Unless this happens, I don't want to use :focus-visible. It perpetuate the myth that focus is just for keyboard users, at the expense of users with cognitive impairments who also benefit from focus styles.

However, if browsers do implement an always-show-focus preference for :focus-visible, then a progressive enhancement approach could work. The CSS :not() selector can be used as a way of detecting support. See :focus-visible and backwards compatibility. It looks like this:

:focus { /* focus styles for browsers which don't support focus-visible */ }
:focus:not(:focus-visible) {
    /* undo all the above :focus styles for browsers that support :focus-visible,
        but have determined not to apply the pseudoclass */
}
:focus-visible   /* same as the :focus styles above */  }

For now, we should use :focus only, and we can add the progressive enhancement when there are some browsers that support a user preference. I'm excited by the prospect, but cautious about rushing into it.

modulist’s picture

Responding to #16 I'd like to point out that the purpose of the white border was to make the focus stand out on dark backgrounds as well. For that reason, I would recommend staying with an opaque white border, and not making it transparent.

I would also suggest having a transition that varies the outline's width (think: bounce) so that the user is certain to see where the focus is being applied. I'm not sure if a gentler transition can be made to re-appear periodically every 20 seconds or so after the focus event.

mgifford’s picture

Issue tags: -accessibility (duplicate tag) +Accessibility

Fixing tagging.

huzooka’s picture

Project: Claro » Drupal core
Version: 8.x-1.x-dev » 8.9.x-dev
Component: User interface » Claro theme
andrewmacpherson’s picture

@saschaeggi asked on Slack if we can close this now.

Yes. We have good coverage now for focus styles, so this can be closed.

There are a few cases where they could be improved a bit. We can use new small issues for those.

  • The primary tabs focus style looks a bit weird IMO, only on 3 sides.
  • The text and select inputs could be better. They aren't so obvious because there's less of a shape change. The border is slightly thicker, but it's not so obvious in grey scale. I think these would benefit from the green outline too. It would increase consistency and clarity.

The checkbox and radio focus styles are magnificent!

andrewmacpherson’s picture

Status: Active » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.