Tooltip
التلميحrole="tooltip" + aria-describedby
also calledhover hint، info bubble، help tip، title tip، hover label، تولتيب، تلميح الأدوات، فقاعة التلميح، تلميح عائم، شرح الأيقونة
A tooltip is a short piece of text that appears next to an element when the pointer rests on it or the keyboard focuses it. The text names the element or explains what it does. It is a description, not content: plain text with no button, link, or field, because role="tooltip" defines no navigation model inside itself, and the first interactive thing you put in it turns it into something else. Tell it apart from three look-alikes. A hover card is a rich, interactive layer with images and links, built for the pointer to enter and stay. A toggletip opens on click rather than hover, and its text is announced through an aria-live region because it answers a question the user asked. The native HTML title attribute is a tip the browser draws, with a delay you cannot set, a look you cannot style, and no keyboard or touch exposure at all. Two rules follow from that. A tooltip never holds interactive content, and it is never the only place a piece of information exists, because half your users are on a touch screen where "hover" does not exist.
If you called it…
Live specimen
Interact with the demo. Every part is real and numbered.
مرّر المؤشّر فوق أيقونة الرابط، أو اضغط Tab للوصول إليها.
Anatomy: every part, named
Hover a row to locate it in the demo above.
Build prompt
How it behaves right-to-left
This section is ours alone.
Side, alignment, and edge collision
mirrorsThe main side values in Floating UI and Radix (top, right, bottom, left) are physical and know nothing about page direction: a tooltip set to right stays on the right of its trigger even on an Arabic page, so derive the side yourself from a logical intent. The -start / -end alignment suffix is logical; computePosition reads direction off the computed styles and flips it, so bottom-start aligns to the right edge in RTL. The flip middleware handles flipping at the viewport edge, and direction has nothing to do with it. Any manual anchoring is written with inset-inline-start, never left.
The arrow offset
never mirrorsThe value returned in middlewareData.arrow.x is physical pixels measured from the left edge of the tooltip box, already computed with page direction taken into account, so apply it literally as left: Xpx. Write it as inset-inline-start and it flips a second time, so the arrow detaches from the trigger in RTL. The face the arrow sticks out of is likewise derived from the physical side in placement (the opposite of top is bottom, the opposite of left is right), so it stays physical too, and writing it logically unhooks it from the side the engine actually resolved. This is one of the rare places where the physical property is the correct one. The general rule, inset-inline-start over left, still governs everything else in the tooltip.
Direction of the tooltip text
never mirrorsText direction inside a tooltip follows the language of the text, not the language of the page: an Arabic tooltip explaining a function name like getUserById or a path like /var/log/app.log must isolate the Latin run with <bdi>, or dir="ltr" plus unicode-bidi: isolate, otherwise the leading slash jumps to the other end. The bigger trap is that tooltips are usually portalled to <body>, so they inherit dir from the document root rather than from the trigger. If your trigger sits inside a dir="ltr" code block, the box never finds out. Set dir explicitly on the tooltip content, or drive it from the DirectionProvider in Radix.
The enter-animation origin
mirrorsA scale-in has to grow out of the side the trigger is on, otherwise the tooltip looks like it sprouted from nowhere. The trap is that transform-origin accepts no logical keywords at all: inline-start is not a valid value, and the allowed keywords and percentages are physical, resolved from the top-left edge whatever the direction. Drive it from a variable: --tip-origin: right, then [dir="rtl"] & { --tip-origin: left }, and apply transform-origin: var(--tip-origin) center. Any translateX in the animation needs the same treatment.
The native title attribute
never mirrorsA title-based tip is painted by the browser outside the DOM tree: CSS never reaches it, and you cannot wrap part of it in <bdi>, because an attribute value is raw text that accepts no markup. So a mixed line like "افتح config.json من مجلّد build" is ordered by the bidi algorithm alone, and the Latin name, the dot, or the slash can land at the wrong end. The only lever left inside raw text is the control characters themselves: U+2066 and U+2069 to isolate, or U+200E. The better fix is to replace title with your own role="tooltip" element, where dir and <bdi> work and keyboard and touch users can see it.
In code
Each row is one framework's word for the same thing. Take the row your project speaks.
See also
Updated · 2026-08-19