focus-visible icon indicating copy to clipboard operation
focus-visible copied to clipboard

Brainstorm: options for opting in to always matching focus ring

Open alice opened this issue 8 years ago • 24 comments

We know we need a way to opt an element in to always (or never?) getting a focus ring. Let's talk about strategies for doing this.

alice avatar Jun 18 '17 22:06 alice

Proposal: just use :focus

Use the existing :focus pseudo-selector to opt an element in to always getting a focus ring on focus. Requires a way to recover the platform default focus style, assuming :focus-ring will be the UA default in future (which we should probably provide in any case).

Example

custom-text-editor:focus {
  outline: platform-default;  /* need a way to express this */ 
}

Pros

  • Potentially makes the mental model of :focus-ring easier to understand
  • Could use same strategy in UA stylesheet, e.g. input[type=text]:focus

Cons

  • No scope for any more nuanced matching options
  • Requires an extra concept (albeit one we probably want anyway) to allow re-enabling the platform default focus ring.

alice avatar Jun 18 '17 22:06 alice

Proposal: add a new CSS property to express when an element should match :focus-ring

Allow an element to opt in to :focus-ring matching the way built-in text editing elements do. Potentially also allows fine tuning focus-ring matching at page author discretion.

Example (all syntax to be considered a "straw man")

custom-text-editor {
  show-focusring: always;
}

div[tabindex=-1] {
  show-focusring: never;  /* may potentially be overridden by user preference */
}

* {
  /* match when focus is moved via the keyboard explicitly, i.e. tab/shift-tab */
  show-focusring: explicit-focus; 
}

button {
  show-focusring: on-keypress;
}

Pros

  • More nuance possible

alice avatar Jun 18 '17 23:06 alice

cc @shans

alice avatar Jun 19 '17 08:06 alice

@alice I think your 2nd proposal is far far better than pursuing the current :focus-ring implementation; it's more robust.

  1. Allows for fine grain control over when the focus ring is displayed; solving for all of the various niche cases discussed in #33
  2. Makes it much easier for authors to preserve browser default focus styles (should they want to)
  3. Feels more with-the-grain of CSS; reminds me of how overflow works.

Nice one.

kloots avatar Jun 20 '17 19:06 kloots

I like the second proposal if we can get buy-in. And I also want outline: platform-default; :)

robdodson avatar Jun 23 '17 16:06 robdodson

@alice @robdodson what's the next step for moving on @alice's proposal?

kloots avatar Jun 23 '17 17:06 kloots

@kloots I think one thing alice and I were unsure of: were you saying you like the second proposal instead of :focus-ring or in addition to :focus-ring? In other words, were you suggesting we drop :focus-ring entirely and pursue that other proposal?

robdodson avatar Jun 26 '17 16:06 robdodson

@robdodson yeah, I really like @alice's second proposal and think it'd be better for the industry if we pursued that over :focus-ring.

kloots avatar Jun 26 '17 17:06 kloots

To clarify: this was always intended to be as well as :focus-ring, and affect when :focus-ring matches. :focus can't be changed at this point (believe me, we went around and around on this previously).

The full story would then hopefully look like:

  • Browsers provide a default :focus-ring style in the UA stylesheet.
  • Authors may override that style if they wish.
  • Authors may use outline: platform-default (whatever it ends up being called) to reset the outline style further on down the cascade.
  • Authors may also fine-tune when they wish certain elements to match :focus-ring.
  • :focus will continue to match any active element.

alice avatar Jun 27 '17 00:06 alice

@alice thanks for the clarification. Man, sorry to hear :focus cannot be changed because that's the obvious pseudo-selector everyone knows about. Giving developers a new CSS prop that would allow authors to fine tune when it matches and what it looks like seemed really with the grain of how other things in CSS already work; like when border-radius was introduced years back.

kloots avatar Jun 27 '17 15:06 kloots

Next steps:

  • Write up full proposal for show-focusring (whatever we call it) property
  • Figure out the status of outline-style, which allows recovering the platform outline style if used correctly
  • Propose :focus-ring and show-focusring at CSS WG in Paris in August.

alice avatar Jun 28 '17 01:06 alice

I really like the way this is going. It seemed difficult to support all necessary use cases with :focus-ring alone, and this provides a lot more control for handling focus states within a deep cascade. We'll have a challenge explaining why :focus couldn't be used no matter which way we go, so at least if the APIs allow us to achieve more detailed focus we'll be successful at getting UI jobs done (and then relaying to others how we did it). Curious to hear how the proposal goes over with the CSS WG.

marcysutton avatar Aug 07 '17 17:08 marcysutton

regarding this example:

custom-text-editor:focus {
  outline: platform-default;  /* need a way to express this */ 
}

I just learned about the revert value. It looks like only Safari supports it but I think this might be what we want.

robdodson avatar Aug 11 '17 20:08 robdodson

@robdodson nice one!

kloots avatar Aug 11 '17 22:08 kloots

I'm really glad to see this conversation happening: Early on I posited that we needed more than just :focus-ring with a simple modality switch as there are things that just don't/can't automatically be mapped cleanly to existing concepts: custom elements and pretty much anything with a tabindex=-1 present interesting challenges that seem like they have to somehow be component specified at least, possibly left then further to individual authors. It's possible that using the above we could work custom attributes into the mix to signal which path to follow - the original implementation had something like that (so does my company's fork iirc for this reason), though @alice's breakdown seems better. I'm very pro us experimenting with this in the polyfill if we can as so far it does seem we're getting useful feedback that is much better to get now than once we're shipping a real thing.

bkardell avatar Oct 19 '17 15:10 bkardell

Just wanted to add my support for @alice's proposal for show-focusring which is a really nice idea.

iandevlin avatar Oct 23 '17 09:10 iandevlin

Just a quick update, see the last part of this comment for details. https://github.com/WICG/focus-visible/issues/88#issuecomment-398518020

robdodson avatar Jun 19 '18 19:06 robdodson

Per Alice's earlier comment about styling the focus ring to match the platform default. It seems like you can kind of do this today, using outline: auto, but it doesn't get the color right.

:focus-visible {
  outline: auto;
}

image

To recreate the specific color used in Chrome requires using -webkit-focus-ring-color.

:focus-visible {
  outline: auto -webkit-focus-ring-color;
}

image

I wonder if it would be possible to encourage other browsers that implement :focus-visible to also expose a CSS variable that contains all of the appropriate styles. Then you could do:

:focus-visible {
  outline: var(--default-focus-ring)
}

robdodson avatar Jun 19 '18 23:06 robdodson

I wonder if it would be possible to encourage other browsers that implement :focus-visible to also expose a CSS variable that contains all of the appropriate styles.

Even if we are gonna do this it should be a new keyword instead of a custom property IMO.

Justineo avatar Jun 20 '18 00:06 Justineo

I noticed Chrome's stylesheet uses a single dash -webkit-focus-ring-color and not the double dash syntax for custom properties, --webkit-focus-ring-color. I'm curious if browsers have the notion of a variable that's public but not configurable.

robdodson avatar Jun 20 '18 00:06 robdodson

They are the same syntax actually. -vendor- has always been the model. Custom properties created be the author just have no vendor.

bkardell avatar Jun 20 '18 00:06 bkardell

Custom preoperties(aka “CSS variables”), as the name says, are properties which require var() to call the values. -webkit-focus-ring-color is just a value keyword with a vendor prefix, not a “variable”. I think using revert should be the most proper way to restore the UA style but before it’s implemented in Chrome something like -webkit-focus-ring-color is also acceptable.

Justineo avatar Jun 20 '18 01:06 Justineo

@alice Has there been any movement on this recently? Would love to gain some momentum across vendors for supporting your proposal.

kevinSuttle avatar Jul 09 '19 14:07 kevinSuttle

Some more discussion here: https://github.com/w3c/webcomponents/issues/762

alice avatar Jan 28 '20 01:01 alice