Tooltip
A label that provides information on hover or focus.
Anatomy
To set up the tooltip correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-partattribute to help identify them in the DOM.
Examples
Learn how to use the Tooltip component in your project. Let's take a look at the most basic
example:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Basic = () => (
  <Tooltip.Root>
    <Tooltip.Trigger disabled>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Basic = () => (
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Portal>
      <Tooltip.Positioner>
        <Tooltip.Content>I am a tooltip!</Tooltip.Content>
      </Tooltip.Positioner>
    </Portal>
  </Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
</template>
Controlled Tooltip
To create a controlled Tooltip component, manage the state of whether the tooltip is open using the
open prop:
import { Tooltip } from '@ark-ui/react/tooltip'
import { useState } from 'react'
export const Controlled = () => {
  const [isOpen, setIsOpen] = useState(false)
  return (
    <>
      <button type="button" onClick={() => setIsOpen(!isOpen)}>
        Toggle
      </button>
      <Tooltip.Root open={isOpen}>
        <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
        <Tooltip.Positioner>
          <Tooltip.Content>I am a tooltip!</Tooltip.Content>
        </Tooltip.Positioner>
      </Tooltip.Root>
    </>
  )
}
import { Tooltip } from '@ark-ui/solid/tooltip'
import { createSignal } from 'solid-js'
import { Portal } from 'solid-js/web'
export const Controlled = () => {
  const [isOpen, setIsOpen] = createSignal(false)
  return (
    <>
      <button type="button" onClick={() => setIsOpen(!isOpen())}>
        Toggle
      </button>
      <Tooltip.Root open={isOpen()}>
        <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
        <Portal>
          <Tooltip.Positioner>
            <Tooltip.Content>I am a tooltip!</Tooltip.Content>
          </Tooltip.Positioner>
        </Portal>
      </Tooltip.Root>
    </>
  )
}
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
import { ref } from 'vue'
const isOpen = ref(false)
</script>
<template>
  <button @click="isOpen = !isOpen">Toggle</button>
  <Tooltip.Root :open="isOpen">
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
</template>
Using a Render Function
For more control over the Tooltip's functionality, you can use a function as a child, which provides access to the Tooltip API:
import { Tooltip } from '@ark-ui/react/tooltip'
export const RenderFn = () => (
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Context>
        {(tooltip) => (
          <Tooltip.Content>This tooltip is open: {tooltip.open.toString()}</Tooltip.Content>
        )}
      </Tooltip.Context>
    </Tooltip.Positioner>
  </Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const RenderFn = () => (
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Portal>
      <Tooltip.Positioner>
        <Tooltip.Context>
          {(context) => (
            <Tooltip.Content>This tooltip is open: {context().open.toString()}</Tooltip.Content>
          )}
        </Tooltip.Context>
      </Tooltip.Positioner>
    </Portal>
  </Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Context v-slot="tooltip">
        <Tooltip.Content>This tooltip is open: {{ tooltip.open.toString() }}</Tooltip.Content>
      </Tooltip.Context>
    </Tooltip.Positioner>
  </Tooltip.Root>
</template>
Adding an Arrow
To display an arrow pointing to the trigger from the tooltip, use the Tooltip.Arrow and
Tooltip.ArrowTip components:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Arrow = () => (
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>
        <Tooltip.Arrow>
          <Tooltip.ArrowTip />
        </Tooltip.Arrow>
        I am a tooltip!
      </Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Arrow = () => (
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Portal>
      <Tooltip.Positioner>
        <Tooltip.Arrow>
          <Tooltip.ArrowTip />
        </Tooltip.Arrow>
        <Tooltip.Content>I am a tooltip!</Tooltip.Content>
      </Tooltip.Positioner>
    </Portal>
  </Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
  <Tooltip.Root>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>
        <Tooltip.Arrow>
          <Tooltip.ArrowTip />
        </Tooltip.Arrow>
        I am a tooltip!
      </Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
</template>
Configuring Delay Timings
To configure the delay timings for the Tooltip, use the closeDelay and openDelay props:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Timings = () => (
  <Tooltip.Root closeDelay={0} openDelay={0}>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Timings = () => (
  <Tooltip.Root closeDelay={0} openDelay={0}>
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Portal>
      <Tooltip.Positioner>
        <Tooltip.Content>I am a tooltip!</Tooltip.Content>
      </Tooltip.Positioner>
    </Portal>
  </Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
  <Tooltip.Root :closeDelay="0" :openDelay="0">
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
</template>
Custom Positioning
To customize the position of the Tooltip relative to the trigger, use the positioning prop:
import { Tooltip } from '@ark-ui/react/tooltip'
export const Positioning = () => (
  <Tooltip.Root
    positioning={{
      placement: 'left-start',
      offset: { mainAxis: 12, crossAxis: 12 },
    }}
  >
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
)
import { Tooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const Positioning = () => (
  <Tooltip.Root
    positioning={{
      placement: 'left-start',
      offset: { mainAxis: 12, crossAxis: 12 },
    }}
  >
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Portal>
      <Tooltip.Positioner>
        <Tooltip.Content>I am a tooltip!</Tooltip.Content>
      </Tooltip.Positioner>
    </Portal>
  </Tooltip.Root>
)
<script setup lang="ts">
import { Tooltip } from '@ark-ui/vue/tooltip'
</script>
<template>
  <Tooltip.Root
    :positioning="{
      placement: 'left-start',
      gutter: 16,
      offset: { mainAxis: 12, crossAxis: 12 },
    }"
  >
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.Root>
</template>
Using the Root Provider
The RootProvider component provides a context for the tooltip. It accepts the value of the useTooltip hook.
You can leverage it to access the component state and methods from outside the tooltip.
import { Tooltip, useTooltip } from '@ark-ui/react/tooltip'
export const RootProvider = () => {
  const tooltip = useTooltip()
  return (
    <>
      <button onClick={() => tooltip.setOpen(true)}>Open</button>
      <Tooltip.RootProvider value={tooltip}>
        <Tooltip.Trigger disabled>Hover Me</Tooltip.Trigger>
        <Tooltip.Positioner>
          <Tooltip.Content>I am a tooltip!</Tooltip.Content>
        </Tooltip.Positioner>
      </Tooltip.RootProvider>
    </>
  )
}
import { Tooltip, useTooltip } from '@ark-ui/solid/tooltip'
import { Portal } from 'solid-js/web'
export const RootProvider = () => {
  const tooltip = useTooltip()
  return (
    <>
      <button onClick={() => tooltip().setOpen(true)}>Open</button>
      <Tooltip.RootProvider value={tooltip}>
        <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
        <Portal>
          <Tooltip.Positioner>
            <Tooltip.Content>I am a tooltip!</Tooltip.Content>
          </Tooltip.Positioner>
        </Portal>
      </Tooltip.RootProvider>
    </>
  )
}
<script setup lang="ts">
import { Tooltip, useTooltip } from '@ark-ui/vue/tooltip'
const tooltip = useTooltip()
</script>
<template>
  <button @click="tooltip.setOpen(true)">Open</button>
  <Tooltip.RootProvider :value="tooltip">
    <Tooltip.Trigger>Hover Me</Tooltip.Trigger>
    <Tooltip.Positioner>
      <Tooltip.Content>I am a tooltip!</Tooltip.Content>
    </Tooltip.Positioner>
  </Tooltip.RootProvider>
</template>
If you're using the
RootProvidercomponent, you don't need to use theRootcomponent.
API Reference
Root
| Prop | Default | Type | 
|---|---|---|
| aria-label | stringCustom label for the tooltip. | |
| closeDelay | 500 | numberThe close delay of the tooltip. | 
| closeOnClick | true | booleanWhether the tooltip should close on click | 
| closeOnEscape | true | booleanWhether to close the tooltip when the Escape key is pressed. | 
| closeOnPointerDown | true | booleanWhether to close the tooltip on pointerdown. | 
| closeOnScroll | true | booleanWhether the tooltip should close on scroll | 
| defaultOpen | booleanThe initial open state of the tooltip when it is first rendered. Use when you do not need to control its open state. | |
| disabled | booleanWhether the tooltip is disabled | |
| id | stringThe `id` of the tooltip. | |
| ids | Partial<{
  trigger: string
  content: string
  arrow: string
  positioner: string
}>The ids of the elements in the tooltip. Useful for composition. | |
| immediate | booleanWhether to synchronize the present change immediately or defer it to the next frame | |
| interactive | false | booleanWhether the tooltip's content is interactive. In this mode, the tooltip will remain open when user hovers over the content. | 
| lazyMount | false | booleanWhether to enable lazy mounting | 
| onExitComplete | () => voidFunction called when the animation ends in the closed state | |
| onOpenChange | (details: OpenChangeDetails) => voidFunction called when the tooltip is opened. | |
| open | booleanWhether the tooltip is open | |
| openDelay | 1000 | numberThe open delay of the tooltip. | 
| positioning | PositioningOptionsThe user provided options used to position the popover content | |
| present | booleanWhether the node is present (controlled by the user) | |
| unmountOnExit | false | booleanWhether to unmount on exit. | 
Arrow
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
ArrowTip
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
Content
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | tooltip | 
| [data-part] | content | 
| [data-state] | "open" | "closed" | 
| [data-placement] | The placement of the content | 
Positioner
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
RootProvider
| Prop | Default | Type | 
|---|---|---|
| value | UseTooltipReturn | |
| immediate | booleanWhether to synchronize the present change immediately or defer it to the next frame | |
| lazyMount | false | booleanWhether to enable lazy mounting | 
| onExitComplete | () => voidFunction called when the animation ends in the closed state | |
| present | booleanWhether the node is present (controlled by the user) | |
| unmountOnExit | false | booleanWhether to unmount on exit. | 
Trigger
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | tooltip | 
| [data-part] | trigger | 
| [data-expanded] | Present when expanded | 
| [data-state] | "open" | "closed" | 
Accessibility
Complies with the Tooltip WAI-ARIA design pattern.
Keyboard Support
| Key | Description | 
|---|---|
| Tab | Opens/closes the tooltip without delay. | 
| Escape | If open, closes the tooltip without delay. |