Skip to content

Instantly share code, notes, and snippets.

@jack-sf
Created July 8, 2019 08:42
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save jack-sf/853e72ec53ba597c89b5215dedfc813c to your computer and use it in GitHub Desktop.
Add `.has-keyboard-focus` class to your `<body>` element whenever keyboard focus is active - as an easy solution to add focus outline to all keyboard-focused elements (until `:focus-visible` is supported in all the major browsers)
import * as React from 'react';
import { document, window } from '../../../utils/browser';
// https://hackernoon.com/removing-that-ugly-focus-ring-and-keeping-it-too-6c8727fefcd2
export class KeyboardFocusHandler extends React.PureComponent {
componentDidMount(): void {
window!.addEventListener('keydown', this.handleFirstTab);
}
componentWillUnmount(): void {
document!.body.classList.remove('has-keyboard-focus');
window!.removeEventListener('keydown', this.handleFirstTab);
window!.removeEventListener('mousedown', this.handleMouseDownOnce);
}
handleFirstTab = (e: KeyboardEvent): void => {
// TAB key
if (e.keyCode === 9) {
document!.body.classList.add('has-keyboard-focus');
window!.removeEventListener('keydown', this.handleFirstTab);
window!.addEventListener('mousedown', this.handleMouseDownOnce);
}
};
handleMouseDownOnce = (): void => {
document!.body.classList.remove('has-keyboard-focus');
window!.removeEventListener('mousedown', this.handleMouseDownOnce);
window!.addEventListener('keydown', this.handleFirstTab);
};
render() {
return null;
}
}
@jack-sf
Copy link
Author

jack-sf commented Jul 8, 2019

Then, in CSS:

/* no outline for non-keyboard-inputs elements */
*:focus {
  outline: none;
}
body.has-keyboard-focus *:focus {
  outline: 2px solid #7aacfe; /* for non-webkit browsers */
  outline: 5px auto -webkit-focus-ring-color;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment