Skip to content
This repository was archived by the owner on Jul 7, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
235 changes: 219 additions & 16 deletions content/components/tooltip.mdx
Original file line number Diff line number Diff line change
@@ -1,47 +1,250 @@
---
title: Tooltip
description: Tooltips add additional context to other UI elements and appear on mouse hover or keyboard focus.
description: Tooltips add additional context to interactive UI elements and appear on mouse hover or keyboard focus.
reactId: tooltip
railsIds:
- Primer::Alpha::Tooltip
- Primer::Tooltip
- Primer::Alpha::Tooltip
- Primer::Tooltip
cssId: tooltip
figmaId: tooltip
---

import ComponentLayout from '~/src/layouts/component-layout'
import {Text, Note} from '@primer/react'
import {Link, Text, Box} from '@primer/react'
import {Link as GatsbyLink} from 'gatsby'
export default ComponentLayout
import {AccessibilityLink} from '~/src/components/accessibility-link'

## Usage
<Note variant="danger">
<Text sx={{display: 'block', fontWeight: 'bold', mb: 2}}>⚠️ Usage Warning ⚠️</Text>
<Text>
Tooltips as a UI pattern should be the last resort for conveying information as they are hidden by default and often
with zero or little visual indicator of its existence. See{' '}
<Link href="#alternatives-to-tooltips">tooltip alternatives</Link> before using this component.
</Text>
</Note>

The tooltip component adds a tooltip to add context to interactive elements on the page.
## Usage

<img
width="960"
role="presentation"
src="https://github.com/primer/design/assets/586552/787873b7-d496-454c-b669-0c2400ef503f"
alt="three examples of tooltips on interactive elements"
src="https://github.com/primer/primitives/assets/18661030/172aa8f6-2273-4719-bb63-8dd678ffcbc9"
alt="Three examples of tooltips on interactive elements"
/>

## Accessibility
- Reserve tooltips to visually surface the label for icon buttons.
- Keep the tooltip text minimal.
- **Never** include tooltips on non-interactive components (`div`, `span`, `p`) because it will not be accessible for keyboard or screen reader users.

<Note variant="danger">
<Text sx={{display: 'block', fontWeight: 'bold', mb: 2}}>⚠️ Usage Warning ⚠️</Text>
<Text>Tooltips as a UI pattern should be our last resort for conveying information because it is hidden by default and often with zero or little visual indicator of its existence.</Text>
</Note>
### Best practices

<DoDontContainer>
<Do>
<img
width="456"
alt="Icon buttons with tooltips for edit, favorite, and sponsor"
src="https://github.com/primer/primitives/assets/18661030/e9f86af8-3792-4794-af68-ad0efccd8bc8"
/>
<Caption>Use a tooltip on an icon button to help convey the purpose of the action</Caption>
</Do>
<Dont>
<img
width="456"
alt="Non-interactive text element activating a long and wordy tooltip on hover"
src="https://github.com/primer/primitives/assets/18661030/1d8d86a2-8ee7-40d2-8934-c3d36f34d9b3"
/>
<Caption>Don't use tooltips on non-interactive elements</Caption>
</Dont>
</DoDontContainer>

## Options

### Label
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it be useful to talk about the underlying markup of the differences between a label and description (e.g. aria-labelledby vs aria-describedby)? One will serve as the accessible name of a control, while the other will supplement it.

We have some more documentation in Primer Rails tooltip (This was originally under an accessibility section in Primer Rails but I think it changed with the recent docs site update!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thank you! I had a hard time trying to explain this one so let me see if I can rework it a bit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is shipped in React. Would we want to hold off on this section to avoid confusing people 🤔

(cc: @broccolinisoup who worked on React tooltip :) )

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thank you! I had a hard time trying to explain this one so let me see if I can rework it a bit.

Katie let me know if you want to pair on this or any help with it!

I don't think this is shipped in React. Would we want to hold off on this section to avoid confusing people

Yes! We are going to ship the draft version soon hopefully 🙏🏻 and also the visual changes (i.e. removing the caret) also will be shipped with the draft version so holding off merging this PR until the draft is out would be wise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we mention how a label type tooltip should be reserved for icon buttons? The underlying semantic of a label tooltip is aria-labelledby would override any label the button already has.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this is clear already by saying "For interactive controls with no visible text label" but I will add "such as icon buttons" 😄


<Box
mb={3}
display="flex"
alignItems="flex-start"
flexDirection={['column', 'column', 'column', 'column', 'row']}
sx={{gap: 4}}
>
<img
width="456"
alt="icon button with tooltip as a label"
src="https://github.com/primer/design/assets/18661030/b06d4fc2-d4e6-482d-a9b9-05eb866ce3e1"
/>
<Box as="p" mt="0">
Icon buttons have a visually hidden label utilizing `aria-label`. To instead display that label in a tooltip, the
`label` option should be used. The `label` serves as the accessible name for the control utilitizing
`aria-labelledby` under the hood.
</Box>
</Box>

### Description

The `description` is intended to supplement the control's text label by utilitizing `aria-describedby` under the hood, and will be announced to a screen reader in addition to the label. Keep the description short and concise.

#### Icon button with visually hidden label

<Box
mb={3}
display="flex"
alignItems="flex-start"
flexDirection={['column', 'column', 'column', 'column', 'row']}
sx={{gap: 4}}
>
<img
width="456"
alt="Icon button with tooltip as a description"
src="https://github.com/primer/design/assets/18661030/2d0cd085-2454-406e-8c99-bc8bd3dd20db"
/>
<Box as="p" mt="0">
Icon buttons have a visually hidden label utilizing `aria-label`. To provide context in addition to the visually
hidden label, use the `description` option.
</Box>
</Box>

#### Button with visible label

<Box
mb={3}
display="flex"
alignItems="flex-start"
flexDirection={['column', 'column', 'column', 'column', 'row']}
sx={{gap: 4}}
>
<img
width="456"
alt="Button labeled Notifications with tooltip as a description"
src="https://github.com/primer/design/assets/18661030/a85cc241-c194-498d-b6ad-8e973fd18aca"
/>
<Box as="p" mt="0">
For buttons that have a visible label, the `description` option can also be used to provide additional context.
</Box>
</Box>

### Position

By default, the Tooltip component will position itself below the interactive control in a centered alignment. The position is dependant on the space available within the viewport, and it will never break outside of it. It may appear to the top, bottom, left, or right of the interactive control.

<img
width="960"
role="presentation"
src="https://github.com/primer/design/assets/18661030/c620d282-1efd-4556-9d9c-770c37359fc9"
alt="tooltips rendered in all possible positions surrounding a control"
/>

## Alternatives to tooltips
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love this section so much

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have a couple of lint rules and doc pages where we cross-reference the existing Tooltip alternatives docs. Let's make sure to update those to avoid a dead link! (I can verify tomorrow which ones those are).

Or could it be sufficient to just cross-reference that page from this section rather than moving it entirely?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll follow up with the links outside this repo once this PR merges! ❤️ thank you


Before adding a tooltip, please consider: Is this information essential and necessary? Can the UI be made clearer? Can the information be shown on the page by default? See Tooltip alternatives for more accessible alternatives.

We use aria-label for tooltip contents. However, aria-label replaces the text content of an element in screen readers, so only use Tooltip on elements with no existing text content.

A tooltip may only be used on an element that is interactive such as a button or a link. Even if an element is focusable, a tooltip may only be used if the element does something when it's clicked.

### Tooltip alternatives
### 1. Persist the content

If possible, persist the content so it's always available rather than using a tooltip, which hides content by default. This ensures that the content is always discovered and surfaced to users regardless of device.

<DoDontContainer>
<Do>
<img
width="456"
alt="Information about how many discussions can be pinned added to the confirmation dialog"
src="https://github.com/primer/primitives/assets/18661030/e66db2af-723c-4cfa-8d97-47a42f17047d"
/>
<Caption>Find an appropriate permanent place to display additional information.</Caption>
</Do>
<Dont>
<img
width="456"
alt="Information about how many discussions can be pinned within tooltip on non-interactive element"
src="https://github.com/primer/primitives/assets/18661030/283a5677-ea86-40de-9a84-6751a9b531f8"
/>
<Caption>Don't use a tooltip to add additional helpful information</Caption>
</Dont>
</DoDontContainer>

### 2. Don't duplicate content

If the tooltip duplicates content that is already available on the page, remove it.

<DoDontContainer>
<Do>
<img
width="456"
alt="Pointer hovering over a link with no tooltip"
src="https://github.com/primer/primitives/assets/18661030/d62b048f-1095-41d8-8bfb-fef204ba50dc"
/>
<Caption>Remove any duplicate tooltip text.</Caption>
</Do>
<Dont>
<img
width="456"
alt="Screenshot of tooltip with GitHub username, @inkblotty, on a static span that says @inkblotty"
src="https://github.com/primer/primitives/assets/18661030/78046a69-57f2-4fcd-9f17-fc06576d704f"
/>
<Caption>Don't set tooltips that duplicate the trigger element content.</Caption>
</Dont>
</DoDontContainer>

### 3. Use a modal

Consider using a modal, which is accessible for mobile users and allows you to structure content that may otherwise be crammed into a tooltip.

<DoDontContainer>
<Do>
<img
width="456"
alt="Screenshot of GitHub Actions page with a modal that conveys workflow file information about a runner"
src="https://user-images.githubusercontent.com/40274682/160210527-2319e408-d433-407f-aac2-66eaf9e63246.png"
/>
<Caption>Do use a pattern that is accessible to a larger number of users such as a modal</Caption>
</Do>
<Dont>
<img
width="456"
alt="Screenshot of GitHub Actions page using a tooltip on a static element to convey long workflow file information"
src="https://github.com/primer/primitives/assets/18661030/f1107770-cf3b-4bc1-9f75-a766833c67e0"
/>
<Caption>Don't place long content inside a tooltip</Caption>
</Dont>
</DoDontContainer>

### 4. Use a summary disclosure

Consider using a summary disclosure that is accessible for mobile users and also offers the ability to show or hide content.

<DoDontContainer>
<Do>
<img
width="800"
alt="Screenshot of GitHub pricing page that uses a summary disclosure to hide and show additional information on each point"
src="https://user-images.githubusercontent.com/40274682/160211684-6c102dd6-4039-4c7b-8c52-eeeb71a27db5.png"
/>
<Caption>Do use a pattern that is accessible to a larger number of users such as a summary disclosure</Caption>
</Do>
<Dont>
<img
width="800"
alt="Screenshot of GitHub pricing page using a tooltip to hide and show long descriptions on each point"
src="https://github.com/primer/primitives/assets/18661030/8efbc68b-7fa9-409d-a020-2e5d75337005"
/>
<Caption>Don't use tooltips on non-interactive elements</Caption>
</Dont>
</DoDontContainer>

### Other

If you are unsure which alternative is more suited to your scenario and need help, consult a designer or the GitHub Accessibility team (if you are GitHub staff) for advice.

## Additional resources
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We introduced a new PVC lint rule recently the deprecated Primer CSS tooltipped which we have a ton of debt around that we want to tackle. It looks like the lint rule doc is now on Primer CSS Tooltipped.
Could it make sense to link to it here? :)


Most UI cases don't call for tooltips. Learn some [alternative methods to use in place of tooltips](/../guides/accessibility/tooltip-alternatives).
- [Your tooltips are bogus](https://heydonworks.com/article/your-tooltips-are-bogus/)
- [erb lint rule: NoAriaLabelMisuseCounter](https://github.com/github/erblint-github/blob/main/docs/rules/accessibility/no-aria-label-misuse-counter.md#no-aria-label-misuse-counter)
- [Rails tooltip linter](https://github.com/primer/view_components/blob/main/lib/primer/view_components/linters/tooltipped_migration.rb)

### Known accessibility issues

<AccessibilityLink label="tooltip"/>
<AccessibilityLink label="tooltip" />
Loading