I want to apply styling to my element when I’m focus it using my keyboard or when focused programatically using HTMLElement.focus().
E.g in the example below. I want the <div> to have blue borders initially or when I focus with tab. I only want it to have red border when I click the <div> using my mouse.
Is this possible?
EDIT1: Changed from triggering focus with a button to just on render as this scenario wasn’t accurate to my actual issue.
EDIT2: Changed from vanilla JS to React as I though that might be the issue. Seems like it still works like I want to to here, but not in my App :(. I have no clue why.
const useFocusOnMount = (ref) => {
React.useEffect(() => {
if (ref.current) {
ref.current.focus();
}
}, [ref]);
};
const App = (props) => {
const divRef = React.useRef(null)
useFocusOnMount(divRef);
return (
<div ref={divRef} role="listbox" tabindex="0" className="focusable">
<div data-testid="displayValue">Lol</div>
</div>
);
};
ReactDOM.render(<App />, document.getElementById("root"));.focusable {
border: 1px solid lightgrey;
outline: none;
}
.focusable:focus {
border: 2px solid red;
}
.focusable:focus-visible {
border: 2px solid blue;
}<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script> <div id="root"></div>
Advertisement
Answer
Not sure why you want this, and I would advise you to find an other way to do what you want (e.g, why not use only :focus?).
But for the hack, you can trick the browser in thinking your div is editable, it should* make it trigger its focus-visible rule.
const focusable = document.getElementById('focusable');
const button = document.getElementById('button');
const onClickHandler = (e) => {
focusable.contentEditable = true;
focusable.focus();
focusable.contentEditable = false;
};
button.addEventListener("click", onClickHandler);.focusable {
border: 1px solid lightgrey;
outline: none;
}
.focusable:focus {
border: 2px solid red;
}
.focusable:focus-visible {
border: 2px solid blue;
}<div id="focusable" class="focusable" tabIndex=0>Lol</div> <button id="button">Focus Lol</button>
*I only tested in latest Chrome and Firefox.