Skip to content

Instantly share code, notes, and snippets.

@dominikwilkowski
Last active November 4, 2021 00:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dominikwilkowski/b2b4a766030891b0622e to your computer and use it in GitHub Desktop.
Save dominikwilkowski/b2b4a766030891b0622e to your computer and use it in GitHub Desktop.
Doc strangelove outline love

Handle focus styling for keyboard and mouse users

See below code for React, Vanilla JavaScript and jQuery.

Read more in my article

/*
* Use like this:
*
* import { useFocus } from './useFocus';
*
* const App = ({ ...props }) => {
* useFocus();
*
* return (
* <Fragment>your app</Fragment>
* )
* }
*/
export const useFocus = () => {
// Let's make sure we only add the script once
const hasScript = document.querySelectorAll('script[id="FocusScript"]').length > 0;
if (!hasScript) {
// Insert a script that:
// - adds the "isMouseMode" class to the body
// - listens for the tab key
// - when tab key is pressed removes the "isMouseMode" class and removes the listener
const scriptEl = document.createElement('script');
scriptEl.setAttribute('id', 'FocusScript');
scriptEl.text = `
function FocusKeyHandler( event ) {
if( event.key === 'Tab' ) {
document.getElementsByTagName('body')[ 0 ].classList.remove('isMouseMode');
document.removeEventListener('keydown', FocusKeyHandler);
}
};
document.getElementsByTagName('body')[ 0 ].classList.add('isMouseMode');
window.document.addEventListener('keydown', FocusKeyHandler);
`;
document.body.insertBefore(scriptEl, document.body.firstChild);
// Insert CSS style to hide all focus only when the "isMouseMode" is present
const styleEl = document.createElement('style');
styleEl.setAttribute('type', 'text/css');
styleEl.innerHTML = `
html body.isMouseMode *:focus {
outline: 0 !important;
}
`;
document.head.appendChild(styleEl);
}
};
/*
* Use like this:
*
* Include the script as the first child of the body
*/
if ( !document.querySelectorAll('script[id="FocusScript"]').length > 0 ) {
var scriptEl = document.createElement('script');
scriptEl.setAttribute('id', 'FocusScript');
scriptEl.text = '' +
'function FocusKeyHandler( event ) {' +
' if( event.key === "Tab" ) {' +
' document.getElementsByTagName("body")[ 0 ].classList.remove("isMouseMode");' +
' document.removeEventListener("keydown", FocusKeyHandler);' +
' }' +
'};' +
'document.getElementsByTagName("body")[ 0 ].classList.add("isMouseMode");' +
'window.document.addEventListener("keydown", FocusKeyHandler);';
document.body.insertBefore(scriptEl, document.body.firstChild);
var styleEl = document.createElement('style');
styleEl.setAttribute('type', 'text/css');
styleEl.innerHTML = '' +
'html body.isMouseMode *:focus {' +
' outline: 0 !important;' +
'}';
document.head.appendChild(styleEl);
}
/*
* Use like this:
*
* Include the script at the bottom of body (or anywhere else really)
*/
$(function() {
$('head').append('<style type="text/css">html body.isMouseMode *:focus { outline: 0 !important; }</style>');
$('body').addClass('isMouseMode');
$('body').one('keydown', function( event ) {
var keyCode = event.keyCode || event.which;
if (keyCode == 9) {
$('body').removeClass('isMouseMode');
}
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment