Skip to content

Add :focusring selector #709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 22, 2016
Merged

Add :focusring selector #709

merged 2 commits into from
Nov 22, 2016

Conversation

robdodson
Copy link
Contributor

Adds support for :focusring, related discussion here: https://lists.w3.org/Archives/Public/www-style/2016Mar/0250.html

:focusring only matches an element if the element is currently focused and a focus ring or other indicator should be drawn for that element. This is extremely useful for accessibility.

As @tabatkins explained on the mailing list:

The main benefit of such a thing is that, today, if the default UA focus ring style does not work well with your site's theme, you're kinda screwed. You can manually write a :focus rule, but you can't predict when an element would have a focus ring drawn; you'll unfortunately start drawing focus rings when the user mouse-clicks a button. Using :focus-ring instead does the right thing automatically, triggering your styles only when the UA determines via heuristics that it should draw a focus ring.

@frivoal frivoal added the selectors-4 Current Work label Nov 15, 2016
@JanMiksovsky
Copy link

This would be great to have! This would address one of the big problems we've had implementing focus in web components.

The other big problem: there's no consistent way to ask that the standard focus appearance be applied to an element. The case we've hit here is a custom combo box that contains an input element and a dropdown button.

  • We want the standard focus appearance to be applied to the entire combo box, not just the input element.
  • At the same time, we actually want the input element to have the focus. As with many combo boxes (e.g., Windows combo boxes, Chrome's address bar), we don't need the dropdown button focusable, relying instead on arrow keys to invoke them.
  • Hence, we want to tell the browser: Make this outer element look focused, don't make the actual input element look focused.
  • Unfortunately, we're not aware of any standard CSS that lets us apply the browser's own focus appearance to an element.

Could you possible tackle this problem at the same time as :focusring?

@robdodson
Copy link
Contributor Author

@JanMiksovsky if you're using shadow dom, have you looked into the delegatesFocus flag? It's a little confusing but here's a discussion on it: WICG/webcomponents#554

The tl;dr is that you can have :focus match on the containing element as well as the child that actually has focus.

enabled and how the element was focused. Whether the user agent has focus ring
drawing enabled can depend on things like the settings of the operating system
the user is using, so the precise behavior of this pseudo-class can vary from
platform to platform depending on each platforms' particular focus best
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: platform’s

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mathiasbynens fixed, thank you!

@StommePoes
Copy link

\o/
I'm tired of writing

    <script>
      document.addEventListener('mousedown',function() {
        document.body.classList.add('mouseDetected');
      },false);

      document.addEventListener('keydown',function() {
        document.body.classList.remove('mouseDetected');
      },false);
    </script>

...

elements blah:focus {
  super awesome visible fugly focus styles;
}
.mouseDetected elements blah:focus {
nope nope nope
or the graphic designer will have my head
}

because while it does work well enough for most things on desktop, mobile is a whole screwy other world. Plus it's javascript for what feels like should be a pure styling thing.

@patrickhlauke
Copy link
Member

patrickhlauke commented Nov 16, 2016

Lazy: so this essentially matches the behavior/explanation of :-moz-focusring exactly, right? https://developer.mozilla.org/en-US/docs/Web/CSS/:-moz-focusring

@robdodson
Copy link
Contributor Author

Yes, this is based on moz-focusring

On Nov 16, 2016 5:59 AM, "Patrick H. Lauke" notifications@github.com
wrote:

Lazy: so this essentially matches the behavior/explanation of
:-moz-focusring exactly, right?


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
#709 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/ABBFDSDgxpj1wlRuWWZokQF0Zyng8yOdks5q-wwrgaJpZM4KxmMy
.

@traviskaufman
Copy link

This would make a literal universe 🌠 of difference for Material Design Lite. Thanks for the excellent work on this. I was sad to see the input modality spec killed but I'm glad it's being resurrected and evolved into this.

<h3 id="the-focusring-pseudo">
The Input Focusring Pseudo-class: '':focusring''</h3>

The <dfn id="focusring-pseudo'>:focusring</dfn> pseudo-class is similar to the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mixed use of single and double quotes around the value of id might be a problem

platform to platform depending on each platform's particular focus best
practices (defaults) or user modified settings.

<div class='example'>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this class attribute value be wrapped in double quotes for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

* if a non-native element is focused, even if it did not become focused via
the keyboard, apply '':focusring'' to that element.

<div class='note'>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this class attribute value be wrapped in double quotes for consistency?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

double checking the spec I found examples of both "note" and 'note'. happy to do it all as double quotes though to make it consistent in the PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's not consistent across all the specs. Looks like this particular spec leans towards double quotes, hence my suggestion.

@SebastianZ
Copy link
Contributor

Regardless of the usefulness of the pseudo-class, I think it would be better called focusindicator or something like that, because it may not always be a ring that is shown.

Sebastian

…he non-normatives into advisements and examples.
@tabatkins
Copy link
Member

First, thanks so much for writing this! I've been working on other projects for a good while and hadn't gotten around to doing this, so it's much appreciated. I'm going to do some heavy editting and then merge this.

Regardless of the usefulness of the pseudo-class, I think it would be better called focusindicator or something like that, because it may not always be a ring that is shown.

I think it's okay to call it "focus-ring" even if the indicator isn't always a ring; optimizing for simpler terminology is good.

@tabatkins tabatkins merged commit c2ccd09 into w3c:master Nov 22, 2016
@robdodson
Copy link
Contributor Author

@tabatkins wonderful!! thanks so much for fixing it up 😸

@kaelig
Copy link
Member

kaelig commented Nov 22, 2016

Good job on getting this in!

@benfrain
Copy link

benfrain commented Nov 25, 2016

I realise that :focusring will be fine. I agree that something more on the node may be advantageous. I'd favour something like :has-focus which declares exactly what the selector is for but leaves the author open to style that focus however is relevant for the UI.

@cookiecrook
Copy link
Contributor

I think it's okay to call it "focus-ring" even if the indicator isn't always a ring; optimizing for simpler terminology is good.

What about :visible-focus or :focus-outline?

@cookiecrook
Copy link
Contributor

Presumably this would allow authors to style things differently depending on how things were focused?

For example: If you called .focus() on a heading with tabindex="-1", it would not need the focus indicator. Is that correct?

Likewise, a mouse click on a button could move focus to that button but not trigger a focus outline since it was focused via the pointer? However if the focus was triggered via a Tab key press, it should show the outline/indicator. This would avoid the common anti-pattern of hiding all visible focus style because the designers want to avoid mouse-triggered visual artifacts.

@robdodson
Copy link
Contributor Author

@cookiecrook

Presumably this would allow authors to style things differently depending on how things were focused?

Likewise, a mouse click on a button could move focus to that button but not trigger a focus outline since it was focused via the pointer? However if the focus was triggered via a Tab key press, it should show the outline/indicator. This would avoid the common anti-pattern of hiding all visible focus style because the designers want to avoid mouse-triggered visual artifacts.

Yes it is exactly for this use case.

For example: If you called .focus() on a heading with tabindex="-1", it would not need the focus indicator. Is that correct?

:focus-ring follows the UA's heuristic for when it decides to show a focus ring. In Chrome at least, if you focus() something with tabindex=-1 it will also show a ring. Having said that, I think there's room to refine that heuristic. For example, if you have a native <button> and you click on it with a mouse you will not see a focus ring. But if you style that button with something like border: none and then click on it, you will see a focus ring in Chrome, you will not in Safari. jsbin.

It may be a matter of figuring out what behavior we want from the UAs and working with them to ensure consistency.

@afercia
Copy link

afercia commented Jun 1, 2017

Hello everyone. Seems to me part of the intent here is based on the assumption that a clear indication of the focus benefits only keyboard users. To me, that doesn't seem a correct assumption. Reading the "Understanding SC 2.4.7 (Focus Visible)" it's pretty clear the intent of that guideline is to make focus always visible for all users. Also for mouse users. Quoting:

Specific Benefits of Success Criterion 2.4.7:
This Success Criterion helps anyone who relies on the keyboard to operate the page, by letting them visually determine the component on which keyboard operations will interact at any point in time.
People with attention limitations, short term memory limitations, or limitations in executive processes benefit by being able to discover where the focus is located.

They're just two examples. The second one is not related to the device in use.

@bradkemper
Copy link
Contributor

I think it is great to have this pseudo-class, but the name of it is dumb (no offense). It is describing what it looks like, I guess (or maybe it will "ring" like a bell for assistive tech?), instead of describing an understandable state.

It should be :keyboard-focus or :non-pointer-focus or something.

WRT focus for attention/memory limitations, I think that is why type-able controls, like text fields, show focus regardless of input method. But clicking or tapping a button isn't something that requires you to know that it has focus (and in the standard Mac UI, it doesn't even move the focus out of a text field). So that should be part of the heuristics.

That said, tabindex=0 does not really say much about whether focusing should be more like a text field or more like a button. I guess we could just continue to use :focus for text-fields. But it would be better if we had a css property (or @rule?) to make something focusable and to say what type of focus it should be.

@tabatkins
Copy link
Member

Reading the "Understanding SC 2.4.7 (Focus Visible)" it's pretty clear the intent of that guideline is to make focus always visible for all users.

That guideline doesn't end up matching reality. Browsers have settled pretty conclusively on, for some types of elements, only visually indicating focus when it's obtained via keyboard. Requiring people that just want to restyle the focus ring to also fundamentally alter their page's UI affordances is not very useful. If we believed that focus rings should show on all focused elements, this should happen at the browser level first for all pages; then :focus and :focus-ring would just be synonyms that we support for legacy reasons. Until that happens, letting people just restyle the focus-ring and not otherwise alter how/when focus is visually indicated is useful, and that's what :focus-ring does.


I think it is great to have this pseudo-class, but the name of it is dumb (no offense).

It was named :focus-ring because that matches Moz's name (with fixed hyphen usage), and suggests, in a very clear way and simple way, when it'll match - when the focus ring would normally show up - and what it's intended for - restyling the focus ring. Any other name attempting to nail down the concept more semantically/abstractly loses this, requiring people to read spec text and grok the distinctions between this and :focus more explicitly. That sort of understanding is useful, no doubt, but it's not required to use :focus-ring correctly.

@patrickhlauke
Copy link
Member

patrickhlauke commented Jun 1, 2017

Reading the "Understanding SC 2.4.7 (Focus Visible)" it's pretty clear the intent of that guideline is to make focus always visible for all users.

For mouse users, the focus is always wherever they move their mouse to and click. This is different from keyboard users who need to know their current position within the document.

The problem with using straight :focus is also that it can end up confusing users. Take, for example, a series of buttons on a page that trigger some in-page behavior. They trigger every time the user activates them. Now a mouse user clicks one to trigger its specific behavior, and the :focus styles kick in. The button now looks visually different from the other buttons. However, it still functions exactly the same as before. This can confuse sighted mouse users who may think the button is now...different (maybe they think it's disabled, or that the button is some kind of on/off toggle, etc).

So, from an accessibility and usability issue, I would actually advocate for :focus-ring in these cases, and I would not fail this under WCAG 2.0 SC 2.4.7

additionally, note that most modern browsers are already silently optimising away their default focus indication (if not explicitly set by the page/author) on certain elements (like buttons) following a mouse activation. this just bridges the gap for author-defined focus styles to behave the same way.

@afercia
Copy link

afercia commented Jun 1, 2017

For mouse users, the focus is always wherever they move their mouse to and click. This is different from keyboard users who need to know their current position within the document.

As I read it, the point of "Understanding SC 2.4.7" is that also people with attention deficit, etc., greatly benefit from a clear indication of focus, even if they're mouse users. This is the spirit of the guideline, unless I'm misreading it.

@afercia
Copy link

afercia commented Jun 1, 2017

note that most modern browsers are already silently optimising away their default focus indication (if not explicitly set by the page/author) on certain elements (like buttons) following a mouse activation.

Yep I know, and this differs also across platforms. See for example current Firefox (53) on macOS (no focus indication on buttons) and on Windows (has focus indication). The current situation is pretty confusing but, as I see it, hiding focus on mouse activation on certain elements is against WCAG 2.0 SC 2.4.7. If things are going to change (I hope not), then WCAG 2.0 SC 2.4.7 should be updated to reflect the change?

@patrickhlauke
Copy link
Member

Reading the actual SC itself

2.4.7 Focus Visible: Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible. (Level AA)

note the "has a mode of operation". When the user uses the keyboard, :focus-ring (and the silently optimised default focus indicator) are shown, thus fulfilling the requirements of the SC.

@afercia
Copy link

afercia commented Jun 1, 2017

SC text are very synthetic :) I guess that's the reason why they're accompanied by an "Understanding".

People with attention limitations, short term memory limitations, or limitations in executive processes benefit by being able to discover where the focus is located.

Is clearly related to mouse users too.

@robdodson
Copy link
Contributor Author

I don't think this needs to be seen as being only for keyboard users, quite the contrary, my hope is that :focus-ring could make it easier for users to define when they want to see focus indicators.
Here's the relevant bit of spec language:

an E element that has user input focus, and the UA has determined that a focus ring or other indicator should be drawn for that element

Since the UA gets to determine when to draw a focus ring, it means we now have access to some interesting options.

For example, today the UA checks to see if the user is using a keyboard to move around, if they are, then :focus-ring matches. But it could potentially include user configuration options as well. So one day the browser could expose a user preference for strong focus indicators. Checking that option would tell the UA that even if someone clicked on a control using the mouse, it should still match :focus-ring.

Personally I understand the argument for always displaying a focus indicator even on mouse click, but in practice I've found that these can be tough battles to win when your designers or project managers disagree. You may end up with very compromised focus styles that are subtle so as not to offend mouse users, but are therefore less useful to any user who wants a strong focus indicator. Or as @patrickhlauke pointed out, the focus indicator might be confusing to a mouse or touch user who wasn't expecting it. :focus-ring (hopefully) helps address this in a way that makes everyone happy.

@StommePoes
Copy link

StommePoes commented Jun 22, 2017

We just got a complaint about a button showing its focus colours after some testing mouse users tested it. The button removes something from the page. Focus remains on the button (natch). The users thought they broke something (thought they made the button quit working) and the designers were, on the basis of that, asked to stop making the button change colour when clicked.

I think this is partially due to a combination of browsers acting a bit different regarding buttons than, say, links and inputs, and secondly because it's become super a la mode fashion hipster trend to go Material-Design-style where all the interactive feedbacks are so so so subtle that if you have anything less than the greatest-newest-sharpest monitor and eyeballs, you don't even see it. Example: faint shadow on clickable disappears when focussed. I think a lot of mouse users have simply not even noticed their buttons looked like a faintly different shade of blue all this time. And that's only IF designers and developers even bothered to add something other than :hover styles.

That's not to say there aren't any good cog reasons to show last-clicked or where focus is currently; but then that would need to be something any individual user could set (ideally in their browsers or OS and NOT via some crazy widget on the web page written by J Random Developer), because of that large majority of casual-mousers who get a disadvantage of being surprised, confused, and hitting against the element of least surprise.

@kizu
Copy link
Member

kizu commented Jun 27, 2017

Hi everyone, I've wrote an article today about having keyboard focus-only styles — http://kizu.ru/en/blog/keyboard-only-focus/ — alongside other things I've looked at how the existent :-moz-focusring behaves, and found out that it doesn't work for spans with added tabindex, while it works ok for buttons and links. In my opinion, the new property should work for any interactive element, not only for those that are initially interactive, as I can imagine people creating new interactive elements that are not semantically covered by links and buttons, but which should still have the same functionality in regards to focus styles and clickability.

@robdodson
Copy link
Contributor Author

robdodson commented Jun 27, 2017 via email

@tabatkins
Copy link
Member

The selector should match exactly and only those elements that, in the absence of author styling, would receive a native focus ring. If you want it to match in more situations, the correct approach is to get browsers to show a native focus ring in those situations. :focus-ring should never diverge from the native focus ring.

@kizu
Copy link
Member

kizu commented Jun 27, 2017

@tabatkins What is considered “native” focus ring? When an element has tabindex="0", is the focus ring on it in absence of any styles considered “native”?

@tabatkins
Copy link
Member

It means there's a focus ring drawn on it by the browser. Yes, that particular example counts, at least in Chrome (I see a focus ring when I tab to the element).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
selectors-4 Current Work
Projects
None yet
Development

Successfully merging this pull request may close these issues.