Tooltip is a floating text label that succinctly describes the function of an interactive element, typically Icon Button. It’s displayed continuously as long as the user hovers over or focuses on the element.

also known as Info Tip

Planning to use Tooltip with IconButton? Instead, use IconButton's built-in tooltip.
Tooltip is under an experiment to fix and improve component behavior. No visual updates. Visit the Pull Request to learn more.
; Opens a new tab
Figma:

Responsive:

Adaptive:

A11y:

Props

Component props
Name
Type
Default
children
Required
React.Node
-

The anchor element, usually Icon Button, that triggers Tooltip on hover or focus.

text
Required
string
-

The text shown in Tooltip to describe its anchor element. See localization to learn more.

accessibilityLabel
string
-

Label to provide more context around the Tooltip’s function or purpose. By default text is used but this prop allows you to override it. Learn more about when to override it in the Accessibility section.

idealDirection
"up" | "right" | "down" | "left"
"down"

Specifies the preferred position of Tooltip relative to its anchor element. See the ideal direction variant to learn more.

inline
boolean
-

Properly positions Tooltip relative to an inline element, such as Icon Button using the inline property. See the inline variant to learn more.

React.Node
-

Displays a link at the bottom of Tooltip. See the link variant to learn more.

zIndex
Indexable
-

Specifies the stacking order of Tooltip along the z-axis in the current stacking context. See the z-index variant to learn more.

Usage guidelines

When to use
  • Providing helpful, but non-essential context to a UI element.
  • Enhancing a baseline understanding of an element or feature.
When not to use
  • Using a separate Tooltip instance with IconButton. Use IconButton's built-in tooltip instead.
  • Displaying information that is critical to the understanding of an element/feature. Use inline text instead.
  • Offering context at the surface-level scope. Consider a BannerCallout instead.

Best practices

Do

Use Tooltip to describe the function of an interactive element, typically Icon Button, in as few words as possible.

Don't

Use Tooltip to restate text already visible on screen.

Do

Use Tooltip to distinguish related actions with visually similar iconography.

Don't

Use Tooltip to communicate critical information, such as an error, instructions for performing a task or interaction feedback.

Do

Use Tooltip to add supplementary information about a feature, typically paired with an info-circle IconButton.

Don't

Pair Tooltip with a disabled element. See disabled elements to learn more.

Accessibility

Labels

When using Tooltip with IconButton, avoid repetitive labeling. The accessibilityLabel provided to IconButton should describe the intent of the button, not the icon itself. For instance, use “Settings” instead of “Cog icon”. Tooltip text should expand upon that intention, as seen in the "cog" example below. If Tooltip text is the same as IconButton accessibilityLabel, then add accessibilityLabel="" to the Tooltip, as seen with the "share" example below

import { Box, IconButton, Tooltip } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Tooltip text="Customize performance stats for your paid ads">
        <IconButton
          accessibilityLabel="Settings"
          bgColor="white"
          icon="cog"
          iconColor="darkGray"
          size="lg"
        />
      </Tooltip>
    </Box>
  );
}

import { Box, IconButton, Tooltip } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Tooltip accessibilityLabel="" text="Share">
        <IconButton
          accessibilityLabel="Share"
          bgColor="white"
          icon="share"
          iconColor="darkGray"
          size="lg"
        />
      </Tooltip>
    </Box>
  );
}

Disabled elements

Tooltips must be paired with an interactive, focusable element, like Button or IconButton. They cannot be paired with anything disabled or static, because this prevents keyboard users from triggering Tooltip and consuming its content. To test if you’re using Tooltip properly, use your keyboard rather than your mouse to trigger Tooltip.

If you need to explain why an item is disabled, consider adding plain Text near the disabled item, or an info-circle IconButton adjacent to the disabled element.

Localization

Be sure to localize all text strings. Note that localization can lengthen text by 20 to 30 percent.

Variants

Ideal direction

Pass in idealDirection to specify the preferred position of Tooltip relative to its anchor element. The default direction is "down", which should be used in most cases. The actual position may change given the available space around the anchor element.

import { useState } from 'react';
import { Box, Flex, IconButton, RadioButton, Tooltip } from 'gestalt';

export default function ExampleTooltip() {
  const [idealDirection, setIdealDirection] = useState('down');

  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Flex alignItems="center" direction="column" gap={{ column: 8, row: 0 }}>
        <Flex gap={{ column: 0, row: 4 }}>
          <RadioButton
            checked={idealDirection === 'up'}
            id="up"
            label="Up"
            name="idealDirection"
            onChange={() => setIdealDirection('up')}
            value="up"
          />
          <RadioButton
            checked={idealDirection === 'right'}
            id="right"
            label="Right"
            name="idealDirection"
            onChange={() => setIdealDirection('right')}
            value="right"
          />
          <RadioButton
            checked={idealDirection === 'down'}
            id="down"
            label="Down"
            name="idealDirection"
            onChange={() => setIdealDirection('down')}
            value="down"
          />
          <RadioButton
            checked={idealDirection === 'left'}
            id="left"
            label="Left"
            name="idealDirection"
            onChange={() => setIdealDirection('left')}
            value="left"
          />
        </Flex>
        <Tooltip
          accessibilityLabel=""
          idealDirection={idealDirection}
          inline
          text="Share"
        >
          <IconButton
            accessibilityLabel="Share this Pin"
            bgColor="white"
            icon="share"
            iconColor="darkGray"
            size="lg"
          />
        </Tooltip>
      </Flex>
    </Box>
  );
}

Inline

Use inline to properly position Tooltip relative to an inline element, such as an Icon Button

import { useRef, useState } from 'react';
import { Box, Dropdown, Heading, IconButton, Tooltip } from 'gestalt';

export default function SectionsIconButtonDropdownExample() {
  const [open, setOpen] = useState(false);
  const anchorRef = useRef(null);

  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Box width={600}>
        <Heading accessibilityLevel={4}>
          Sugar-Free Strawberry-Chocolate Greek Yogurt Bark Three-Step Recipe.
          <Tooltip
            accessibilityLabel=""
            idealDirection="right"
            inline
            text="More board options"
          >
            <IconButton
              ref={anchorRef}
              accessibilityControls="sections-dropdown-example"
              accessibilityExpanded={open}
              accessibilityHaspopup
              accessibilityLabel="More board options"
              bgColor="lightGray"
              icon="ellipsis"
              iconColor="darkGray"
              onClick={() => setOpen((prevVal) => !prevVal)}
              selected={open}
              size="sm"
            />
          </Tooltip>
        </Heading>
        {open && (
          <Dropdown
            anchor={anchorRef.current}
            id="sections-dropdown-example"
            onDismiss={() => {
              setOpen(false);
            }}
          >
            <Dropdown.Section label="Board Options">
              <Dropdown.Item
                onSelect={() => {}}
                option={{ value: 'edit', label: 'Edit Board' }}
              />
              <Dropdown.Item
                onSelect={() => {}}
                option={{ value: 'share', label: 'Share' }}
              />
              <Dropdown.Item
                onSelect={() => {}}
                option={{ value: 'merge', label: 'Merge' }}
              />
            </Dropdown.Section>
          </Dropdown>
        )}
      </Box>
    </Box>
  );
}

Pass in link to display a link at the bottom of Tooltip.

⚠️ Note: this feature will soon be deprecated, as it is not accessible. Please do not use it in new designs or features.
⚠️ Note: Please use HelpButton instead.

import { Box, Flex, IconButton, Link, Text, Tooltip } from 'gestalt';

export default function Example() {
  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Flex
        alignItems="center"
        gap={{ row: 2, column: 0 }}
        justifyContent="center"
      >
        <Text>Enable expanded targeting</Text>
        <Tooltip
          link={
            <Text color="inverse" size="100" weight="bold">
              <Link
                href="https://help.pinterest.com/en/business/article/expanded-targeting"
                target="blank"
              >
                Learn more
              </Link>
            </Text>
          }
          text="Use your Pin to expand your targeting."
        >
          <IconButton
            accessibilityLabel="Additional info."
            bgColor="white"
            icon="info-circle"
            iconColor="darkGray"
            size="sm"
          />
        </Tooltip>
      </Flex>
    </Box>
  );
}

Z-index

Tooltip has Layer built in, allowing it to overlay surrounding content. Use zIndex to specify the stacking order of Tooltip along the z-axis in the current stacking context. The example below shows FixedZIndex used in Modal and CompositeZIndex to layer Tooltip on top.

import { Fragment, useState } from 'react';
import {
  Box,
  Button,
  FixedZIndex,
  Flex,
  Heading,
  IconButton,
  Image,
  Layer,
  Modal,
  Text,
  Tooltip,
} from 'gestalt';

const MODAL_Z_INDEX = new FixedZIndex(11);

export default function ScrollBoundaryContainerExample() {
  const [showModal, setShowModal] = useState(false);
  const [alignText, setAlignText] = useState('forceLeft');

  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <Fragment>
        <Box display="flex" justifyContent="center">
          <Button
            accessibilityLabel="Edit this Pin"
            color="white"
            onClick={() => setShowModal(true)}
            size="lg"
            text="Open edit modal"
          />
        </Box>
        {showModal && (
          <Layer zIndex={MODAL_Z_INDEX}>
            <Modal
              accessibilityModalLabel="Edit Pin"
              footer={
                <Box flex="grow" paddingX={3} paddingY={3}>
                  <Box
                    display="flex"
                    justifyContent="end"
                    marginBottom={-1}
                    marginEnd={-1}
                    marginStart={-1}
                    marginTop={-1}
                    wrap
                  >
                    <Box paddingX={1} paddingY={1}>
                      <Button
                        onClick={() => setShowModal(false)}
                        size="lg"
                        text="Cancel"
                      />
                    </Box>
                    <Box paddingX={1} paddingY={1}>
                      <Button
                        color="red"
                        onClick={() => setShowModal(false)}
                        size="lg"
                        text="Save"
                        type="submit"
                      />
                    </Box>
                  </Box>
                </Box>
              }
              heading="Edit"
              onDismiss={() => setShowModal(false)}
              size="lg"
            >
              <Box column={12} display="flex" justifyContent="center">
                <Box column={6} paddingX={4}>
                  <Image
                    alt="Tropic greens: The taste of Petrol and Porcelain | Interior design, Vintage Sets and Unique Pieces agave"
                    color="rgb(231, 186, 176)"
                    naturalHeight={751}
                    naturalWidth={564}
                    src="https://i.ibb.co/7bQQYkX/stock2.jpg"
                  >
                    <Box padding={3}>
                      <Heading align={alignText} color="light" size="600">
                        Tropic greens: The taste of Petrol and Porcelain
                      </Heading>
                    </Box>
                  </Image>
                </Box>
                <Flex direction="column" gap={{ column: 4, row: 0 }}>
                  <Heading size="400">Text Overlay</Heading>
                  <Text size="300">Add text directly onto your Pin</Text>
                  <Text size="300" weight="bold">
                    Alignment
                  </Text>
                  <Flex>
                    <Tooltip text="Align left">
                      <IconButton
                        accessibilityLabel="Align left"
                        bgColor="white"
                        icon="text-align-left"
                        iconColor="darkGray"
                        onClick={() => setAlignText('left')}
                        selected={alignText === 'left'}
                        size="lg"
                      />
                    </Tooltip>
                    <Tooltip text="Align center">
                      <IconButton
                        accessibilityLabel="Align center"
                        bgColor="white"
                        icon="text-align-center"
                        iconColor="darkGray"
                        onClick={() => setAlignText('center')}
                        selected={alignText === 'center'}
                        size="lg"
                      />
                    </Tooltip>
                    <Tooltip text="Align right">
                      <IconButton
                        accessibilityLabel="Align right"
                        bgColor="white"
                        icon="text-align-right"
                        iconColor="darkGray"
                        onClick={() => setAlignText('right')}
                        selected={alignText === 'right'}
                        size="lg"
                      />
                    </Tooltip>
                  </Flex>
                </Flex>
              </Box>
            </Modal>
          </Layer>
        )}
      </Fragment>
    </Box>
  );
}

Within scrolling containers

ScrollBoundaryContainer is needed for proper positioning when Tooltip is anchored to an element that is located within a scrolling container. The use of ScrollBoundaryContainer ensures Tooltip remains attached to its anchor when scrolling.

import { useState } from 'react';
import {
  Box,
  Flex,
  Icon,
  IconButton,
  RadioButton,
  ScrollBoundaryContainer,
  Text,
  Tooltip,
} from 'gestalt';

export default function ScrollBoundaryContainerExample() {
  const [content, setContent] = useState(null);
  const [claimed, setClaimed] = useState(null);
  const [device, setDevice] = useState(null);

  return (
    <Box
      alignItems="center"
      display="flex"
      height="100%"
      justifyContent="center"
      padding={8}
    >
      <ScrollBoundaryContainer height={200} overflow="scrollY">
        <Flex direction="column" gap={{ column: 4, row: 0 }} width={300}>
          <Flex direction="column" gap={{ column: 2, row: 0 }}>
            <Flex alignItems="center" gap={{ row: 1, column: 0 }}>
              <Text size="400" weight="bold">
                Content type
              </Text>
              <Tooltip
                idealDirection="right"
                text="See stats about different types of content created by you and/or others on Pinterest. Filter to get more details on your organic (not an ad) and paid (promoted as an ad) content."
              >
                <IconButton
                  accessibilityLabel="Information"
                  bgColor="white"
                  icon="info-circle"
                  iconColor="darkGray"
                />
              </Tooltip>
            </Flex>
            <Box direction="column" display="flex">
              <Box paddingY={1}>
                <RadioButton
                  checked={content === 'all'}
                  id="allcontent"
                  label="All"
                  name="content"
                  onChange={() => setContent('all')}
                  value="all"
                />
              </Box>
              <Box paddingY={1}>
                <RadioButton
                  checked={content === 'organic'}
                  id="organic"
                  label="Organic"
                  name="content"
                  onChange={() => setContent('organic')}
                  value="organic"
                />
              </Box>
              <Box paddingY={1}>
                <RadioButton
                  checked={content === 'paid'}
                  id="paid"
                  label="Paid and earned"
                  name="content"
                  onChange={() => setContent('paid')}
                  value="paid"
                />
              </Box>
            </Box>
          </Flex>
          <Flex direction="column" gap={{ column: 2, row: 0 }}>
            <Flex alignItems="center" gap={{ row: 1, column: 0 }}>
              <Text size="400" weight="bold">
                Claimed account
              </Text>
              <Tooltip
                idealDirection="right"
                text="See stats for Pins linked to your claimed accounts like websites, Etsy, Instagram or Youtube. The Other Pins category includes Pins you’ve published or saved that don’t link to any of your claimed accounts."
              >
                <Icon
                  accessibilityLabel="Information"
                  color="default"
                  icon="info-circle"
                />
              </Tooltip>
            </Flex>
            <Box direction="column" display="flex">
              <Box paddingY={1}>
                <RadioButton
                  checked={claimed === 'all'}
                  id="allclaimed"
                  label="All Pins"
                  name="claimed"
                  onChange={() => setClaimed('all')}
                  value="all"
                />
              </Box>
              <Box paddingY={1}>
                <RadioButton
                  checked={claimed === 'instagram'}
                  id="instagram"
                  label="Instagram"
                  name="claimed"
                  onChange={() => setClaimed('instagram')}
                  value="instagram"
                />
              </Box>
              <Box paddingY={1}>
                <RadioButton
                  checked={claimed === 'other'}
                  id="other"
                  label="Other pins"
                  name="claimed"
                  onChange={() => setClaimed('other')}
                  value="other"
                />
              </Box>
            </Box>
          </Flex>
          <Flex direction="column" gap={{ column: 2, row: 0 }}>
            <Flex alignItems="center" gap={{ row: 1, column: 0 }}>
              <Text size="400" weight="bold">
                Device
              </Text>
              <Tooltip
                idealDirection="right"
                text="See stats for the different devices your Pinterest traffic is coming from."
              >
                <Icon
                  accessibilityLabel="Information"
                  color="default"
                  icon="info-circle"
                />
              </Tooltip>
            </Flex>
            <Box direction="column" display="flex">
              <Box paddingY={1}>
                <RadioButton
                  checked={device === 'all'}
                  id="alldevices"
                  label="All"
                  name="device"
                  onChange={() => setDevice('all')}
                  value="all"
                />
              </Box>
              <Box paddingY={1}>
                <RadioButton
                  checked={device === 'mobile'}
                  id="mobile"
                  label="Mobile"
                  name="device"
                  onChange={() => setDevice('mobile')}
                  value="mobile"
                />
              </Box>
              <Box paddingY={1}>
                <RadioButton
                  checked={device === 'desktop'}
                  id="desktop"
                  label="Desktop"
                  name="device"
                  onChange={() => setDevice('desktop')}
                  value="desktop"
                />
              </Box>
              <Box paddingY={1}>
                <RadioButton
                  checked={device === 'tablet'}
                  id="tablet"
                  label="Tablet"
                  name="device"
                  onChange={() => setDevice('tablet')}
                  value="tablet"
                />
              </Box>
            </Box>
          </Flex>
        </Flex>
      </ScrollBoundaryContainer>
    </Box>
  );
}

Writing

Do
  • Describe only the element that triggers Tooltip.
  • Focus on the action by beginning with a verb.
  • Use succinct and scannable language.
  • As much as possible, limit Tooltip's text to a maximum of 60 to 75 characters.
  • Use sentence case while always capitalizing the word “Pin.”
Don't
  • Describe elements other than the one that triggers Tooltip.
  • Use Tooltip to restate text already visible on screen.
  • Use Tooltip to communicate critical information, such as an error, instructions for performing a task, or interaction feedback.

Component quality checklist

Component quality checklist
Quality item
Status
Status description
Figma Library
Ready
Component is available in Figma for web and mobile web.
Responsive Web
Ready
Component responds to changing viewport sizes in web and mobile web.
Issues
This component has known issues.

Popover
Popover displays a lightweight task related to the content on screen. One example of Popover is the board picker, which allows people to choose the board to save a Pin to. While Tooltips are purely text-based, Popovers offer broader content options, such as Buttons and Images.

ScrollBoundaryContainer
ScrollBoundaryContainer is needed for proper positioning when Tooltip is anchored to an element that is located within a scrolling container. The use of ScrollBoundaryContainer ensures Tooltip remains attached to its anchor when scrolling. See the within scrolling containers variant to learn more.

Toast
Toast provides feedback on an interaction. One example of Toast is the confirmation that appears when a Pin has been saved. Toasts appear at the bottom of a desktop screen or top of a mobile screen, instead of being attached to any particular element on the interface.