链接不是button,div和span更不是

456 阅读7分钟

原文:Links are not buttons. Neither are DIVs and SPANs

作者:Karl Groves

先看看下图:这是什么?

伪按钮

你可能会立马想到按钮。然而,我们在测试中看到了很多使用 Image 或 CSS 样式来触发某种动作的实例。以下是一些标记示例:

<a href="#"><img src="path/to/image.gif" /></a>

<span class="btn_addnew"></span>

<a class="btn_addnew"></a>

<a href="javascript:myFunc();"><img src="path/to/image.gif" /></a>

按钮注意事项

在上面列出的每种情况下,标记都是不合适的,并且会产生不必要的可访问性问题。对于按钮,我们需要牢记以下可访问性注意事项:

  1. 设备独立性: 用户不必使用任何特定设备来操作控件。换句话说,用户必须能够专注于它并使用键盘或语音命令以及鼠标来激活它;

  2. 颜色对比度: 按钮的设计必须有足够的颜色对比度,在高对比度模式下按钮不能消失;

  3. 名称、状态、角色、值: 按钮必须使用适当的名称、状态、角色和值来准确地向可访问性 API 公开自己的对象是什么。正如我在另一篇博文中所描述的

    1. 名字——类似于一个人的唯一名字,这个东西叫什么名字?
    2. 状态——这东西在做什么?隐含地,它还能做什么?
    3. 角色——这个东西是什么类型的对象?
    4. 价值——这东西的值是什么?(通常只有表单元素有值)

DIV 和 SPAN 不是按钮

首先要注意的是,SPAN永远不应该用作按钮。“仅公开 HTML 核心属性的元素由基本 HTMLElement 接口表示。”

interface HTMLElement : Element {            
    attribute DOMString       id;            
    attribute DOMString       title;            
    attribute DOMString       lang;            
    attribute DOMString       dir;            
    attribute DOMString       className; 
};

此外,您也不应该使用DIV。它的 DOM 接口与 SPAN 相同,只是它添加了一个新属性 “align”,该属性已被弃用。

interface HTMLDivElement : HTMLElement {            
    attribute DOMString       align; 
};

然而,这里是 BUTTON 元素的 DOM 接口:

interface HTMLButtonElement : HTMLElement {   
    readonly  attribute HTMLFormElement form;
    attribute DOMString                 accessKey;//激活元素快捷键配置
    attribute boolean                   disabled; // 状态,是否禁用按钮
    attribute DOMString                 name;     //按钮名称
    attribute long                      tabIndex;
    readonly  attribute DOMString       type;     //按钮类型    
    attribute DOMString                 value;    //按钮的值
};

这是 A 元素的接口:

interface HTMLAnchorElement : HTMLElement {            
    attribute DOMString       accessKey;            
    attribute DOMString       charset;            
    attribute DOMString       coords;            
    attribute DOMString       href;            
    attribute DOMString       hreflang;            
    attribute DOMString       name;            
    attribute DOMString       rel;            
    attribute DOMString       rev;            
    attribute DOMString       shape;            
    attribute long            tabIndex;            
    attribute DOMString       target;            
    attribute DOMString       type;   
    void                      blur();   
    void                      focus(); 
};

(以上DOM接口说明来自:w3.org)

您应该注意到一些非常重要的新属性:“tabIndex”、“accessKey”,还有 BUTTON的“value”。

在这里我们将跳过对accessKey 属性的讨论,除了提到根据 HTML 规范,accesskey 和 tabIndex 属性对其有效的项是链接、按钮和表单字段。

换句话说:在标签顺序中本机可用的项目,因此能够以独立于设备的方式访问。您应该注意到 DIV 或 SPAN 没有此类属性。

使用我们上面的注意事项列表,让我们将 DIV & SPAN 与 A & BUTTON 进行比较:

  • 本机键盘可访问

DIV & SPAN:不可以

A & BUTTON:可以,(对于 A,仅当存在 href 时)

  • 足够的色彩对比

DIV & SPAN:依赖设计

A & BUTTON:依赖设计(除非使用没有 CSS 的原生 BUTTON)

  • 公开适当的名称、状态、角色、值

DIV & SPAN:没有

A & BUTTON:有

一些读者可能会注意到,您可以使用WAI-ARIA(无障碍网页应用)操作 DIV 和 SPAN 上的名称、状态、角色和值。此外,WAI-ARIA 规范的作者表示:当宿主语言为该类型的对象(源代码)提供语义元素时,使用样式和脚本创建对象是不合适的。

按钮显然是存在语义元素的事物之一。WAI-ARIA 最适合那些无法通过其他方式实现目标的情况。换句话说,WAI-ARIA 非常适合三态复选框和日期选择器,但对于按钮来说简直是愚蠢的。简而言之,DIV 和SPAN 不是按钮(或链接)。如果你这样用了,那你就错了。

如何在链接和按钮之间进行选择

现在我们只剩下链接和按钮了。我们如何在两者之间进行选择?很简单,通过回答一个问题:当用户激活这个控件时会发生什么?Microsoft 用户界面交互指南关于按钮链接的讨论很好地概述了这个决策过程(在此解释):

  1. 是否会使用此控件来启动即时操作?
  2. 是导航到另一个页面的操作吗?

此外,他们概述了一些关于做出选择的一般准则:

  • 使用命令按钮:

    • 主要命令。
    • 显示用于收集输入或做出选择的窗口,即使它们是辅助命令。
    • 破坏性或不可逆转的行为,以及向导和页面流中的承诺。
  • 使用链接:

    • 导航到另一个页面、窗口或帮助主题;
    • 显示定义;
    • 命令菜单。

无论您是 Windows、Mac 还是 Linux 用户,这些 UI 范例实际上是跨所有操作系统中链接和按钮控件的标准。

  • 一个按钮会启动一个即时操作,例如表单提交。
  • 链接触发导航到不同的资源。

带有糟糕(或缺失)href 的链接不是按钮

我一天至少会看到一次这样的情况:

1. <a class="btn_addnew"></a>
2. <a ><img src="path/to/image.gif" /></a>
3. <a href="#"></a>
4. <a href="#">Some button text</a>

在第一种情况下,我经常看到类似这些带有动图背景的控件,使控件具有按钮的视觉效果。在这种情况下,该项目既不是按钮也不是链接。因为这个项目缺少一个 href 属性,所以它是一个“锚”,而不是一个链接。作为锚,它就不是键盘可聚焦的。此外,由于使用了动图,该项目没有图像的替代文本,因此没有“名称”。对于高对比度模式下的低视力用户,图像会消失。对于语音听写用户,他们将无法在该控件上使用链接或按钮命令。从可访问性的角度来看,这个项目可能根本不存在,这里使用 A 并不比 SPAN 好。

近来,第二个例子越来越少,被 3 或 4 的一些变化所取代。在每一种情况下,这些对象都只比第一个例子好一点。在第一个示例中,缺少 href 属性意味着该项目无法通过键盘获得焦点。在这些示例中,我们看到了href=”#”的使用。开发人员经常使用井号来建立一个(他们认为)什么都不做的链接。问题是他们在很多方面都是错误的。

根据规范,“#”是“片段标识符分隔符”。换句话说,“#”意味着在一个文本字符串之前,该字符串标识页面上的一个片段——一个命名的锚点或一个对象的特定 ID。开发人员认为没有标识符意味着什么都没有,不幸的是他们是 100% 正确的。在某些浏览器/操作系统组合中,这也可能意味着焦点转移到其他地方。例如,在某些情况下,它具有指向浏览器窗口或正文元素的明显效果。从那里标签顺序从头开始。

想象一下这种情况:您编写了一个伪按钮,该按钮通过多个步骤在类似向导的过程中导航,每个步骤都使用<a href=”#”>链接。每次键盘用户完成一个步骤时,他们都需要从页面的最顶部重新开始,然后跳到下一步。

也许使用链接(span 或 div)作为按钮最让我困惑的是,没有任何明智的理由支持这种做法。BUTTON 元素可以像链接、div 和 span 一样设置样式,无论您选择这些元素中的哪一个,您仍然需要将相关事件绑定到您的控件。因此,如果它看起来像一个按钮并且行为像一个按钮,那么有什么令人信服的理由不只使用一个按钮呢?

小结

  1. DIV 和 SPAN 不是按钮
  2. 如果它导航,它是一个链接。使用具有有效超文本引用的链接标记
  3. 如果它触发一个动作,它就是一个按钮。使用BUTTON元素
  4. 如果您不喜欢按钮的外观,请使用 CSS 设置样式。