🔥 Oxide UI v0.1.0 — Dark mode only, copy-paste ready. Get started →
Skip to content

Tooltip

<div role="tooltip">

A short label that appears on hover or keyboard focus. Best used on icon buttons, truncated text, and elements that need brief clarification. For rich content (forms, links, actions) use Popover instead.

Overview

Preview
Tooltip on top
Tooltip on bottom
Left tooltip
Right tooltip
Delete item

Top (default)

Preview
html
<div class="relative inline-flex group">
  <button class="...">Hover me</button>

  <div
    class="pointer-events-none absolute bottom-full left-1/2 mb-2 -translate-x-1/2
           whitespace-nowrap rounded-md bg-zinc-800 border border-zinc-700
           px-2.5 py-1.5 text-xs text-zinc-200 shadow-xl
           opacity-0 translate-y-1 transition-all duration-150
           group-hover:opacity-100 group-hover:translate-y-0 z-20"
    role="tooltip"
  >
    Tooltip text
    <!-- Arrow -->
    <span class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-700"></span>
  </div>
</div>

Positions

All four positions follow the same pattern — change the anchor class and arrow:

html
<!-- Top -->
<div class="absolute bottom-full left-1/2 mb-2 -translate-x-1/2 ... translate-y-1 group-hover:translate-y-0">
  <span class="absolute top-full left-1/2 -translate-x-1/2 border-4 border-transparent border-t-zinc-700"></span>
</div>

<!-- Bottom -->
<div class="absolute top-full left-1/2 mt-2 -translate-x-1/2 ... -translate-y-1 group-hover:translate-y-0">
  <span class="absolute bottom-full left-1/2 -translate-x-1/2 border-4 border-transparent border-b-zinc-700"></span>
</div>

<!-- Left -->
<div class="absolute right-full top-1/2 mr-2 -translate-y-1/2 ... translate-x-1 group-hover:translate-x-0">
  <span class="absolute left-full top-1/2 -translate-y-1/2 border-4 border-transparent border-l-zinc-700"></span>
</div>

<!-- Right -->
<div class="absolute left-full top-1/2 ml-2 -translate-y-1/2 ... -translate-x-1 group-hover:translate-x-0">
  <span class="absolute right-full top-1/2 -translate-y-1/2 border-4 border-transparent border-r-zinc-700"></span>
</div>

On an icon button

Preview
html
<!-- aria-label + role="tooltip" gives full screen reader support -->
<div class="relative inline-flex group">
  <button aria-label="Delete item" aria-describedby="tooltip-delete" class="...">
    <svg ...><!-- icon --></svg>
  </button>
  <div id="tooltip-delete" role="tooltip" class="... opacity-0 group-hover:opacity-100">
    Delete item
  </div>
</div>

Vue composable (reusable)

vue
<!-- components/OxTooltip.vue -->
<script setup>
defineProps({
  text:    { type: String,  required: true },
  pos:     { type: String,  default: 'top' },  // top | bottom | left | right
})
</script>

<template>
  <div class="relative inline-flex group">
    <slot />
    <div
      class="pointer-events-none absolute z-20 whitespace-nowrap rounded-md border border-zinc-700
             bg-zinc-800 px-2.5 py-1.5 text-xs text-zinc-200 shadow-xl
             transition-all duration-150 opacity-0 group-hover:opacity-100"
      :class="{
        'bottom-full left-1/2 mb-2 -translate-x-1/2 translate-y-1 group-hover:translate-y-0': pos === 'top',
        'top-full left-1/2 mt-2 -translate-x-1/2 -translate-y-1 group-hover:translate-y-0': pos === 'bottom',
        'right-full top-1/2 mr-2 -translate-y-1/2 translate-x-1 group-hover:translate-x-0': pos === 'left',
        'left-full top-1/2 ml-2 -translate-y-1/2 -translate-x-1 group-hover:translate-x-0': pos === 'right',
      }"
      role="tooltip"
    >
      {{ text }}
    </div>
  </div>
</template>

<!-- Usage -->
<OxTooltip text="Save document" pos="top">
  <button class="..."><SaveIcon /></button>
</OxTooltip>

Accessibility notes

  • Add role="tooltip" to the tooltip element and aria-describedby on the trigger pointing to the tooltip's id
  • For icon-only buttons, also add aria-label so the button itself has an accessible name
  • Tooltips must appear on keyboard focus, not just hover — the group-focus-within:opacity-100 variant handles this: add it alongside group-hover:opacity-100
  • Tooltip text should be brief (under ~10 words). For anything richer use Popover
  • Never put interactive content (links, buttons) inside a tooltip — use a Popover instead

Released under the MIT License.