Skip to content
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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding focus-visible styles with polyfill #3695

Merged
merged 4 commits into from Feb 3, 2021
Merged

Adding focus-visible styles with polyfill #3695

merged 4 commits into from Feb 3, 2021

Conversation

dfmcphee
Copy link
Contributor

@dfmcphee dfmcphee commented Dec 9, 2020

WHY are these changes introduced?

Currently we use a hack for not showing focus rings on things like buttons by blurring on mouseup. This works, but it takes adding this behaviour specifically to every component that needs it.

This adds the focus-visible polyfill so that we can start taking a CSS approach to this that will eventually be supported by browsers and we can remove the polyfill at that point.

Right now this would be about a 1kb bundle increase, but I think we could get it to about the same once we start removing the custom click/blur code.

Here is an example of clicking or tabbing to a tooltip activator before this change:

Screen Shot 2020-12-09 at 1 15 56 PM

And after this change clicking would show this:
Screen Shot 2020-12-09 at 1 16 21 PM

And tabbing to would show this:
Screen Shot 2020-12-09 at 1 16 13 PM

WHAT is this pull request doing?

This adds the polyfill package as well as some default focus-visible styles for all elements.

How to 馃帺

馃枼 Local development instructions
馃棐 General tophatting guidelines
馃搫 Changelog guidelines

Copy-paste this code in playground/Playground.tsx:
import React from 'react';
import {Page} from '../src';

export function Playground() {
  return (
    <Page title="Playground">
      {/* Add the code you want to test in here */}
    </Page>
  );
}

馃帺 checklist

  • Tested on mobile
  • Tested on multiple browsers
  • Tested for accessibility
  • Updated the component's README.md with documentation changes
  • Tophatted documentation changes in the style guide
  • For visual design changes, pinged one of @鈥奌YPD, @鈥妋irualves, @鈥妔arahill, or @鈥妑y5n to update the Polaris UI kit

@github-actions
Copy link
Contributor

github-actions bot commented Dec 9, 2020

馃煛 This pull request modifies 8 files and might impact 5 other files. This is an average splash zone for a change, remember to tophat areas that could be affected.

Details:
All files potentially affected (total: 5)
馃搫 UNRELEASED.md (total: 0)

Files potentially affected (total: 0)

馃搫 package.json (total: 0)

Files potentially affected (total: 0)

馃З src/components/AppProvider/AppProvider.tsx (total: 0)

Files potentially affected (total: 0)

馃З src/components/Popover/components/PopoverOverlay/tests/PopoverOverlay.test.tsx (total: 0)

Files potentially affected (total: 0)

馃搫 src/components/Tooltip/README.md (total: 0)

Files potentially affected (total: 0)

馃З src/components/Tooltip/Tooltip.tsx (total: 3)

Files potentially affected (total: 3)

馃帹 src/components/Tooltip/components/TooltipOverlay/TooltipOverlay.scss (total: 5)

Files potentially affected (total: 5)

馃搫 yarn.lock (total: 0)

Files potentially affected (total: 0)

@dfmcphee dfmcphee changed the title Adding focus-visible polyfill Adding focus-visible styles with polyfill Dec 9, 2020
@dfmcphee dfmcphee marked this pull request as ready for review December 9, 2020 18:19
<Link>Order #1001</Link>
<TextStyle variation="strong">Order #1001</TextStyle>
Copy link
Member

Choose a reason for hiding this comment

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

Should we revert this example change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it is actually useful to have one example that isn't a link here. The link never showed this being an issue because it had its own focus styles.

Copy link
Member

@alex-page alex-page left a comment

Choose a reason for hiding this comment

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

Looks great, the NPM package is nice and clean as well.

@dleroux
Copy link
Contributor

dleroux commented Dec 9, 2020

Globally, I think we should just remove the focus styles altogether. Since our styles are not being applied to the element directly, but to the ::after selector using the focusing ring, this could cause en element to have 2 focus styles:

Screen Shot 2020-12-09 at 2 22 46 PM

@dfmcphee
Copy link
Contributor Author

dfmcphee commented Dec 9, 2020

Globally, I think we should just remove the focus styles altogether. Since our styles are not being applied to the element directly, but to the ::after selector using the focusing ring, this could cause en element to have 2 focus styles:

The problem with this is that for components not getting a specific focus style, just a tabindex like a tooltip activator, they would never have a focus style reapplied.

I think the real problem here is we have two different ways of applying our focus styles. This one adds a box-shadow directly to the focused element, whereas or focus-ring mixin applied it to an ::after. The reason I didn't use the same approach for the global style is that it assumes too much by applying position: relative to everything. I wish our focus-ring was a little more flexible to work on elements.

@dleroux
Copy link
Contributor

dleroux commented Dec 9, 2020

it assumes too much by applying position: relative

I think that is the reality of the focus ring. We need to make a conscious decision when applying styles to all focusable elements. I don't recall us adding it directly to an element. Do we do that anywhere?

@dfmcphee
Copy link
Contributor Author

dfmcphee commented Dec 9, 2020

I think that is the reality of the focus ring. We need to make a conscious decision when applying styles to all focusable elements. I don't recall us adding it directly to an element. Do we do that anywhere?

Not currently but that is part of the issue. We end up with inconsistent browser default focus styles on some elements because we don't do this (like the tooltip example above). In my opinion it would be better to have a better base focus style that we can apply globally that respects focus-visible. We could then tweak those focus styles where we need to in specific components, but we also wouldn't leave anything out then.

The alternative is not apply anything globally but fix this up in each individual case but it is going to be difficult to do that in all cases.

@dfmcphee
Copy link
Contributor Author

dfmcphee commented Dec 9, 2020

I pushed up one more commit showing what this would look like without any global styles and only fixing the tooltip activator focus for now.

@alex-page
Copy link
Member

I think it's worth fixing globally and then going through the components and addressing any technical debt. It will remove a lot of code and hopefully make it a better experience when developing new components or patterns as they will have focus styles by default.

@beefchimi
Copy link
Contributor

beefchimi commented Dec 9, 2020

I implemented a CSS-only solution to using :focus-visible in online-store-ui, which looks something like this:

@mixin interaction-focus-ring-suppress {
  &::after {
    box-shadow: 0 0 0 0 transparent;

    @media (-ms-high-contrast: active) {
      outline: none;
    }
  }
}

@mixin interaction-focus-ring($width: rem(0)) {
  @include focus-ring($border-width: $width);

  &:focus {
    @include focus-ring($style: 'focused');
  }

  &:focus:not(:focus-visible) {
    @include interaction-focus-ring-suppress;
  }

  &:focus-visible {
    @include focus-ring($style: 'focused');
  }
}

So far this seems to have worked nicely. Curious what more the polyfill is affording you?

@dleroux
Copy link
Contributor

dleroux commented Dec 9, 2020

That shouldn't work anywhere but chrome right now: https://caniuse.com/mdn-css_selectors_focus-visible

@dfmcphee
Copy link
Contributor Author

dfmcphee commented Dec 9, 2020

Yep, exactly. That code would only work in browsers that support focus-visible whereas the polyfill would let you also use [data-focus-visible-added] as a selector to make that code work in all browsers.

@beefchimi
Copy link
Contributor

beefchimi commented Dec 9, 2020

@dleroux seems to work as intended in the browsers I've tested. You can play around in our Chroma instance if you like - but you'd kind of need to know what components this code is applied to.

Edit: I think the part that might not be obvious is the use of :not(:focus-visible). I picked up this technique from here:
https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/

@dfmcphee
Copy link
Contributor Author

dfmcphee commented Dec 9, 2020

Edit: I think the part that might not be obvious is the use of :not(:focus-visible). I picked up this technique from here:
https://developer.paciellogroup.com/blog/2018/03/focus-visible-and-backwards-compatibility/

I was actually following that implementation as well when looking at this. This is only backwards compatible in the sense that you will still get focus styles in all browsers, not that they will only be applied with keyboard focus.

For example, take a look a this codepen in Chrome, Safari, and Firefox.

In Chrome where focus-visible is supported, clicking the example heading will not show the custom focus ring, but tabbing to it will. In Safari and Firefox the focus ring shows up both when clicking and tabbing.

@alex-page alex-page force-pushed the master branch 2 times, most recently from 4eab9e5 to 9e09ba7 Compare January 15, 2021 05:17
Base automatically changed from master to main January 21, 2021 15:38
@kyledurand kyledurand merged commit 79c5b78 into main Feb 3, 2021
@kyledurand kyledurand deleted the focus-visible branch February 3, 2021 18:30
sylvhama pushed a commit that referenced this pull request Mar 26, 2021
* Adding focus-visible polyfill

* Adding to UNRELEASED changelog

* Removing global styles and fixing tooltip activator

* Fixing test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants