Menu

HTML 按钮链接:如何做一个跳转页面的按钮

要做一个跳转到其他页面的按钮,正确的做法是把链接设置成按钮的样式。了解为什么链接里套按钮和用 onclick 跳转会出问题,什么时候适合用表单按钮,以及如何设置链接按钮的样式和禁用状态。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

如何做一个链接到页面的按钮

写一个普通的链接 <a href>,再用 CSS 把它设置成按钮的样子。它像任何链接一样跳转到页面,而且保留了链接的所有功能:在新标签页中打开、复制链接地址,以及悬停时预览 URL。

把链接变成按钮的几条规则:

  • display: inline-block 让内边距能把盒子撑开,同时让它保持在文字行内。
  • text-decoration: none 去掉下划线。
  • color 和 background 替换掉蓝色的链接颜色。
  • :focus-visible 为键盘用户提供清晰的焦点环。

同一个类也适用于 <button>,所以表单的提交按钮和链接到其他页面的链接可以看起来一模一样,同时各司其职。

按钮还是链接:该用哪个元素

关键在于点击后会发生什么,而不是它看起来像什么。

点击后使用示例
跳转到另一个 URL<a href>注册、阅读更多、查看价格、下载
改变当前页面上的某些内容<button type="button">打开菜单、播放、加入购物车、显示密码
提交表单<button type="submit">登录、搜索、保存

屏幕阅读器把链接播报为“链接”,把按钮播报为“按钮”,以此告诉用户接下来会发生什么。它们的键盘行为也不同:Enter 键对两者都有效,但空格键只能激活按钮(在链接上按空格会滚动页面)。按钮元素本身的介绍见 HTML 按钮。

为什么不要把按钮放在链接里

大多数人首先尝试的都是这种写法:

<!-- Invalid: interactive content inside <a> -->
<a href="/signup"><button>Sign up</button></a>

<!-- Invalid the other way round, too -->
<button><a href="/signup">Sign up</a></button>

HTML 标准对这两种写法都是禁止的:<a> 和 <button> 里面都不能包含交互元素。实际上,键盘会在一个控件上遇到两个 Tab 停留点,屏幕阅读器可能会播报“链接,按钮,Sign up”,而点击是否会跟随链接取决于浏览器。只选一个元素。

为什么不要用 onclick 加 location.href

另一种常见的变通办法,是做一个用 JavaScript 设置 URL 的按钮。它看起来和链接一样:

(示例里用的是 window.open,因为预览不能离开当前页面;平时的写法是 location.href = '...'。)把鼠标悬停在两者上并点击右键:只有真正的链接会显示它的 URL,并提供“在新标签页中打开链接”和“复制链接地址”。按钮也无法用 Ctrl+点击或中键点击,浏览器不会把它标记为已访问,搜索引擎也不会把它当作链接来抓取。如果目标是一个 URL,就写 <a href>。

打开 URL 的表单按钮

有一种情况下,跳转到其他页面的 <button> 是正确的:它需要同时发送数据。搜索框就是典型的例子。表单的 action 是 URL,method="get" 会把字段放进查询字符串:

点击 Search:在真实页面中,浏览器会跳转到 https://duckduckgo.com/?q=html+button+link。预览不会离开页面,而是显示这些数据。第二个按钮上的 formaction 会把同一个表单发送到另一个 URL。

禁用的链接按钮

链接没有 disabled 属性;<a disabled> 什么作用都没有。要关闭一个链接按钮,就删掉它的 href(没有 href 的 <a> 不是链接,无法点击也无法聚焦),并用 aria-disabled="true" 标记它,让样式和屏幕阅读器都知道:

在预览中按 Tab 键:焦点只会落在第一个按钮上。有些网站保留 href,改用 pointer-events: none,但这只能阻止鼠标。用 Tab 键依然能访问到这个链接,按 Enter 也依然会跳转。

新标签页和下载按钮

设置成按钮样式的链接,所有链接属性依然有效:

<a class="btn" href="/files/guide.pdf" download>Download the guide</a>
<a class="btn" href="https://github.com/" target="_blank" rel="noopener">GitHub</a>

这是使用 <a> 的又一个理由:<button> 没有 download 或 target。关于 target 的更多内容,请参阅在新标签页中打开链接。

常见错误

  • 链接里套按钮,或按钮里套链接。 不合法的 HTML,行为无法预测。
  • 用 <button onclick="location.href=..."> 做普通跳转。 无法在新标签页打开,无法复制链接,也无法被抓取。
  • 在跳转用的链接上加 role="button"。 它告诉屏幕阅读器用户这里有个按钮,结果页面却跳转了。保持它是链接。
  • 把链接做成按钮样式来执行操作,比如用 href="#" 做“删除”或“打开菜单”。如果没有页面要加载,就用 <button type="button">。
  • <a disabled>。 链接上根本没有这个属性。删掉 href。
  • 忘了写 display: inline-block,导致垂直内边距与上下行文字重叠。

常见问题

在 HTML 中如何做一个链接到其他页面的按钮?

使用链接,并把它设置成按钮的样式:<a href="/signup" class="btn">Sign up</a>,再用 CSS 设置内边距、背景、圆角和 text-decoration: none。它看起来像按钮,行为上则是链接,而它本来就是链接。

可以把按钮放在 a 标签里面吗?

不可以。HTML 标准不允许在 <a> 里面放 <button> 这类交互内容。各个浏览器的处理方式不同,键盘用户会在一个控件上遇到两个 Tab 停留点,屏幕阅读器的播报也会让人困惑。只用一个元素。

button 有 href 属性吗?

没有。<button> 没有 href。要让浏览器跳转到某个 URL,使用 <a href>,或者把按钮放进带有 action 的 <form> 中(按钮上的 formaction 属性可以覆盖它)。

在按钮上用 onclick 加 location.href 不好吗?

能用,但读者会失去链接带来的一切:用中键点击或 Ctrl+点击在新标签页打开、复制链接地址、悬停时预览 URL,搜索引擎也不会把它当作链接来抓取。目标是 URL 时,请使用 <a>。

如何禁用一个看起来像按钮的链接?

链接没有 disabled 属性。删掉 href,让它不再是链接,加上 aria-disabled="true",并设置成禁用的样式。需要它重新可用时,再把 href 加回来。

Coddy 编程语言插图

和 Coddy 一起学编程

开始