Snippets /
CSS tooltip
A pure-CSS tooltip that reads its text from a data attribute and appears on hover or keyboard focus.
Quick implementation
[data-tooltip] {
position: relative;
}
[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 0.6rem);
left: 50%;
translate: -50% 0.5rem;
padding: 0.4rem 0.75rem;
border-radius: 0.35rem;
background: oklch(0.28 0.02 260);
color: oklch(0.9 0.01 260);
font-size: 0.8rem;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease, translate 0.2s ease;
}
[data-tooltip]:hover::after,
[data-tooltip]:focus-visible::after {
opacity: 1;
translate: -50% 0;
}
Prompt this to your LLM
Paste this into ChatGPT, Claude, or any code-generating model to scaffold the pattern instantly.
Create a pure CSS tooltip using the ::after pseudo-element
and attr(data-tooltip) for the content. Position the tooltip
above the element, centered horizontally with left: 50% and
translate: -50%. Animate in with opacity and a small upward
slide using the translate property. Show the tooltip on
:hover and :focus-visible. Use oklch() colors for
background and text. Add pointer-events: none to the
pseudo-element so it doesn't block interactions.
Why this matters
Tooltips are one of the most common UI patterns, yet many implementations depend on JavaScript positioning libraries. A pure-CSS approach means zero bundle size, instant rendering, and no layout shift. It works without JavaScript enabled and is trivial to maintain since the tooltip text lives in a data-tooltip attribute right on the element.
The logic
The ::after pseudo-element uses attr(data-tooltip) to pull its text content directly from the HTML attribute. It is positioned absolutely above the trigger element with bottom: calc(100% + 0.6rem) to create a gap. The initial state is opacity: 0 and a slight downward offset via translate. On :hover or :focus-visible, both values transition to their final state, creating a smooth fade-and-slide entrance. The pointer-events: none declaration ensures the tooltip does not intercept mouse events.
Accessibility & performance
CSS-only tooltips have a limitation: screen readers do not announce ::after content reliably across all browsers. For true accessibility, pair this with an aria-label or aria-describedby attribute on the trigger element. Also add role="tooltip" and an id to a real DOM element for screen-reader users if the tooltip conveys essential information. For decorative hints, the CSS-only approach is sufficient. The transition is lightweight and respects prefers-reduced-motion when wrapped in the appropriate media query.