Components
Tooltip
A tooltip is a short, plain-text hint that appears on hover or keyboard focus. It's driven entirely by one attribute — data-tf-tooltip — with no separate markup for the tooltip element itself.
How It Works
TicFrame creates the tooltip element for you the first time it's needed, links it to the trigger with aria-describedby, and shows/hides it on hover and keyboard focus together — not just mouse events.
Trigger events
mouseenter/focus show it; mouseleave/blur/Escape hide it. Keyboard users get the same information as mouse users, not a degraded experience.
Placement
data-tf-tooltip-placement accepts top (default), bottom, left, right, or the logical start/end, which resolve to the correct physical side under RTL automatically.
Plain text only
The tooltip's content is set with textContent, not innerHTML — a deliberate limit. Rich, interactive content belongs in a Popover instead.
No automatic collision flipping
The placement you request is the placement you get — TicFrame doesn't flip a tooltip to the opposite side if it would overflow the viewport. Choose a placement that fits where the trigger actually sits on the page.
Live Examples
All four placements
Hover or Tab to each button.
<button type="button" class="tf-btn" data-tf-tooltip="Appears above (default)">Top</button>
<button type="button" class="tf-btn" data-tf-tooltip="Appears below" data-tf-tooltip-placement="bottom">Bottom</button>
<button type="button" class="tf-btn" data-tf-tooltip="Appears to the left" data-tf-tooltip-placement="left">Left</button>
<button type="button" class="tf-btn" data-tf-tooltip="Appears to the right" data-tf-tooltip-placement="right">Right</button>Logical start/end (RTL-aware)
Switch the site to RTL (More → Customize) and hover these again — they swap sides automatically, unlike left/right above.
<button type="button" class="tf-btn" data-tf-tooltip="Start edge" data-tf-tooltip-placement="start">Start</button>
<button type="button" class="tf-btn" data-tf-tooltip="End edge" data-tf-tooltip-placement="end">End</button>Icon-only trigger
An icon-only trigger needs its own aria-label — the tooltip's aria-describedby supplements the name, it doesn't replace it.
<button type="button" class="tf-btn tf-btn-icon tf-btn-ghost" aria-label="Help"
data-tf-tooltip="Read the documentation for this field" data-tf-tooltip-placement="right">
<i class="ti ti-013658" aria-hidden="true"></i>
</button>Disabled trigger
A disabled control never fires hover/focus events, so its tooltip never appears — this is native platform behavior, not a TicFrame limitation. Use a wrapping element with the tooltip instead if you need to explain why something is disabled.
<span data-tf-tooltip="Upgrade to Pro to enable exports">
<button type="button" class="tf-btn" disabled>Export (disabled)</button>
</span>Accessibility
| Requirement | TicFrame guidance |
|---|---|
| Role | The tooltip element gets role="tooltip" automatically. |
| Association | aria-describedby on the trigger points at the tooltip — set automatically, don't set it yourself. |
| Keyboard parity | Tooltips show on focus, not only hover, so keyboard-only users see the same hints. |
| Dismissal | Escape hides an open tooltip without moving focus away from the trigger. |
| Icon-only triggers | Still need their own aria-label — a tooltip is a supplementary description, not an accessible name. |
| Disabled elements | Wrap a disabled control in an element that carries data-tf-tooltip instead, since a disabled element doesn't fire the hover/focus events that show it. |
API Reference
Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
data-tf-tooltip | string | — | Required. The tooltip's text content. |
data-tf-tooltip-placement | "top" | "bottom" | "left" | "right" | "start" | "end" | "top" | Which side the tooltip appears on. start/end are RTL-aware. |
Events
| Event | When it fires | Target |
|---|---|---|
tf:tooltip:show | After the tooltip appears. | Trigger |
tf:tooltip:hide | After the tooltip is hidden. | Trigger |
CSS Variables
| Token | Purpose |
|---|---|
--tf-float-x, --tf-float-y | Set by TicFrame's positioning JS every time the tooltip shows — the anchor point the placement class's translate percentage is measured from. Documented, but not meant to be set by hand. |
--tf-z-tooltip | Stacking order, falls back to --tf-z-dropdown if unset. |
Troubleshooting
| Symptom | Fix |
|---|---|
| Tooltip never appears | Confirm the trigger isn't disabled — disabled elements don't fire the hover/focus events TicFrame listens for. Wrap it in a non-disabled element instead. |
| Tooltip is clipped or runs off-screen | Pick a placement with more room, or shorten the text — there's no automatic collision flip. max-inline-size: 24rem caps width but doesn't reposition. |
| Start/end doesn't seem to change anything | You're most likely still viewing the page in LTR — the visible difference from left/right only appears once dir="rtl" is active. |
| Need rich content (links, buttons, formatting) | Use Popover instead — tooltips are intentionally plain-text only. |