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. |