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>
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.