【翻译】工具提示组件不应存在

27 阅读4分钟

Photo by Daniel Herron

原文链接:tkdodo.eu/blog/toolti…

作者:Dominik

我必须承认:网页应用中糟糕的工具提示是我最讨厌的事情之一。公平地说,工具提示确实很容易设计失误。需要考虑的因素很多:

  • 可访问性
  • 键盘交互性
  • 所有用户体验一致性
  • 避免隐藏关键信息

多年来,我见过许多设计系统试图为用户提供<Tooltip>组件,但在我看来它们有个共同点——用户永远不会按预期使用。从API设计角度看,这很可能意味着<Tooltip>组件作为抽象层过于底层,这也引出了我今天的犀利观点🌶:

Screenshot 2026-01-16 at 14.40.16.png

我并非主张取消工具提示功能本身。当应用得当——无论对你的具体场景而言"得当"意味着什么——它们仍是宝贵的辅助工具。当然,教育或许能解决问题,但坦白说:极少有人会阅读文档,而AI只会复现它已见过的内容,因此很可能放大我们代码库中现有的反模式。

在探讨替代方案之前,让我们先剖析错误使用工具提示可能引发的潜在问题。

键盘交互性

这一点理应不言自明:我们应当为所有人构建网页应用,这意味着必须意识到并非所有用户都会使用鼠标。然而我经常遇到这样的实现方式——当触发提示的元素本身不可交互时,却仅在鼠标悬停时显示工具提示。

以广受欢迎的组件库Material UI为例,其文档中的基础工具提示示例如下:

<Tooltip title="Delete">
  <IconButton>
    <DeleteIcon />
  </IconButton>
</Tooltip>

这很简单且有效,但如果我们只在图标周围添加<Tooltip>,或者在Badge等其他非交互元素周围添加,会发生什么情况:

<Tooltip title="Home">
  <IconHome />
</Tooltip>

<Tooltip title="Unread Mails">
  <Badge badgeContent={4} color="primary">
    <IconMail color="action" />
  </Badge>
</Tooltip>

没错——悬停时提示框仍会显示,但焦点状态下不会出现,因为按Tab键会直接跳过它。该元素不支持键盘交互,因此永远不会获得焦点,这意味着仅使用键盘导航时提示框永远不会出现。

此外,这种方案无法实现类型安全,因为我们无法控制传递给<Tooltip>组件的子元素类型。React Aria 的方案稍优,它会直接隐藏非交互元素的提示框,便于主要使用鼠标的开发者识别。解决方案是将自定义触发器包裹在 <Focusable> 组件中。虽然这比其他方案好得多,但仍存在其他问题,具体而言:

对所有用户而言,最小化意外

只要某个元素能添加<Tooltip>,总会有人尝试。我见过最离奇的提示框位置——比如出现在句子中间的某个文字上,却没有任何提示说明背后藏着附加信息。

但我也见过相反的情况。看到一个仅由无法理解的图标组成的按钮,却完全不知道点击后会发生什么,这让我极其恼火。

当开发者和设计师团队规模达到临界点时,应用程序中必然会出现这类不一致现象。

既然独立的<Tooltip>组件并非理想方案,设计系统还能采用哪些方法实现工具提示功能?我的观点是:

Screenshot 2026-01-16 at 16.16.47.png

过去我见过效果特别好的做法包括:

  • 交互组件如<Button><Link>可添加可选的title属性。 这让我们能根据需要展示额外信息。交互元素通常在界面中很容易被发现,通过键盘Tab键也能定位到。
  • <IconButton> 组件强制要求 title 属性。此举既能向用户解释图标含义,又为按钮提供符合无障碍标准的标注方式。
  • 引入额外的 <InfoIcon> 组件,用于渲染信息图标/问号图标 + 工具提示。
  • 这既能引导用户获取补充信息,又能确保该组件内部可获得焦点。
  • 创建组件以提供文本补充说明。
  • 该组件需通过视觉标识(如虚线下划线)与普通文本区分,并支持键盘交互操作。

我确信可能还有其他遗漏之处,但若真有遗漏,添加另一个模式组件也比让所有人访问底层的<Tooltip>组件更可取。别误会,灵活性在许多场景下确实很棒,比如布局设计,但对工具提示而言,提供一致的用户体验和包容性远比灵活重要得多,因此限制反而更好。

限制反而能激发创造力——当屏幕空间不足时,若不能简单地将信息塞进工具提示框,或许反而能促使我们从根本上重新思考设计方案。

因此,若您正在为组织构建设计系统,请务必克制在公共接口中添加<Tooltip>组件的冲动。