May 25th, 2025
It’s possible (easy, even) to build tooltips using nothing but HTML and Tailwind CSS. No Javascript required.
Here’s an example tooltip:
The tooltip in action. It’s built with vanilla HTML & Tailwind CSS (no Javascript).
In classic fashion, the tooltip is a little piece of text that appears when you hover over another element. Specifically, in this case, when you hover over a prior sibling element (note the peer
class).
Here’s a live example you can try (explanation below). Hover over the text to reveal the tooltip:
>>> Hover over me <<<
I'm a tooltip, built with plain HTML & Tailwind CSSOn mobile, tapping the text will show the tooltip. Tapping away will dismiss it.
Here’s the code. It’s just vanilla HTML & Tailwind CSS:
<div class="relative w-fit">
<p class="peer ...">target element</p>
<span
class="bottom-full left-1/2 -translate-x-1/2 absolute
text-stone-50 text-xs bg-stone-800 opacity-0 px-2 py-1 rounded-md w-max
-translate-y-0.5 peer-hover:-translate-y-1 peer-hover:opacity-100 transition-all"
>
tooltip content
</span>
</div>
There are three key things happening here: the relative
class on the wrapping div, the peer
class on the target element, and the absolute
positioning of the tooltip.
relative
on the wrapping div:
absolute
-ly within the scope of the relative
wrapper.peer
on the target element:
peer
on the target lets us trigger the peer-hover
classes on the tooltip. It handles showing/hiding of the tooltip, plus the little pop-in animation.absolute
positioning of the tooltip:
relative
class on the wrapping div, it makes these classes place the tooltip top-middle of the target: bottom-full left-1/2 -translate-x-1/2
Adjust the position of the tooltip with the Tailwind CSS layout properties.
The classes below will position the tooltip top-middle of an element (like above), or bottom-middle.
top: "bottom-full -translate-y-0.5 peer-hover:-translate-y-1.5";
bottom: "top-full -translate-y-1.5 peer-hover:-translate-y-0.5";
It would be wise to turn this tooltip into a component.
Mainly to hide away all the weird absolute positioning styles. Plus, it gives you an easy way to specify the position of the tooltip.
Here’s an example, using ViewComponents in Ruby on Rails:
# ui/tooltip.rb
# Need to nest within a 'relative' div and make the target element a prior 'peer'
class UI::Tooltip < ViewComponent::Base
def initialize(text:, position: :top)
@text = text
@position = position
end
def call
tag.span(**merged_options) do
@text
end
end
private
def merged_options
default_classes = "pointer-events-none absolute left-1/2 mt-2 w-max -translate-x-1/2 rounded-md bg-stone-800 px-2 py-1 text-xs text-stone-50 opacity-0 transition-all peer-hover:opacity-100"
position_classes = { top: "bottom-full -translate-y-0.5 peer-hover:-translate-y-1.5",
bottom: "top-full -translate-y-1.5 peer-hover:-translate-y-0.5" }}
{ class: [default_classes, position_classes[@position]] }.merge(@options)
end
end
Chrome Developers Reference: The CSS anchor positioning API
MDN Reference: anchor()
The CSS anchor positioning API is a fresh browser API that makes it easier to position our tooltips.
Specifically, we can directly anchor our target & tooltip elements together with an anchor
, and position them relatively with position-area
. This means that soon, you won’t need to wrap your elements with div class='relative'>
.
Here’s an example:
>>> Hover over me (Chrome / Edge) <<<
I'm a tooltip (anchor: '--anc')Currently, only Chrome & Edge support anchor positioning. If you’re on Safari, Firefox etc. this won’t work. I’ve tested on Safari and it seems like you just won’t see… anything.
Here’s the code to link your target & tooltip elements via anchors
:
<p
style="anchor-name: --anc;"
class="peer w-fit cursor-help font-medium underline decoration-dotted underline-offset-2"
>
target element (anchor: '--anc')
</p>
<span
style="position-anchor: --anc; position-area: top;"
class="fixed rounded-md bg-stone-800 px-2 py-1 text-xs text-stone-50 opacity-0 transition-all peer-hover:-translate-y-1 peer-hover:opacity-100"
>
tooltip content (anchored to '--anc')
</span>
Notice how we set anchor-name
on the target element, then link our tooltip to it with anchor-position
.
Use this handy position area anchor tool to find the correct value for position-area, depending on where you want to place your tooltip.
Some common values:
top: "position-area: top";
bottom: "position-area: bottom";
left: "position-area: left";
right: "position-area: right";
Tooltips without Javascript have been a holy grail for me for a while, so I’m glad I’ve finally cracked them.
I’ve been sprinkling them through the AttendList UI and I think they work nicely.
These tooltips are a powerful example of what you can accomplish with native HTML elements, and the new CSS anchor positioning API will — eventually — make them even more versatile.