如何在HTML中创建可访问的按钮
#html #网络开发人员 #a11y

可访问性总是很重要的,但是最近它获得了更多的吸引力,如果您不知道如何创建可访问的网站,那么您真的可以称自己为良好的前端开发人员。我知道,这是一个大胆的声明,但这是对的,只是处理它。

今天,我们将研究任何网站的最基本元素之一 - 一个按钮。如何使其访问?毫无疑问 - 让我们跳入它。

首先 - 使用button标签。为什么?为什么不例如div?在这里,您有一些原因button标签是更好的选择:

  1. 这在语义上是正确的。语义html确实很重要,它有助于代码可读性,还可以帮助网络爬虫更好地了解我们的网站。
  2. 默认情况下是可集中的和可单击的。您不需要实现这些行为(但是,如果您使用某些为每个元素重置样式的CSS框架 - 请记住,请记住实现hoverfocus状态)
  3. 屏幕阅读器可以识别。使用任何屏幕读取器时,它将宣布button标签为按钮。

是吗?那太好了,不会吗?
但是,不,我们需要谈论的下一件事是按钮内容。在这里,我们可以走三种方法:

  1. 文字
  2. 图标 +文本
  3. 只有图标

文本按钮

在这种情况下,我们能做的最好的事情就是使用自我解释的文本。我们不需要放置任何其他属性以使这种按钮可访问。
在某些情况下,您可能会很想使用aria-label来覆盖按钮上的文本。我强烈建议您不要这样做 - 它违反了WCAG原则之一。

注意:您可以在此处查看我在本文中使用的所有代码:Codepen

<html lang="en">
  <body>
    <button>This is a test button</button>

    <!-- incorrect -->
    <button aria-label="This is a different button">This is another button</button>
  </body>
</html>

带有文本按钮的图标

第二种情况 - 带有文本的图标也很简单。实际上,我们可以使用与简单文本相同的技术,但是还有一件事 - 我们需要为svg图标添加aria-hidden=true属性。这样,屏幕读取器将忽略图标并仅读取文本。

也值得做的一件事是添加focusable=false属性,因为某些旧浏览器由于某种原因将重点放在svg上。

<button>
    <svg class="svg-icon" viewBox="0 0 20 20" aria-hidden="true" focusable="false">
        <title>The icon</title>     
        <path d="M9.719,17.073l-6.562-6.51c-0.27-0.268-0.504-0.567-0.696-0.888C1.385,7.89,1.67,5.613,3.155,4.14c0.864-0.856,2.012-1.329,3.233-1.329c1.924,0,3.115,1.12,3.612,1.752c0.499-0.634,1.689-1.752,3.612-1.752c1.221,0,2.369,0.472,3.233,1.329c1.484,1.473,1.771,3.75,0.693,5.537c-0.19,0.32-0.425,0.618-0.695,0.887l-6.562,6.51C10.125,17.229,9.875,17.229,9.719,17.073 M6.388,3.61C5.379,3.61,4.431,4,3.717,4.707C2.495,5.92,2.259,7.794,3.145,9.265c0.158,0.265,0.351,0.51,0.574,0.731L10,16.228l6.281-6.232c0.224-0.221,0.416-0.466,0.573-0.729c0.887-1.472,0.651-3.346-0.571-4.56C15.57,4,14.621,3.61,13.612,3.61c-1.43,0-2.639,0.786-3.268,1.863c-0.154,0.264-0.536,0.264-0.69,0C9.029,4.397,7.82,3.61,6.388,3.61"></path>
    </svg>
  Button with icon
</button>

图标按钮

第三种情况 - 仅图标按钮也很简单。我们可以在button标签上使用aria-label,屏幕读取器将忽略按钮内部的所有内容(因此,在这种情况下 - 图标)。我们甚至不需要在图标上添加aria-hidden=true

<button aria-label="Like">
    <svg class="svg-icon" viewBox="0 0 20 20" focusable="false" width="40px">
        <title>The icon</title>     
        <path d="M9.719,17.073l-6.562-6.51c-0.27-0.268-0.504-0.567-0.696-0.888C1.385,7.89,1.67,5.613,3.155,4.14c0.864-0.856,2.012-1.329,3.233-1.329c1.924,0,3.115,1.12,3.612,1.752c0.499-0.634,1.689-1.752,3.612-1.752c1.221,0,2.369,0.472,3.233,1.329c1.484,1.473,1.771,3.75,0.693,5.537c-0.19,0.32-0.425,0.618-0.695,0.887l-6.562,6.51C10.125,17.229,9.875,17.229,9.719,17.073 M6.388,3.61C5.379,3.61,4.431,4,3.717,4.707C2.495,5.92,2.259,7.794,3.145,9.265c0.158,0.265,0.351,0.51,0.574,0.731L10,16.228l6.281-6.232c0.224-0.221,0.416-0.466,0.573-0.729c0.887-1.472,0.651-3.346-0.571-4.56C15.57,4,14.621,3.61,13.612,3.61c-1.43,0-2.639,0.786-3.268,1.863c-0.154,0.264-0.536,0.264-0.69,0C9.029,4.397,7.82,3.61,6.388,3.61"></path>
    </svg>
</button>

这绝对是最简单,最受支持的解决方案。但是有什么选择?

首先是在CSS中创建sr-onlyvisuallyhidden类,然后使用创建一个隐形标签。 tailwindcss定义sr-only类如下:

.sr-only {
    **position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
}

当您将这堂课到位时,您可以这样使用它:

<button>
    <svg class="svg-icon" viewBox="0 0 20 20" aria-hidden="true" focusable="false" width="40px">
        <title>The icon</title>     
        <path d="M9.719,17.073l-6.562-6.51c-0.27-0.268-0.504-0.567-0.696-0.888C1.385,7.89,1.67,5.613,3.155,4.14c0.864-0.856,2.012-1.329,3.233-1.329c1.924,0,3.115,1.12,3.612,1.752c0.499-0.634,1.689-1.752,3.612-1.752c1.221,0,2.369,0.472,3.233,1.329c1.484,1.473,1.771,3.75,0.693,5.537c-0.19,0.32-0.425,0.618-0.695,0.887l-6.562,6.51C10.125,17.229,9.875,17.229,9.719,17.073 M6.388,3.61C5.379,3.61,4.431,4,3.717,4.707C2.495,5.92,2.259,7.794,3.145,9.265c0.158,0.265,0.351,0.51,0.574,0.731L10,16.228l6.281-6.232c0.224-0.221,0.416-0.466,0.573-0.729c0.887-1.472,0.651-3.346-0.571-4.56C15.57,4,14.621,3.61,13.612,3.61c-1.43,0-2.639,0.786-3.268,1.863c-0.154,0.264-0.536,0.264-0.69,0C9.029,4.397,7.82,3.61,6.388,3.61"></path>
    </svg>
    <span class="sr-only">Like</span>
</button>

正如您所看到和听到的 - 它可以按预期工作(我强烈建议您尝试以配音为开启的按钮 - 它确实有助于理解我们在这里所做的事情)。

另一个解决方案更复杂。我们需要在按钮上使用aria-labelledby,然后在内部提供hidden标签。请注意,即使标签将被隐藏,labelledby属性仍然可以访问它。

看起来像这样:

<button aria-labelledby="likeBtn">
    <svg class="svg-icon" viewBox="0 0 20 20" aria-hidden="true" focusable="false" width="40px">
        <title>The icon</title>     
        <path d="M9.719,17.073l-6.562-6.51c-0.27-0.268-0.504-0.567-0.696-0.888C1.385,7.89,1.67,5.613,3.155,4.14c0.864-0.856,2.012-1.329,3.233-1.329c1.924,0,3.115,1.12,3.612,1.752c0.499-0.634,1.689-1.752,3.612-1.752c1.221,0,2.369,0.472,3.233,1.329c1.484,1.473,1.771,3.75,0.693,5.537c-0.19,0.32-0.425,0.618-0.695,0.887l-6.562,6.51C10.125,17.229,9.875,17.229,9.719,17.073 M6.388,3.61C5.379,3.61,4.431,4,3.717,4.707C2.495,5.92,2.259,7.794,3.145,9.265c0.158,0.265,0.351,0.51,0.574,0.731L10,16.228l6.281-6.232c0.224-0.221,0.416-0.466,0.573-0.729c0.887-1.472,0.651-3.346-0.571-4.56C15.57,4,14.621,3.61,13.612,3.61c-1.43,0-2.639,0.786-3.268,1.863c-0.154,0.264-0.536,0.264-0.69,0C9.029,4.397,7.82,3.61,6.388,3.61"></path>
    </svg>
    <span id="likeBtn" hidden>Like</span>
</button>

span上设置id很重要,因为这是我们如何从labelledby属性访问标签。

所有三个解决方案都相同。这就是为什么我最喜欢的只是设置aria-label,这是最简单的解决方案。

这些是您可以进行的最重要的可访问性调整,以确保按钮与屏幕读取器合作。但是,患有视觉障碍的人不使用屏幕读取器呢?在这里,我们还有另外两件事要照顾,我们将全部设定。

浆纱

首先让我们谈论尺寸。在WCAG指南中,有一个标准2.5.5-目标大小。如下所述:

指针输入目标的大小至少为44 x 44 CSS像素。

几乎没有例外,您现在可以在屏幕上看到这些例外,在这种特定情况下它们不相关。

A11Y

所以让我们确保我们的按钮实际上足够大。我不是使用像素的粉丝,我宁愿选择remsems。如果用户更改其基本字体大小,这也将有所帮助 - 该按钮仍将适当尺寸。

button {
  min-height: 3rem;
  min-width: 3rem;
}

我通常使用3rem,因为根字体大小为16px,因此3rem给了我们48px。但是,如果用户缩放到24px,则按钮将更大。

好吧,随之而来的是 - 让我们处理我今天要谈论的最后一件事 - 对比。

对比

WCAG指南说:

文本和文本图像的视觉呈现至少为4.5:1-对于AA成功标准,对于AAA标准,7:1的对比度。

这里使用的最佳工具是Webaim https://webaim.org/resources/contrastchecker/

的对比检查器

您可以将按钮颜色放在那里,您会得到文本颜色,反之亦然。简单但很棒的工具。如果我的例子说我想要一个绿色按钮。

Contrast Checker

您可以看到白色文本失败了所有条件,但黑色应该可以。如您所见,当我滚动颜色时,对比度的变化以及不同的标准正在传递。用直发黑色的对比度超过10到1。这样可以工作!

就是这样!这些就是使您的按钮可以访问的事情。我希望您喜欢它,如果您这样做 - 考虑在Twitter,Dev.to和LinkedIn上关注我,更多的前端和可访问性与内容正在途中。