From bd135966ca1b27e55ee957fa2890342506bdde7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javi=20Mart=C3=ADn?= Date: Fri, 27 Aug 2021 15:25:29 +0200 Subject: [PATCH] Use :focus-visible to define styles on focus Styles on keyboard focus are essential for keyboard navigation; without them, keyboard users wouldn't see which element they're currently interacting with. That's why we use an `outline` on elements having the current keyboard focus. However, this is sometimes annoying for mouse/touchscreen users, since clicking/touching an element also gives it keyboard focus. When clicking on a button performing some kind of action through JavaScript, keeping the outline on the button after clicking it is distracting. Even after clicking a link, for some users having the outline present while they wait for the next page to load is annoying. That's why modern browsers (at the time of writing, 74%) implement the `:focus-visible` pseudoclass, which selects elements which have received focus using the keyboard, but not elements which have been clicked/tapped on. We can use it to provide focus styles for keyboard users without getting in the way of mouse/touchscreen users. Usually we wouldn't use a feature which isn't supported in more than 96% of the browsers out there. However, in this case we've got a solid fallback: we just use the `:focus` pseudoclass. Since the `@support` CSS condition doesn't accept pseudoclasses as parameters, we're disabling `:focus` styles only on browsers supporting the `:focus-visible` pseudoclass using the `:focus:not(:focus-visible)` selector, which will be ignored by browsers without support for `:focus-visible`. Since now users receive less feedback when clicking/touching a link or a button, we're adding styles for the `:active` pseudoclass. This way users will know which item they're clicking/tapping on. I'm not sure the outline is a good option for this case, though; I think for touchscreen users a better solution would be to apply the styles we apply on hover. We might change it in the future. Note grouping styles together like this would *not* work: ``` &:focus, &:focus-visible { // Styles here } ``` Browsers not supporting the `:focus-visible` pseudoclass would ignore this statement completely, meaning they wouldn't apply the styles on `:focus` either. --- app/assets/stylesheets/layout.scss | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 7f8727814..67f55e2d1 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -116,6 +116,19 @@ button, &:focus { outline: $outline-focus; } + + &:focus-visible { + outline: $outline-focus; + } + + &:focus:not(:focus-visible) { + outline: none; + } + + &:active, + &:focus:active { + outline: $outline-focus; + } } .button {