杭州网站建设:建立包容性切换按钮

2019.08.13 mf_web

198

切换按钮是一种更简单的设计模式,通常只基于一个元素。但是设计它们仍然很容易。使它们具有包容性是语言,视觉设计,标记和行为的问题。

杭州网站建设在这篇文章中,我将探讨如何制作切换按钮。与任何组件一样,没有办法解决这个问题,尤其是在不同情况下检查此类控件时。然而,肯定有很多事情要忘记做或者搞砸了,所以让我们试着避免这些。

改变国家

如果Web应用程序没有根据其用户的指示进行更改,则所得到的体验将完全不令人满意。尽管如此,并不总是能够在不使用页面刷新的情况下立即增加自己的网络文档的奢侈品。

不幸的是,在某个地方我们认为可访问的网页只是那些很少发生的网页 - 静态文档,纯粹是为了阅读而设计的。因此,我们很少努力使包含Web应用程序的更丰富,更有状态的体验。

一个流行的误解是屏幕阅读器不理解 JavaScript。这不仅是完全不真实的 - 所有主要的屏幕阅读器都会对DOM发生变化做出反应 - 但是基本的状态变化,无论是视觉还是辅助技术软件,都不一定依赖于JavaScript。

复选框和单选按钮

表单元素是交互式网页的基础,如果我们不直接使用它们,我们应该密切关注它们的行为方式。他们对状态变化的处理建立了可用性约定,我们将愚蠢地忽略它们。

可以说,该checkbox类型的开箱即用输入是一个完全可用的开/关开关。当正确的标记,它具有可访问控制的所有基本要素:它的平台和设备之间的屏幕阅读器和键盘操作,并将其传送其状态的变化(检查到未选中,而无需重建整个文档,反之亦然)。

在以下示例中,复选框用作电子邮件通知设置的切换。

<input type="checkbox" id="notify" name="notify" value="on">  <label for="notify">Notify by email</label>
复制

通过我的电子邮件控件选中复选框

屏幕阅读器软件对该控件的解释相当统一。在聚焦控件(使用Tab键移动到它)时,将会公布类似于“通过电子邮件通知,复选框,未选中”的内容。这是所有存在的标签,角色和状态信息。

选中该复选框后,大多数屏幕阅读器软件将立即通知已更改状态,“已检查”(有时也会重复标签和角色信息)。没有JavaScript,我们处理状态和屏幕阅读器软件能够反馈给用户。

屏幕阅读器不仅仅适合盲人

有些操作屏幕阅读器以帮助他们理解界面。其他人可能在视觉上阅读障碍或识字率低。甚至有些人在理解界面时几乎没有身体或认知上的困难,他们有时更愿意将它读出来。

支持屏幕阅读器软件是支持屏幕阅读器软件,而不是盲人。屏幕阅读器是很多不同人喜欢使用的工具。

在这种情况下,开关的开/关部分不通过标签而是通过状态进行通信。相反,标签用于识别我们正在关闭或打开的东西。如果研究表明用户可以从更明确的开/关比喻中受益,则可以使用单选按钮组。

<fieldset>  
  <legend>Notify by email</legend>
  <input type="radio" id="notify-on" name="notify" value="on" checked>
  <label for="notify-on">on</label>
  <input type="radio" id="notify-off" name="notify" value="off">
  <label for="notify-off">off</label></fieldset>
复制

字段集,通过电子邮件组标签(图例)和标记为打开和关闭的单选按钮进行通知。 选择一个。

组标签是一个强大的工具。顾名思义,他们可以为相关(分组)项目提供单一标签。在这种情况下,<fieldset>group元素与元素一起工作,<legend>以向一对单选按钮提供组标签“通过电子邮件通知”。这些按钮通过共享name属性值成对,这使得可以使用箭头键在它们之间切换。HTML语义不只是添加信息,还会影响行为。

在Windows屏幕阅读器JAWS和NVDA中,当用户聚焦第一个控件时,组标签将添加到该控件的单个标签之前,并枚举分组的单选按钮。在NVDA中,附加术语“分组”以使事情更明确。在上面的例子中,聚焦第一个(默认选中)单选按钮引出“通过电子邮件通知,分组,单选按钮,选中,两个中的一个”。

现在,即使检查状态(在一些屏幕阅读器中宣布为“已选择”)仍在切换,我们真正允许用户在“开”和“关”之间切换。对于复合控制,这些是两种可能的词法状态,如果你愿意的话。

样式表单元素

众所周知,表单元素很难设计,但有一些支持CSS的技术可用于样式化收音机和复选框控件,正如我在“ 更换单选按钮而无需替换单选按钮”中所写的那样。有关如何设置选择元素和文件输入样式的提示,请参阅WTF Forms?马克奥托。

这感觉不太对劲

复选框和单选按钮实现都可以作为开/关控件。毕竟,它们可通过不同设备,浏览器和操作系统上的鼠标,触摸,键盘和辅助技术软件访问。

但可访问性只是包容性设计的一部分。这些控件也必须对用户有意义 ; 他们必须在界面中发挥明确的作用。

使用表单元素的麻烦在于它们与数据集合的长期关联。也就是说,复选框和单选按钮被建立为用于指定值的控件。当用户选中复选框时,他们可能只是在切换状态,但他们可能怀疑他们也在选择提交值。

无论您是看到复选框的视力正常的用户,听取其身份宣布的屏幕阅读器用户,还是两者,其词源都是有问题的。我们希望切换按钮成为按钮,但复选框和单选按钮确实是输入。

一个真正的切换按钮

有时我们使用<button>元素来提交表单。为了完全兼容和可靠,这些按钮应该type取值submit。

<button type="submit">Send</button>
复制

但这些只是一种按钮,涵盖一个用例。事实上,<button>元素可以用于各种事物,而不仅仅是与表单相关联。他们只是按钮。我们通过赋予它们的type价值来提醒自己button。

<button type="button">Send</button>
复制

通用按钮是您在界面内更改任何内容(使用JavaScript而无需重新加载页面)的首选元素,除了文档内部和文档之间的位置,这是链接的范围。

在链接旁边,按钮应该是您在Web应用程序中最常用的交互元素。它们预先打包了“按钮”角色,默认情况下可以访问键盘和屏幕阅读器。与某些表单元素不同,它们对于样式也很简单。

那么我们如何制作<button>一个切换按钮呢?这是一个使用WAI-ARIA作为渐进增强的案例。WAI-ARIA提供基本HTML中不可用的状态,例如按下状态。想象一下电脑的电源开关。按下 - 或按下 - 表示计算机处于“开启”状态。当它没有按下时 - 戳出 - 计算机必须关闭。

<button type="button" aria-pressed="true">  
  Notify by email</button>
复制

WAI-ARIA状态属性的aria-pressed行为类似于布尔值,但与标准的HTML状态属性不同,checked它们必须具有明确的值true或false。只是添加aria-pressed是不可靠的。此外,缺少属性意味着不会传达未压缩状态(没有属性的按钮只是一个通用按钮)。

您可以在表单内部或外部使用此控件,具体取决于您的需要。但如果您在表单中使用它,则该type="button"部分很重要。如果它不存在,某些浏览器将默认为隐式type="submit"并尝试提交表单。您没有使用event.preventDefault()上type="button"的控制来抑制表单提交。

将状态从true(on)切换到false(off)可以通过简单的单击处理程序完成。由于我们使用a <button>,因此可以通过鼠标单击,按空格键或回车键或通过触摸屏点击按钮来触发此事件类型。对这些行为中的每一个做出响应是<button>作为标准内置于元素中的内容。如果您查阅HTMLButtonElement接口,您将看到其他属性(例如disabled,)也支持开箱即用。在<button>不使用元素的情况下,必须使用定制的脚本来模拟这些行为。

const toggle = document.querySelector('[aria-pressed]');toggle.addEventListener('click', (e) => {  
  let pressed = e.target.getAttribute('aria-pressed') === 'true';
  e.target.setAttribute('aria-pressed', String(!pressed));});
复制

一个更清晰的状态

当aria-pressed某些屏幕阅读器遇到具有该状态的按钮时会发生一件有趣的事情:它被识别为“切换按钮”,或者在某些情况下,被称为“按钮”。状态属性的存在会更改按钮的标识。

当aria-pressed="true"使用NVDA 聚焦示例按钮时,屏幕阅读器会发出“通过电子邮件通知,按下切换按钮”。“按下”状态比“检查”更容易,另外我们避开表单数据输入内涵。单击该按钮时,将以“未按下”的形式提供即时反馈。

造型

我们构建的HTML是我们设计工作的重要组成部分,也是我们为Web创建的内容。我非常相信HTML First Prototyping™,确保为风格和品牌产品奠定坚实的基础。

在我们的切换按钮的情况下,该基础包括使按钮与各种输入(例如语音激活软件)和输出(例如屏幕阅读器)设备可互操作的语义和行为。这可能是使用HTML,但需要CSS才能使控件在视觉上易于理解。

表单应该遵循函数,这在CSS中很容易实现:我们的HTML中的所有内容都使我们的简单切换按钮功能也可用于表单。

  • <button>→ button元素选择器

  • aria-pressed="true"→ [aria-pressed="true"]属性选择器。

在一致且易于理解的界面中,按钮应该共享一定的外观。按钮应该看起来像按钮。因此,我们的基本切换按钮样式应该可以从button元素块继承:

/* For example... */button {  
  color: white;
  background-color: #000;
  border-radius: 0.5rem;
  padding: 1em 2em;}
复制

我们可以通过多种方式在视觉上表示“按下”。从字面上解释,我们可能会使用一些插图使按钮看起来很紧box-shadow。让我们使用一个属性选择器:

[aria-pressed="true"] {
  box-shadow: inset 0 0 0 0.15rem #000,
              inset 0.25em 0.25em 0 #fff;}
复制

为了完成按下/未按下的比喻,我们可以使用一些定位并使未按下box-shadow的按钮“戳出”。该块应出现[aria-prressed="true"]在级联块的上方。

[aria-pressed] {
  position: relative;
  top: -0.25rem;
  left: -0.25rem;
  box-shadow: 0.125em 0.125em 0 #fff,
              0.25em 0.25em #000;}
复制

左键,伸出,被标记为咏叹调按等于假。 右键,视觉上被压抑,被标记为咏叹调等于真。

(注意:这种样式方法只是一个想法。你可能会发现更明确的东西,比如在一个例子中使用“on”/“off”标签,更多用户可以更好地理解。)

不要单靠颜色

“On”通常用绿色表示,“off”用红色表示。这是一个完善的惯例,并没有任何损害。但是,请注意不要仅使用颜色来描述按钮的两种状态。如果你这样做,一些色盲用户将无法区分它们。

按下咏叹调的假按钮具有红色背景颜色,按下咏叹调的按钮具有绿色背景颜色
这些版本的控件将失败WCAG 2.0 1.4.1使用颜色(A级)

焦点风格

重要的按钮以及所有交互式组件都具有焦点样式。否则,通过键盘导航的人无法看到哪个元素在他们的控制中并准备好进行操作。

最佳焦点样式不会影响布局(在元素之间移动时,界面不应分散注意力)。通常,人们会使用outline,但outline只在大多数浏览器中绘制一个盒子。为了适应按钮弯曲角落的焦点风格,box-shadow更好。由于我们box-shadow已经在使用,我们必须要小心一点:注意两个以逗号分隔的box-shadow样式处于压缩和聚焦状态。

/* Remove the default outline and
add the outset shadow */  [aria-pressed]:focus {
  outline: none;
  box-shadow: 0 0 0 0.25rem yellow;}/* Make sure both the inset and
outset shadow are present */  [aria-pressed="true"]:focus {
  box-shadow: 0 0 0 0.25rem yellow,
              inset 0 0 0 0.15rem #000,
              inset 0.25em 0.25em 0 #fff;  }
复制

改变标签

之前的切换按钮设计具有独立的独特标签,并使用引发样式的属性更改来区分其两种状态。如果我们想要创建一个按钮,将其标签从“开”更改为“关闭”或“播放”到“暂停”,该怎么办?

在JavaScript中完成此操作非常容易,但我们需要注意一些事项。

  1. 如果标签发生变化,状态会发生什么变化?

  2. 如果标签只是“打开”或“关闭”(“播放”或“暂停”;“活动”或“非活动”),我们如何知道按钮实际控制的是什么?

在上一个切换按钮示例中,标签描述了打开或关闭的内容。在“什么”部分不一致的情况下,很快就会出现混乱:一旦“关闭”/未按下已经“开启”/按下,我必须取消按下“开启”按钮以重新打开“关闭”按钮。什么?

根据经验,您不应该一起更改按下的状态和标签。如果标签发生变化,那么按钮在某种意义上已经改变了状态,而不是通过显式的WAI-ARIA状态管理。

在以下示例中,只是标签更改。

const button = document.querySelector('button');button.addEventListener('click', (e) => {  
  let text = e.target.textContent === 'Play' ? 'Pause' : 'Play';
  e.target.textContent = text;});
复制

这种方法的问题在于标签更改不会在发生时公布。也就是说,当您单击播放按钮时,缺少等效于“按下”的反馈。相反,您必须手动取消对焦并重新对焦按钮才能听到它已更改。对于有视力的用户而言,这不是一个问题,但对于盲人屏幕阅

播放/暂停按钮通常在播放符号(侧面三角形)和暂停符号(两条垂直线)之间切换。我们可以在保持一致的非可视标签和改变状态的同时做到这一点。

<!-- Paused state -->  <button type="button" aria-pressed="false" aria-label="play">  
  &#x25b6;</button><-- Playing state -->  <button type="button" aria-pressed="true" aria-label="play">  
  &#x23f8;</button>
复制

因为aria-label覆盖了unicode符号文本节点,所以暂停按钮被宣布为类似于“播放按钮,未按下”和播放按钮,“播放按钮,按下”。

除了语音识别和激活之外,这种方法效果很好。在语音识别软件中,您通常需要通过发声标签来识别按钮。如果用户看到暂停符号,他们的第一个倾向是说“暂停”,而不是“播放”。出于这个原因,切换标签而不是状态在这里更加稳健。

三个实现示例。 第一个只是将标签从播放更改为暂停,并且没问题。 第二个保持播放标签并改变状态,这是不正确的,因为暂停按钮无法通过语音识别识别。 第三个更改标签和状态,因此按钮变为按下的暂停按钮,这是不正确的。 仅使用前两个实现中的一个。
切勿同时更改标签和状态。在此示例中,这将导致处于按下状态的暂停按钮。由于视频或音频将在此时播放,因此词汇“暂停”状态也不能被视为“按下”在“开启”上。

辅助标签

在某些情况下,我们可能想要提供实际读取“开/关”的开/关开关。这些诀窍是确保每个切换开关和相应的辅助标签之间存在明确的关联。

想象一下,电子邮件通知设置与列表中的其他类似设置一起分组。每个列表项都包含设置的描述,后跟开/关开关。开/关开关使用术语“开”和“关”作为其设计的一部分。<span>为样式提供了一些元素。

<h2>Notifications</h2>  <ul>  
  <li>
    Notify by email
    <button>
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    Notify by SMS
    <button>
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    Notify by fax
    <button>
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    Notify by smoke signal
    <button>
      <span>on</span>
      <span>off</span>
    </button>
  </li></ul>
复制

具有关联按钮的通知设置列表,可以根据状态突出显示打开或关闭

列表的优点在于,无论是视觉还是非视觉,它们将项目组合在一起,显示它们是相关的。这不仅有助于理解,而且列表还在某些屏幕阅读器中提供导航快捷方式。例如,JAWS提供L(列表)和I(列表项)快捷键,用于在列表之间移动和通过列表移动。

每个“标签”和按钮通过属于公共列表项来关联。但是,不提供明确,独特的标签是危险的领域 - 特别是在语音识别方面。使用aria-labelledby,我们可以将每个按钮与列表的文本相关联:

<h2>Notifications</h2>  <ul>  
  <li>
    <span id="notify-email">Notify by email</span>
    <button aria-labelledby="notify-email">
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    <span id="notify-sms">Notify by SMS</span>
    <button aria-labelledby="notify-sms">
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    <span id="notify-fax">Notify by fax</span>
    <button aria-labelledby="notify-fax">
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    <span id="notify-smoke">Notify by smoke signal</span>
    <button aria-labelledby="notify-smoke">
      <span>on</span>
      <span>off</span>
    </button>
  </li></ul>
复制

每个aria-labelledby值都匹配适当的范围id,形成关联并为按钮提供唯一标签。它的工作方式非常类似于标识字段的<label>元素for属性id。

转换角色

重要的是,ARIA标签会覆盖每个按钮的文本内容,这意味着我们可以再次使用它aria-pressed来传达状态。但是,由于这些按钮明确是“开/关”开关,我们可以使用WAI-ARIA开关角色,它通过状态进行通信aria-checked。

<h2>Notifications</h2>  <ul>  
  <li>
    <span id="notify-email">Notify by email</span>
    <button role="switch" aria-checked="true" aria-labelledby="notify-email">
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    <span id="notify-sms">Notify by SMS</span>
    <button role="switch" aria-checked="true" aria-labelledby="notify-sms">
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    <span id="notify-fax">Notify by fax</span>
    <button role="switch" aria-checked="false" aria-labelledby="notify-fax">
      <span>on</span>
      <span>off</span>
    </button>
  </li>
  <li>
    <span id="notify-smoke">Notify by smoke signal</span>
    <button role="switch" aria-checked="false" aria-labelledby="notify-smoke">
      <span>on</span>
      <span>off</span>
    </button>
  </li></ul>
复制

你如何设计活动状态取决于你,但我个人可以节省<span>用JavaScript 编写类属性。相反,我会使用伪类编写一些CSS来定位依赖于状态的相关跨度。

[role="switch"][aria-checked="true"] :first-child,
[role="switch"][aria-checked="false"] :last-child {
  background: #000;
  color: #fff;}
复制

遍历设置

现在让我们谈谈使用两种不同的策略浏览这个设置部分:按Tab键(仅在可聚焦元素之间跳转)和屏幕阅读器浏览(在每个元素中移动)。

即使在使用Tab键导航时,您所关注的交互元素的身份和状态也将在屏幕阅读器中公布。例如,当您对第一个进行聚焦时<button>,您会听到它是一个标记为“通过电子邮件通知” 的开关,处于打开状态。“Switch”是角色,并且aria-checked="true"在此角色存在的情况下被发声为“on”。

切换角色支持

这个switch角色并没有得到很好的支持aria-pressed。例如,Chrome的ChromeVox屏幕阅读器扩展程序无法识别它。

但是,ChromeVox 确实支持aria-checked。这意味着,而不是“宣布切换,通过电子邮件通知”,“按钮,通过电子邮件通知,已检查”。这不是令人回味的,但它足够了。更有可能的是,它只会被误认为是复选框输入。

奇怪的是,对于NVDA一个按钮,role="switch"并aria-checked="true"在其按下状态的切换按钮。由于开/关和按下/未按下是等效的,这是可以接受的(虽然有点令人失望)。

但在大多数屏幕阅读器中,您还会被告知您输入了四个项目的列表,并且您在第一个项目上 - 有用的上下文信息有点像我在本文前面介绍的组标签。

重要的是,因为我们习惯aria-labelledby将相邻文本与按钮关联作为其标签,所以在此模式下导航时也可以使用该文本。

在项目之间进行浏览时(例如,在NVDA屏幕阅读器运行时按下向下键),会公布您遇到的所有内容,包括标题(“通知,标题级别2”)。当然,以这种方式浏览“通过电子邮件通知”是单独宣布的,也是与相邻按钮相关联的。这有点重复,但有道理:“这是设置名称,这里是用于设置此名称的开/关开关。”

如何明确地将控件与其控制的内容相关联是一个更好的用户体验设计点,值得考虑。在这种情况下,我们为有视力的用户保留了我们的经典开/关开关,无论他们使用哪种键盘交互模式,都不会混淆或误导盲人或视力的屏幕阅读器用户。它非常强大。

结论

您如何设计和实现切换按钮取决于您,但我希望您在将此特定组件添加到模式库时会记住这篇文章。没有理由为什么切换按钮 - 或任何接口组件 - 应该边缘化他们经常做的人数。

杭州网站建设您可以参考这里探索的基础知识并添加各种设计细微差别,包括动画。首先打下坚实的基础是非常重要的。

清单

  • 如果您确定用户不相信他们是用于提交数据,请使用表单元素(如复选框)进行开/关切换。

  • 使用<button>的元素,而不是链接,与aria-pressed或aria-checked。

  • 不要一起更改标签和状态。

  • 使用可视“on”和“off”文本标签(或类似文件)时,您可以使用唯一标签来覆盖这些标签aria-labelledby。

  • 小心确保按钮的文本和背景颜色之间的对比度水平符合WCAG 2.0要求。



最新案例

寒枫总监

来电咨询

18868949445

微信咨询

寒枫总监

TOP