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.