覆盖默认按钮样式

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

HTML 中有各种“按钮”。您有

<button>Button</button>
<input type="button" value="Button">

此外,无论好坏,人们都喜欢将链接的样式设置为与网站上其他真实按钮的外观相匹配

<a href="#0" class="button">Button</a>

一个挑战是使所有这些元素的外观和布局完全相同。我们将通过几种方式来解决这个问题。

另一个挑战是让人们正确使用它们

这让我有点惊讶——但我经常听到它以至于对此感到担忧——越来越多的开发人员正在使用<div>作为按钮。也就是说,他们只需使用任何方便的通用、无样式的 HTML,然后根据需要对其进行构建。Andy Bell 解释了为什么真正的按钮更好

所以,<button>元素很难正确设置样式?但这并不意味着您应该将 JavaScript 事件附加到<div><a href="#">上。您看,当您使用<button>时,您可以免费获得键盘事件。您还在帮助屏幕阅读器用户,因为它会正确地宣布元素。

以下是 Andy 再次帮助您使用一段 CSS 代码来获得干净的按钮样式

查看 CodePen 上 Andy Bell (@hankchizljaw) 编写的笔 Button Pal — 一些基本的按钮样式

正是样式可能成为心理障碍

这有点可以理解。按钮很奇怪!它们具有大量的默认样式(来自“用户代理样式表”),这些样式因浏览器而异,这意味着您需要做一些工作才能使其完全符合您的要求。

看到那里所有的怪异之处了吗?

  • 没有任何样式的情况下,按钮有点小,并且具有本机的边框/边框半径/阴影效果。
  • 仅通过设置字体大小,我们就会丢失所有这些默认值,但它具有新的默认外观,即带边框和方形角、渐变背景且没有阴影。这本质上是-webkit-appearance: button;
  • 按钮有自己的字体系列,因此除非您告诉它,否则不会从级联继承。

这是 Chrome 的按钮用户代理样式表

Firefox 的行为略有不同。在上面的视频中可以看到,设置border: 0;在 Chrome 中删除了边框,但背景也删除了吗?在 Firefox 中并非如此

我之所以指出这一点,是因为我想说,我明白,按钮在浏览器中确实是奇怪的东西。再考虑十几个其他浏览器、移动设备以及我们希望将所有这些不同的元素样式设置为完全相同(参见文章开头)的想法,我对想要避免这种情况的人们有一丝同情。

参考 Normalize 总没有坏处

Normalize 做了很多工作

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Show the overflow in IE.
 * 1. Show the overflow in Edge.
 */

button,
input { /* 1 */
  overflow: visible;
}

/**
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

我有点惊讶地发现 WTF,表单? 没有涵盖按钮,仅仅是因为存在很多怪异之处。但该项目整理的表单元素更加臭名昭著地难以处理!

一种样式测试工具

我觉得答案基本上是一大块 CSS 代码。这就是 Andy 提供的,您也可能通过比平时更用力地设置按钮的样式规则来自己找到答案。

尽管如此,我还是觉得有必要制作一个小型测试机,以便您可以切换样式的开关,并在您所处的任何浏览器中查看它们是如何组合在一起的

查看 CodePen 上 Chris Coyier (@chriscoyier) 编写的笔 一致的按钮样式

无障碍性

这里最重要的一点是使用正确的原生元素,因为您可以免费获得大量功能和可访问性。但是您也应该正确设置样式!

既然我们正在讨论按钮,我将使用我们在 何时使用按钮元素 文章中使用的相同引述,该引述来自 MDN

警告:使用按钮角色标记链接时要小心。预期按钮是使用空格键触发的,而链接是使用 Enter 键触发的。换句话说,当链接用于像按钮一样工作时,仅添加role="button"是不够的。还需要添加一个键事件处理程序来侦听空格键,以便与原生按钮保持一致。

您不需要在<button>上使用role="button",因为它们已经是按钮了,但是如果您要使任何其他元素像按钮一样,则需要做更多工作来模拟其功能。

此外,不要忘记:hover:focus样式!一旦您控制了默认状态的样式,这应该不难,但您绝对需要它们!

button:hover,
button:focus {
    background: #0053ba;
}

button:focus {
    outline: 1px solid #fff;
    outline-offset: -4px;
}

button:active {
    transform: scale(0.99);
}