发布于 2026-01-06 2 阅读
0

CSS按钮样式指南

CSS按钮样式指南

这是我撰写的系列文章的第九篇,旨在探讨现代 CSS 解决方案如何解决我过去 13 年多前端开发工作中遇到的问题。访问ModernCSS.dev查看整个系列文章及其他资源

本指南将探讨如何为链接和按钮元素设计易于访问、可扩展的按钮外观。

涵盖的主题包括:

  • 重置a样式button
  • 显示、视觉、大小和文本样式
  • 易于接受的造型考量
  • 常见场景的扩展样式

哦,那个按钮(或者说是链接?)。从鼠标悬停延迟等待第二张图片加载的时代,到图像精灵,再到渐变效果出现之后border-radius,我一直都在与按钮作斗争,直到box-shadow它出现,我才如释重负。

但是……我们对按钮样式的重视程度过高,以至于完全忘记了按钮的真正含义,更不用说一个易于访问的按钮(或链接)了。

等等!快去读读这篇精彩的文章:《现代 Web 应用中的链接与按钮》,了解何时应该使用链接,何时应该使用a按钮。button

我们将探讨为按钮a和按钮创建视觉外观所需的属性button,以及确保按钮的创建和使用具有可访问性所需的其他细节。


重置默认样式

这是我们的基准样式——Chrome 中渲染的原生浏览器样式,目前唯一的更改是链接继承了 body 元素上设置的自定义字体,我还提高了字体大小font-size

默认链接和按钮样式

如果你在家跟着做,HTML代码是:

<a href="javascript:;">Button Link</a>
<button type="button">Real Button</button>
Enter fullscreen mode Exit fullscreen mode

我使用javascript:;字符串作为href值,这样我们就可以在不触发导航的情况下测试状态。同样地,由于此按钮并非用于表单提交,因此需要明确指定类型,button以防止触发 GET 请求和页面重新加载。

重置样式

注意:通常我会对 CodePen 应用Normalize重置,但本课我们将从零开始,学习如何重置按钮和链接。使用Normalize或其他常用的重置方法可以自动完成其中一些操作。

首先,我们将把 class 添加button到链接和按钮上,以强调本课中样式应用的位置。

<a href="javascript:;" class="button">Button Link</a>
<button type="button" class="button">Real Button</button>
Enter fullscreen mode Exit fullscreen mode

box-sizing

请确保您的样式包含以下重置 - 如果您不希望它全局生效(您应该这样做),您可以将其作用域限定在我们的按钮类中。

* {
  box-sizing: border-box;
}
Enter fullscreen mode Exit fullscreen mode

简而言之,这条规则可以防止边框和内边距等元素扩大预期的元素大小(例如,25% 的宽度仍然是 25%,而不是 25% + 边框宽度 + 内边距)。

a

对于该链接,我们只需要进行一次重置:

a.button {
  text-decoration: none;
}
Enter fullscreen mode Exit fullscreen mode

这会直接去掉下划线。

button

接下来,我们还需要遵守以下几条规则才能重置按钮:

button.button {
  border: none;
  background-color: transparent;
  font-family: inherit;
  padding: 0;
  cursor: pointer;

  @media screen and (-ms-high-contrast: active) {
    border: 2px solid currentcolor;
  }
}
Enter fullscreen mode Exit fullscreen mode

不同浏览器之间的数值也存在一些差异display,但我们很快会将其更改为统一的选项。

重置样式后,我们现在得到这样的外观:

链接和按钮的重置样式

感谢@overflowhidden提供解决方案,确保在启用 Windows 高对比度模式的情况下,用户能够看到按钮边框

显示样式

我发现,在很多情况下,效果最好的方法是,display: inline-flex它能提供 flexbox 的内容对齐功能,但又位于 DOM 的inline-block行为中。

a.button,
button.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
Enter fullscreen mode Exit fullscreen mode

如果您将来添加图标或设置宽度限制,弹性对齐方式会非常有用。

视觉样式

接下来,我们将应用一些标准视觉样式,您当然可以根据自己的喜好进行调整。这是最灵活的一组样式,您可以省略某些样式box-shadow和/或某些元素border-radius

$btnColor: #3e68ff;

a.button,
button.button {
  // ... existing styles
  background-color: $btnColor;
  color: #fff;
  border-radius: 8px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.18);
}
Enter fullscreen mode Exit fullscreen mode

现在我们的链接和按钮看起来越来越像了:

带有视觉样式的链接和按钮

按钮对比度

创建初始按钮样式时,需要考虑两个层次的对比:

  1. 按钮背景颜色与其显示背景颜色之比至少为 3:1
  2. 按钮文本与按钮背景之间至少应保持 4.5:1 的比例(对于小于 18.66 像素粗体或 24 像素的文本)或 3:1 的比例(对于大于这些尺寸的文本)。

以下是我制作的信息图,用来展示按钮颜色与其对比度之间的关系:

一张信息图展示了

假设页面背景为白色,我们的按钮颜色选择符合 4.54:1 的比例要求。

试试 ButtonBuddy,它可以帮你创建易于访问的按钮颜色。我开发的这款网页应用能帮你轻松掌控按钮调色板中的所有对比度。

尺寸

我们特意省略了“视觉”类别下的一个属性,您在查看进度截图时可能没有注意到:padding

由于padding它是其中的一部分box-model,我们将其留给了尺寸部分。

让我们先应用这些尺寸值,然后再进行讨论:

a.button,
button.button {
  // ... existing styles
  padding: 0.25em 0.75em;
  min-width: 10ch;
  min-height: 44px;
}
Enter fullscreen mode Exit fullscreen mode

我们采用padding单位制em,这是一种允许填充与应用的单位成比例调整大小的偏好font-size

接下来,我们min-width使用ch单位来设置宽度,该单位大致等于0所应用字体的字符宽度font-size。此建议旨在维护视觉节奏。设想一下,您有两个并排的按钮,一个标签较短,一个标签较长,例如“分享”和“了解更多”。如果没有设置宽度min-width,“分享”按钮的宽度会明显短于“了解更多”。

min-height是基于确保按钮在触摸设备上的目标足够大,以满足 WCAG 2.1 2.5.5 - 目标大小的成功标准。

各种风格开始融合,但我们还没有完成:

链接和按钮的尺寸样式

文本样式

根据上一张进度截图,你可能会想跳过文本样式部分。

但是,看看当我们缩小视口尺寸并触发响应式行为时会发生什么:

缩小视口内的链接和按钮

如您所见,我们有不同的对齐方式,而且line-height也可以进行调整。

我特意跳过了重置样式中的文本对齐方式调整,所以现在我们要确保两者的文本都居中。然后我们还可以减小行高——这可能需要根据所使用的字体进行调整。

a.button,
button.button {
  // ... existing styles
  text-align: center;
  line-height: 1.1;
}
Enter fullscreen mode Exit fullscreen mode

好的,看起来很棒!

带有文本样式的链接和按钮

州风格

目前,用户在尝试与按钮交互时唯一获得的视觉反馈是光标变为“指针”样式。

我们需要确保三个状态都存在。

:hover

最常受到关注的是hover,所以我们就从这里开始吧。

鼠标悬停时的典型更新之一是更改背景颜色。由于我们之前的版本已经非常接近 4.5,所以我们需要加深背景颜色。

我们可以利用 Sass,使用我们$btnColor在“视觉”部分定义的变量来计算这种颜色:

a.button,
button.button {
  // ... existing styles
  &:hover {
    background-color: scale-color($btnColor, $lightness: -20%);
  }
}
Enter fullscreen mode Exit fullscreen mode

这种效果可能有点突兀,但我们还有另一个现代 CSS 工具可以柔化它,它的名字也恰如其分地叫做 `setOver` transition。这个transition属性需要添加到hover规则之外,以便它同时适用于“over”和“out”两种情况。

a.button,
button.button {
  // ... existing styles

  transition: 220ms all ease-in-out;

  // ...&:hover
}
Enter fullscreen mode Exit fullscreen mode

悬停过渡演示

:focus

对于键盘用户,我们需要确保状态focus能够清晰区分。

默认情况下,浏览器会对获得焦点的元素应用一种“光晕”效果。一种不好的做法是直接移除outline实现该效果的属性,而没有进行相应的替换。

我们将使用自定义的焦点状态替换原有的轮廓box-shadow。与类似outlinebox-shadow它不会改变元素的整体大小,因此不会导致布局偏移。而且,由于我们已经应用了焦点状态transition,因此该自box-shadow定义焦点状态也会继承该状态,从而产生额外的醒目效果。

a.button,
button.button {
  // ... existing styles

  // ...&:hover

  &:focus {
    outline-style: solid;
    outline-color: transparent;
    box-shadow: 0 0 0 4px scale-color($btnColor, $lightness: -40%);
  }
}
Enter fullscreen mode Exit fullscreen mode

我们再次使用了该scale-color函数,这次是为了使颜色比默认颜色更深一些hover。这是因为按钮可以同时处于“开启”hover和“关闭”两种状态。focus

链接和按钮焦点演示

感谢@overflowhidden提供解决方案,确保:focus启用 Windows 高对比度模式的用户能够获得可感知的状态

:active

最后,特别是对于“真正的按钮”,最好定义一个:active状态样式。

对于链接,此效果会在点击/轻触的“按下”瞬间短暂出现。

对于按钮来说,由于可以通过空格键触发按钮,而空格键可以无限期地按住,因此按钮的显示时间可以更长。

我们将对:active现有:hover样式进行补充:

&:hover,
&:active {
  background-color: scale-color($btnColor, $lightness: -20%);
}
Enter fullscreen mode Exit fullscreen mode

风格变化

关于轮廓(“幽灵”)按钮的话题我们改天再谈,但这里我们快速补充两种变体。

小按钮

我们将使用 BEM 格式创建一个button--small类来简单地缩小字体大小。由于我们将内边距设置为 0 em,因此字体大小会按比例调整。我们的样式min-height表将确保按钮保持足够大的触摸目标。

&--small {
  font-size: 1.15rem;
}
Enter fullscreen mode Exit fullscreen mode

屏蔽按钮

有时您可能希望block按钮内容采用行为式布局而不是内联布局,因此我们将添加width: 100%此功能以允许此选项,而不是更改display属性,因为我们仍然希望按钮内容采用弹性对齐:

&--block {
  width: 100%;
}
Enter fullscreen mode Exit fullscreen mode

陷阱:Flex Columns 的子元素

如果按钮是弹性列的子元素,即使没有设置类,按钮也会扩展到全宽,这可能会让您措手不及button--block

为了应对这种情况,您可以align-self: start向基本按钮样式添加样式,或者为每个 flex/grid 对齐属性值创建实用样式:start,,centerend

演示

文章来源:https://dev.to/5t3ph/css-button-styling-guide-4cng