Show · Tooltip

Tooltip

Tooltip is used to identify an element or attach a small amount of auxiliary information. The most typical scenario is to explain the meaning of the icon to the user, display the truncated text, display the description of the picture, and so on.

Demos

How to import

<script setup lang="ts">
    import { Tooltip } from '@fibrous/semi-ui-vue';
</script>

Cautions

Tooltip applies the trigger attributes and event listeners to the trigger in the default slot, and positions the popup against the real DOM element of that trigger, so the default slot supports the following:

  1. A single actual DOM element, such as span, div, p, etc.
  2. A single component whose undeclared attributes reach its root DOM element (the default attrs fallthrough is enough). For a component with several root nodes, such as a nested Tooltip, the first element is the anchor
  3. Text or several nodes, which Tooltip wraps in a span that becomes the trigger
Component
Text DOM
Code
<script setup lang="ts">
    import { Space, Tag, Tooltip } from '@fibrous/semi-ui-vue';

    const style = {
        border: '2px solid var(--semi-color-border)',
        paddingLeft: '4px',
        paddingRight: '4px',
        borderRadius: '4px',
    };
</script>

<template>
    <Space>
        <Tooltip>
            <Tag :style="style">Component</Tag>
            <template #content>semi design</template>
        </Tooltip>
        <Tooltip>
            Text
            <template #content>semi design</template>
        </Tooltip>
        <Tooltip>
            <span :style="style">DOM</span>
            <template #content>semi design</template>
        </Tooltip>
    </Space>
</template>

Position

The direction and alignment position of the popup layer can be configured through position. For detailed optional values of position, please refer to the API document below

When configured as topLeft, it pops up, and the popup layer is left-aligned with the children (when arrowPointAtCenter=false) . When configured as topRight, it pops up, and the popup layer is right-aligned with the children (when arrowPointAtCenter=false) . Same for other directions

TL
Top
TR
LT
Left
LB
RT
Right
RB
BL
Bottom
BR
Code
<script setup lang="ts">
    import { Tag, Tooltip, type Position } from '@fibrous/semi-ui-vue';

    const tops: [Position, string][] = [
        ['topLeft', 'TL'],
        ['top', 'Top'],
        ['topRight', 'TR'],
    ];
    const lefts: [Position, string][] = [
        ['leftTop', 'LT'],
        ['left', 'Left'],
        ['leftBottom', 'LB'],
    ];
    const rights: [Position, string][] = [
        ['rightTop', 'RT'],
        ['right', 'Right'],
        ['rightBottom', 'RB'],
    ];
    const bottoms: [Position, string][] = [
        ['bottomLeft', 'BL'],
        ['bottom', 'Bottom'],
        ['bottomRight', 'BR'],
    ];
</script>

<template>
    <div>
        <div :style="{ marginLeft: '80px', whiteSpace: 'nowrap' }">
            <Tooltip v-for="[position, label] in tops" :key="position" :arrowPointAtCenter="false" :position="position">
                <Tag :style="{ margin: '8px', padding: '20px' }">{{ label }}</Tag>
                <template #content>
                    <article>
                        <p>hi bytedance</p>
                        <p>hi bytedance</p>
                    </article>
                </template>
            </Tooltip>
        </div>
        <div :style="{ width: '80px', float: 'left' }">
            <Tooltip v-for="[position, label] in lefts" :key="position" :arrowPointAtCenter="false" :position="position">
                <Tag :style="{ margin: '8px', padding: '20px', width: '60px' }">{{ label }}</Tag>
                <template #content>
                    <article>
                        <p>hi bytedance</p>
                        <p>hi bytedance</p>
                    </article>
                </template>
            </Tooltip>
        </div>
        <div :style="{ width: '40px', marginLeft: '300px' }">
            <Tooltip v-for="[position, label] in rights" :key="position" :arrowPointAtCenter="false" :position="position">
                <Tag :style="{ margin: '8px', padding: '20px', width: '60px' }">{{ label }}</Tag>
                <template #content>
                    <article>
                        <p>hi bytedance</p>
                        <p>hi bytedance</p>
                    </article>
                </template>
            </Tooltip>
        </div>
        <div :style="{ marginLeft: '80px', clear: 'both', whiteSpace: 'nowrap' }">
            <Tooltip v-for="[position, label] in bottoms" :key="position" :arrowPointAtCenter="false" :position="position">
                <Tag :style="{ margin: '8px', padding: '20px', width: '60px' }">{{ label }}</Tag>
                <template #content>
                    <article>
                        <p>hi bytedance</p>
                        <p>hi bytedance</p>
                    </article>
                </template>
            </Tooltip>
        </div>
    </div>
</template>

Arrow Point at Center

By default arrowPointAtCenter=true, the small triangle always points to the center of the children element.
You can set it to false and the little triangle will no longer keep pointing to the center of the element. The popover is aligned to the edges of the children

Code
<script setup lang="ts">
    import { Button, Tooltip } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div>
        <Tooltip position="topLeft">
            <Button :style="{ marginRight: '8px' }" type="secondary">指向元素中心</Button>
            <template #content>semi design tooltip</template>
        </Tooltip>
    </div>

    <div :style="{ marginTop: '20px' }">
        <Tooltip :arrowPointAtCenter="false" position="topLeft">
            <Button :style="{ marginRight: '8px', width: '120px' }" type="secondary">边缘对齐</Button>
            <template #content>semi design tooltip</template>
        </Tooltip>
    </div>
</template>

Trigger Timing

  • Configure the timing of the trigger display, the default is hover, optional hover / focus / click / custom / contextMenu.
  • When set to custom, it needs to be used in conjunction with the visibleattribute, at which point the display is completely controlled
  • The contextMenu (right-click) trigger is available




Code
<script setup lang="ts">
    import { ref } from 'vue';
    import { Button, Input, Radio, RadioGroup, Tooltip, type RadioValue } from '@fibrous/semi-ui-vue';

    const visible = ref<RadioValue | undefined>(0);
</script>

<template>
    <div>
        <Tooltip>
            <Button :style="{ marginBottom: '20px' }" theme="solid" type="tertiary">悬停显示</Button>
            <template #content>hi bytedance</template>
        </Tooltip>
        <br />
        <Tooltip trigger="click">
            <Button :style="{ marginBottom: '20px' }">点击显示</Button>
            <template #content>hi bytedance</template>
        </Tooltip>
        <br />
        <Tooltip trigger="focus">
            <Input aria-label="聚焦显示" placeholder="聚焦显示" :style="{ width: '100px', marginBottom: '20px' }" />
            <template #content>hi bytedance</template>
        </Tooltip>
        <br />
        <Tooltip trigger="contextMenu">
            <Button :style="{ marginBottom: '20px' }" theme="solid" type="secondary">右键点击展示</Button>
            <template #content>hi bytedance</template>
        </Tooltip>
        <br />
        <Tooltip trigger="custom" :visible="visible === 1">
            <span :style="{ display: 'inline-block' }">
                <RadioGroup v-model="visible" type="button">
                    <Radio :value="1">受控显示</Radio>
                    <Radio :value="0">受控隐藏</Radio>
                </RadioGroup>
            </span>
            <template #content>hi bytedance</template>
        </Tooltip>
    </div>
</template>

Conditional trigger (condition)

When :condition="false", Tooltip will not respond to hover/click/focus triggers (with trigger="custom", visible still shows it); when condition changes from true to false, an open popup closes at once; with visible controlled it only emits update:visible and visibleChange(false), and the popup closes once the owner sets visible to false.

condition
Code
<script setup lang="ts">
    import { computed, ref } from 'vue';
    import { Button, Space, Switch, Tooltip, Typography } from '@fibrous/semi-ui-vue';

    const { Text } = Typography;
    const enabled = ref(true);
    const content = computed(() => `condition is ${enabled.value ? 'true' : 'false'}`);
</script>

<template>
    <Space align="center">
        <Text id="tooltip-condition-label">condition</Text>
        <Switch v-model="enabled" aria-labelledby="tooltip-condition-label" />
        <Tooltip :condition="enabled" trigger="hover">
            <Button>Hover me</Button>
            <template #content>{{ content }}</template>
        </Tooltip>
        <Tooltip :condition="enabled" trigger="click">
            <Button>Click me</Button>
            <template #content>{{ content }}</template>
        </Tooltip>
    </Space>
</template>

Override Style

Configure specific styles for the pop-up layer through class and style, such as overriding the default maxWidth (240px)

Custom Style And ClassName
Code
<script setup lang="ts">
    import { Tag, Tooltip } from '@fibrous/semi-ui-vue';
</script>

<template>
    <div>
        <Tooltip class="another-classname" :style="{ maxWidth: '320px' }">
            <Tag :style="{ marginRight: '8px' }">Custom Style And ClassName</Tag>
            <template #content>hi semi semi semi semi semi semi semi</template>
        </Tooltip>
    </div>
</template>

Use with Popver or Popconfirm

Tooltip, Popconfirm, and Popover all bind related events on the trigger (mouseenter / mouseleave / click ....) and add trigger attributes such as aria-describedby and data-popupid. If they are nested directly, the inner component discards the ARIA attributes, tabindex, data-popupid and arrow key handling added by the outer one.
Add a layer of elements (div or span) in the middle as the trigger of the outer one.

Code
<script setup lang="ts">
    import { Button, Popconfirm, Tooltip } from '@fibrous/semi-ui-vue';
</script>

<template>
    <Popconfirm :style="{ width: '320px' }">
        <span :style="{ display: 'inline-block' }">
            <Tooltip>
                <Button type="danger">删除</Button>
                <template #content>删除评价</template>
            </Tooltip>
        </span>
        <template #title>确认</template>
        <template #content>是否确认删除</template>
    </Popconfirm>
</template>

Show Tooltip only when the content overflows

Semi provides the Typography component for this scenario, so you do not need to check for overflow yourself before showing a Tooltip. For details, see the Typography documentation.

是一个很长很长很长很长5号标题

是一个很长很长很长很长的链接

多行截断,展示 Popover:Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。

Code
<script setup lang="ts">
    import { Typography } from '@fibrous/semi-ui-vue';

    const { Paragraph, Title, Text } = Typography;
</script>

<template>
    <div>
        <Title :ellipsis="{ showTooltip: true }" :heading="5" :style="{ width: '250px' }"> 是一个很长很长很长很长5号标题 </Title>
        <br />
        <Text :ellipsis="{ showTooltip: true, pos: 'middle' }" link :style="{ width: '150px' }"> 是一个很长很长很长很长的链接 </Text>
        <br />
        <br />
        <Paragraph :ellipsis="{ rows: 3, showTooltip: { type: 'popover', opts: { style: { width: '300px' } } } }" :style="{ width: '300px' }">
            多行截断,展示 Popover:Semi Design 是由抖音前端团队与 UED 团队共同设计开发并维护的设计系统。设计系统包含设计语言以及一整套可复用的前端组件,帮助设计师与开发者更容易地打造高质量的、用户体验一致的、符合设计规范的 Web 应用。
        </Paragraph>
    </div>
</template>

API Reference


Props

PropertyDescriptionTypeDefault
motionWhether the popup is animated.booleansemiDefault("Tooltip", "motion", true)
autoAdjustOverflowWhether the popup flips automatically when it would be clipped.booleansemiDefault("Tooltip", "autoAdjustOverflow", true)
positionPosition of the popup relative to the trigger element.Type"top" | "bottom" | "left" | "right" | "topLeft" | "topRight" | "leftTop" | "leftBottom" | "rightTop" | "rightBottom" | "bottomLeft" | "bottomRight" | "leftTopOver" | "rightTopOver" | "leftBottomOver" | "rightBottomOver"semiDefault("Tooltip", "position", "top")
prefixClsClass prefix of the popup. A custom value drops the Tooltip styles.stringsemiDefault("Tooltip", "prefixCls", cssClasses.PREFIX)
spacingDistance in pixels between the popup and the trigger. An object sets the horizontal and vertical distances.number | { x: number; y: number; }semiDefault("Tooltip", "spacing", numbers.SPACING)
showArrowWhether the arrow is shown.booleansemiDefault("Tooltip", "showArrow", true)
roleARIA role of the popup.stringsemiDefault("Tooltip", "role", "tooltip")
ariaLabelaria-label of the popup when its role is dialog.stringsemiGlobalDefault("Tooltip", "ariaLabel")
ariaLabelledbyaria-labelledby of the popup when its role is dialog.stringsemiGlobalDefault("Tooltip", "ariaLabelledby")
ariaDescribedbyaria-describedby of the popup when its role is dialog.stringsemiGlobalDefault("Tooltip", "ariaDescribedby")
arrowPointAtCenterWhether the arrow points at the center of the trigger. Requires showArrow.booleansemiDefault("Tooltip", "arrowPointAtCenter", true)
wrapWhenSpecialWhether a disabled or loading trigger is wrapped in a span so that it still triggers the popup.booleansemiDefault("Tooltip", "wrapWhenSpecial", true)
stopPropagationWhether click, mousedown and focus in/out events on the popup stop propagating.booleansemiGlobalDefault("Tooltip", "stopPropagation")
wrapperClassNameClass name of the span that wraps the trigger when a wrapper is needed.stringsemiGlobalDefault("Tooltip", "wrapperClassName")
wrapperIdid of the popup element, referenced by the trigger's ARIA attributes. Generated when omitted.stringundefined
keepDOMWhether the popup content stays mounted while closed.booleansemiDefault("Tooltip", "keepDOM", false)
clickToHideWhether a click on the popup or anything inside it closes the popup.booleansemiGlobalDefault("Tooltip", "clickToHide")
clickTriggerToHideWhether a click on the trigger closes an open popup.booleansemiGlobalDefault("Tooltip", "clickTriggerToHide")
closeOnEscWhether Esc closes the open popup. With trigger custom it only emits escKeyDown and the caller decides whether to close.booleansemiDefault("Tooltip", "closeOnEsc", true)
conditionWhether the popup may be triggered. Only an explicit false disables the hover, click and focus triggers; with trigger custom, visible still shows the popup. Changing it from true to false closes an open popup at once; with a controlled visible it only emits update:visible and visibleChange(false), and the popup closes once the caller writes back.booleansemiDefault("Tooltip", "condition", true)
disableArrowKeyDownWhether the arrow keys on the trigger are prevented from moving focus into the popup.booleansemiDefault("Tooltip", "disableArrowKeyDown", false)
disableFocusListenerWhether keyboard focus is ignored when trigger is hover.booleansemiDefault("Tooltip", "disableFocusListener", false)
guardFocusWhether Tab cycles inside the popup while focus is in it.booleansemiDefault("Tooltip", "guardFocus", false)
mouseEnterDelayMilliseconds before the popup shows after the pointer enters. Applies to the hover and focus triggers.numbersemiDefault("Tooltip", "mouseEnterDelay", numbers.MOUSE_ENTER_DELAY)
mouseLeaveDelayMilliseconds before the popup hides after the pointer leaves. Applies to the hover and focus triggers; not less than mouseEnterDelay.numbersemiDefault("Tooltip", "mouseLeaveDelay", numbers.MOUSE_LEAVE_DELAY)
preventScrollWhether focusing an element avoids scrolling it into view.booleansemiGlobalDefault("Tooltip", "preventScroll")
returnFocusOnCloseWhether focus returns to the trigger after the popup closes.booleansemiDefault("Tooltip", "returnFocusOnClose", false)
triggerWhen the popup shows. With custom, visible alone decides."hover" | "focus" | "click" | "custom" | "contextMenu"semiDefault("Tooltip", "trigger", "hover")
visibleWhether the popup is shown, used with v-model:visible. When given, this value decides.booleansemiGlobalDefault("Tooltip", "visible")

Events

EventDescriptionCallback parameters
openEmitted once per opening when the popup is shown, as its enter animation starts, before afterOpen, controlled or not; not emitted for a hover open withdrawn because the pointer already left.[]
update:visibleEmitted when the popup should show or hide, for v-model:visible to write back.[visible: boolean]
visibleChangeEmitted when the visibility of the popup changes; with a controlled visible it reports only requests from user interaction, not changes the parent makes to visible.[visible: boolean]
clickOutSideEmitted when the mouse is pressed outside of the trigger and the open popup. Only for trigger click, contextMenu or custom, or with clickTriggerToHide.[event: MouseEvent]
escKeyDownEmitted when Esc is pressed while the popup is open and closeOnEsc is true.[event: KeyboardEvent]
afterOpenEmitted after the popup has opened and its enter animation has finished, or right after opening when there is no enter animation, controlled or not; not emitted for an open that is closed before the enter animation ends.[]
afterCloseEmitted after the popup has closed and its leave animation has finished.[]

Slots

SlotDescriptionScope parameters
defaultThe trigger. A single element or component receives the trigger attributes directly; text or several nodes are wrapped in a span.any
contentPopup content. The scope parameter initialFocusRef binds to the element that receives focus when the popup opens.TypeRenderContentProps<FocusTarget>
arrowReplaces the arrow.any

Exposes

NameDescriptionType
focusTriggerFocuses the trigger element. Only works when returnFocusOnClose is true and trigger is not custom.Type() => void
getPopupIdReturns the id of the popup element.Type() => string
hideCloses the popup. With a controlled visible it only emits update:visible and visibleChange for the caller to write back.Type() => void
rePositionRecomputes the popup position from the trigger's current position at once. The popup already follows scrolling, window resizing, trigger moves and size changes of the trigger or popup, so this is rarely needed; following a trigger move lands a frame late, so call this to align within the same frame.Type() => void

class and style land on the popup; other undeclared attributes are discarded. The trigger attributes are added to the trigger element only. When the subtree is cached by <KeepAlive> (deactivated), the popup is treated as closed and update:visible and visibleChange are emitted with false; a popup whose visible is one-way bound to true is hidden with the cached subtree and shows again once reactivated.

Accessibility

ARIA

  • Tooltip has a tooltip role, following the definition of Tooltip in the WAI-ARIA specification
  • Tooltip's content and children
    • about content
      • The wrapper of content will be automatically added with id attribute to match the aria-describedby of children and associate content with children
    • about children
      • There should be an explicit connection between the content of the Tooltip and its children. Tooltip will automatically add the aria-describedby attribute to the children element, the value is the id of the content wrapper.
      • If the children of your Tooltip are Icon and do not contain visible text, we recommend that you add the aria-label attribute to the children to describe accordingly
<!-- Good practices, add aria-label to the tooltip trigger -->
<Tooltip>
    <IconSetting aria-label="Settings" />
    <template #content><p id="description">Edit your setting</p></template>
</Tooltip>

Content Guidelines

  • Only display information description and guidance, do not display error information
  • Only extra links and buttons not in tooltip
  • Try to simplify the description to one sentence without showing punctuation marks

Design Tokens

These are the component's internal Sass variables and cannot be overridden. To customize styles, override the --semi-* CSS variables (see the Design Token page) or write unlayered CSS rules.
Sass variableValueUsage
$animation_duration-tooltip_out100mstooltip-显示及收起动画-动画持续时间
$animation_function-tooltip_outcubic-bezier(0.215, 0.61, 0.355, 1)tooltip-显示及收起动画-动画插值函数
$horizontal-rate0.24水平方向矫正因子
$vertical-rate0垂直方向矫正因子
$motion-zoom_scale-from0.8进出场动画的初始缩放
$color-tooltip-bg-defaultvar(--semi-grey-7)工具提示默认背景色
$color-tooltip-text-defaultvar(--semi-color-bg-0)工具提示默认文字颜色
$color-tooltip-icon-defaultvar(--semi-grey-7)工具提示默认图标颜色
$color-tooltip_arrow-icon-default$color-tooltip-icon-default工具提示默认小三角箭头颜色
$radius-tooltipvar(--semi-border-radius-medium)工具提示默认圆角
$spacing-tooltip_content-paddingLeft$spacing-base-tight工具提示内容左侧内边距
$spacing-tooltip_content-paddingRight$spacing-base-tight工具提示内容右侧内边距
$spacing-tooltip_content-paddingTop$spacing-tight工具提示内容顶部内边距
$spacing-tooltip_content-paddingBottom$spacing-tight工具提示内容底部内边距
$font-tooltip-fontSize$font-size-regular工具提示文本字号
$width-tooltip240px工具提示宽度 - 默认
$width-tooltip_arrow24px工具提示小三角箭头宽度 - 水平
$height-tooltip_arrow7px工具提示小三角箭头高度 - 水平
$height-tooltip_arrow_vertical24px工具提示小三角箭头高度 - 垂直
$width-tooltip_arrow_vertical7px工具提示小三角箭头宽度度 - 垂直
$spacing-tooltip_arrow_offset-x1px水平方向渲染会有缝隙,所以加个偏移量
$spacing-tooltip_arrow_offset-y1px垂直方向渲染会有缝隙,所以加个偏移量
$spacing-tooltip_arrow_adjusted_offset-y6px垂直方向上的校正偏移量,主要修正三角形有棱角的问题
$spacing-tooltip_arrow_adjusted_offset-xmath.round($horizontal-rate * $width-tooltip_arrow)水平方向上的校正偏移量,主要修正三角形有棱角的问题
$filter-tooltip-bgnone

FAQ

  • Why do some forms of content not wrap when the content in Tooltip is very long?
    The Tooltip popup sets overflow-wrap to break-word, so an overlong word breaks onto the next line. Different language content (e.g. English, Chinese, combination of English and Chinese) needs different line breaking; if the default does not fit, adjust the line break related CSS properties through style and className (class in Vue).