I had a very embarrassing CSS moment the other day.
I was working on the front-end code of a design that had a narrow sidebar of icons. There isn’t enough room there to show text of what the icons are, so the idea is that we’ll use accessible (but visually hidden, by default) text that is in there already as a tooltip on a “long hover.” That is, a device with a cursor, and the cursor hovering over the element for a while, like three seconds.
So, my mind went like this…
- I can use state: the tooltip is either visible or not visible. I’ll manage the state, which will manifest in the DOM as a class name on an HTML element.
- Then I’ll deal with the logic for changing that state.
- The default state will be not visible, but if the mouse is inside the element for over three seconds, I’ll switch the state to visible.
- If the mouse ever leaves the element, the state will remain (or become) not visible.
This was a React project, so state was just on the mind. That ended up like this:
mouseleave a little finicky, CSS could have done the entire thing, and with less code.
I’ll leave the UI in React, but rip out all the state management stuff. All I’ll do is add a
transition-delay: 3s when the
:hover so that it’s zero seconds when not hovered, then goes away immediately when the mouse cursor leaves).
A long hover is basically a one-liner in CSS:
.thing transition: 0.2s; .thing:hover transition-delay: 3s; /* delay hover animation only ON, not OFF */
One problem that isn’t addressed here is the touch screen problem. You could argue screen readers are OK with the accessible text and desktop browsers are OK because of the custom tooltips, but users with touch-only screens might be unable to discover the icon labels. In my case, I was building for a large screen scenario that assumes cursors, but I don’t think all-is-lost for touch screens. If the element is a link, the