来自读者 Don Wilson 的有趣问题
我很想知道你的看法。 我们应该何时使用锚点标签,何时应该使用其他东西?
我通常在想要某些内容可点击时随意使用 `a` 标签。 我查阅了定义,似乎我在不应使用 `a` 标签的地方使用了它。 我浏览了 Gmail 的源代码,他们大多数的可点击内容都使用 `div` 元素。
我认为我的用法源于在 JavaScript 尚未广泛用于事件之前编写 HTML 的经历。 无论如何,我现在不确定在哪里应该为 `a` 标签划定界限。 你的看法是什么?
我认为,如果你要为锚点添加一个 href
属性,即使 JavaScript 被禁用,该属性也能实际执行某些操作,那么锚点就是正确的选择。 如果应用程序完全依赖 JavaScript,所有行为都通过 JavaScript 附加,我想你使用什么元素并不重要。 也许不使用锚点甚至更好,因为行为可能与锚点链接的行为毫无相似之处。 不过,你可能可以让我改变主意。 问题是,锚点为你(“免费”)提供了许多你想要的视觉功能,并且具有广泛的浏览器支持。 所以……
如果你选择不将锚点链接用于可点击的功能元素,那么
- 使用 `cursor: pointer;`,以便用户获得他们习惯的可点击光标。
- 在元素上使用 `tabindex` 属性,以便键盘用户可以切换到它。
- 定义
:hover
、:active
和:focus
样式。
我认为按钮元素最适合 JavaScript 交互。 它们相当可定制,你甚至可以使它们看起来像链接。
我唯一的问题是,除了锚点或按钮之外,其他元素无法通过键盘聚焦。 `tabindex` 属性并不是很好,因为你必须提供一个值,因此如果你想让页面按预期方式运行,基本上必须为每个可聚焦元素添加 `tabindex` 属性。
最好有一个类似于“可聚焦”的属性,或者让 `tabindex` 在没有特定值的情况下也能工作。 这将防止人们做诸如
<a href="#">点击我</a>
或甚至<a href="javascript:void(0)">点击我</a>
之类的事情。 不过,如果你可以,请使用按钮元素,因为这最符合逻辑。抱歉,在我添加自己的评论之前没有完整阅读你的评论。 你已经指出了这一点,可聚焦性。
关于:“你必须提供一个值,因此你基本上必须为每个可聚焦元素添加 `tabindex` 属性”
这并不是它的工作方式。 `tabindex=”0″` 等同于未指定属性/值对,但它用于将元素引入选项卡索引中。 因此,无需更改选项卡顺序(无论如何这非常不可取)即可将元素引入选项卡索引。
@mark 关于 `tabindex=”0″` 的绝佳提示!
此讨论鼓励我更仔细地考虑我在哪里使用锚点标签。
@Mark:IE8 中似乎存在一个与 `tabindex="0"` 相关的错误。 具有此属性的任何元素都会立即获得焦点。
http://fiddle.jshell.net/TdeZc/1/show/light/
可访问性
如果你关注 WCAG 可访问性标准,你可能需要考虑用 或 标签替换锚点标签。
没有 `href` 属性或 `href` 属性值为哈希且不指向页面上具有该 `id` 属性的元素的 标签将被 CodeSniffer 等可访问性审核工具标记。
屏幕阅读器依赖于许多标准和实践,这些标准和实践已开始随着 XHTML 和严格 HTML 而逐渐被淘汰。
现代浏览器只需要很少的代码就能正确渲染页面。 当我看到人们省略标签时,我仍然会感到不寒而栗。 我不希望看到/听到开发人员网站在辅助功能模式或使用屏幕阅读器时的状态。
锚点是可聚焦的,这就是即使“所有行为都通过 JavaScript 附加”时,它们仍然被使用的原因。
不可能!世界真小!
在非链接上使用 DIV 或 SPAN 很棒,因为你无需在 onclick 中阻止默认行为。
怎么样老式的
<button>
? 内置悬停(可能仅限于 Win)、焦点和活动状态,并且无需 `tab-index`。我几乎只在表单提交时使用它。
我更喜欢使用锚点,因为你可以将不同的状态设为书签(例如,sitename#about、sitename#portfolio),而如果你使用 div 来实现这一点,则无法做到。
锚点标签在语义上也更佳,并且在代码中比 div 更易于识别。
我完全反对为所有可点击元素将光标设置为“pointer”。
在我看来,WebApp 更像是一个“应用程序”,而不是一个“网站”,因此只有实际的链接才应该具有“pointer”,而所有其他操作/按钮则应具有“default”。
而且看起来也更简洁 :-)
我更喜欢在按钮和所有可点击元素上使用“cursor: pointer;”,仅仅因为我习惯了它。 当你点击它时,它让我感觉它确实会执行某些操作。 :)
我始终使用锚点标签,因为某些 IE 版本(令人惊讶!)不支持 div 元素的 :hover。
除非是专门用于导航到另一个页面,否则我避免使用锚点。 即使那样,我通常也会在点击事件周围包装 JavaScript,因为 iPad 在全屏模式下存在一些怪异现象。
我的普通“可点击但可能触发某些事件而不是导航”html 通常如下所示
<span class=”clickable” data-target-id=”someIdentifier”>一些描述性文本<span>
…我将样式应用于 .clickable 以使其在视觉上看起来像链接。 我不喜欢在需要可点击元素的所有地方都处理 `e.preventDefault();`。 在这种情况下,我的预期论点是“如果他们关闭了 JavaScript 会发生什么?”。 没什么。 太糟糕了。 打开 JavaScript。 我不会编写大量碎片化的页面来处理在对话框、弹出窗口等中更好地处理的功能。 我在项目中始终如一地使用相同的类名,因此最困难的部分是打开以前的项目并复制我常用的类。
也就是说,我编写的不是 Web“网站”,而是应用程序,以及许多需要在很短时间内处于可演示状态的原型……也许如果我编写的是面向更广泛用户的网站,我会感觉不同。
我说锚点。 JavaScript 密集型应用程序不应具有适当的非 JavaScript 后备方案吗? 使用锚点可以实现这一点(假设你没有忽略你的 `href`),而使用 div 则无法实现。
同意这一点。
当 JavaScript 被关闭时,至少应该添加一些基本功能。
我本来打算写一篇关于后备方案的评论,但我最终可能会同意 Jesse 的观点。
是的,如果你使用的是
<a href="">
,它必须指向一个真实的内容。由于JS可以被关闭或被代理/防火墙/广告拦截器阻止,或者由于某些网络错误而失败,用户可以在新窗口或标签页中打开链接,复制地址并执行他或她可以使用链接执行的所有其他操作。如果你使用按钮,最好使用表单来使其在没有JS的情况下也能工作,只要有可能。关于“如果JavaScript被关闭会怎样”的论点,我相信这对网站来说是一个有效的论点。在这种情况下,应该使用锚点,并且在JavaScript关闭时应该导航到某个有用的位置。
但我想我们已经到了可以这样说的地步:对于Web应用程序来说,JavaScript必须开启,如果它被关闭,应用程序将无法工作。因此,我认为依赖JavaScript执行操作或导航到某个位置没有错。
我同意可聚焦的论点。我们不能为所有内容添加tabindex。每次向页面添加元素时,都需要重新索引。一个可聚焦属性将非常棒!目前,在我想让用户能够使用Tab键的地方,我将使用锚点。如果我不需要用户能够在那里使用Tab键(因为我正在实现另一种使用键盘激活元素的方法),那么我将考虑使用div等。
在我目前正在开发的仅限JavaScript的Web应用程序中,我到处都使用带有
href="#name_of_the_action"
的锚点,在某些情况下,我甚至通过JavaScript解析href属性来确定要调用的函数。但就在几天前,我考虑用按钮替换所有这些东西。这次讨论证实了我的计划。
我赞成使用锚点进行切换事件,并且我的团队中层和底层的开发者似乎更喜欢使用表单元素。我完全不明白这一点,也没有得到令人满意的答复。从这篇文章来看,锚点似乎仍然是最合适的解决方案。实际上,按钮也可能是该项目的一个合适选项。我明天会提议一下。无论如何,它仍然不是表单,而且样式更简单,并且比带有大量隐藏输入的表单更有语义。
我建议在页面内操作的<a>标签应定义为当前页面中的链接(或锚点)。例如,设置HTML代码
以及JavaScript
然后我们可以在鼠标悬停在锚点上时看到状态栏中的一些友好信息,并且我们也可以同时使用锚点样式。
此外,我还相当开放地使用<button>标签来表示“可点击”。但是样式是个问题。
<div>标签没有其他语义含义。这合适吗?
我认为这完全取决于后续的行为……从语义的角度来看,只有在确实附加了超链接时,我才会使用锚点标签。因此,如果发生了页面重新加载或类似情况,我完全会选择它,否则你仍然可以使用span元素。
首先,Chris,感谢你回复我的问题。看到你的回复以及关于这个主题的精彩讨论,这是一次很棒的体验。
在我的应用程序中,我肯定已经诉诸于某些功能,如果JavaScript未启用,则这些功能将无法工作。因此,我发现自己自然地将“垃圾”放入
href
属性中(例如href='#'
或href='javascript:void(0)'
)。然后,当我阅读a
标签的定义时,这些用例似乎完全没有语义。我认为Chris的建议确实很有道理。改变我的做事方式很有趣。我有一个无序列表,它只包含一个锚点标签,每个
li
元素中都有href='javascript:void(0)
,并且被设置为display:block
。我将其更改为li
元素本身可点击。实际上,它变得简单多了。我是不是遗漏了什么?你如何使li可点击?我以为每个元素都可以点击 :)
问题是,默认情况下,只有锚元素具有用户识别和浏览器遵循的独特可点击外观和行为。
否则,只需要一小段JS代码。
还有一件事。你需要养成提供渐进增强,网站或Web应用程序的习惯,这是一种良好的编程技巧。
这样,我的意思是仅仅使用裸露的li元素是不正确的。
抱歉,我的意思是可聚焦,而不是可点击。
我完全支持渐进增强/优雅降级,我总是考虑这一点。但是,在JavaScript主题上,我认为某些网站/Web应用程序需要启用它是一个完全有效的论点。例如,Facebook要求启用它,除非你使用其网站的移动版本。
我认为真相介于两者之间,关于用户是否需要JS支持。
如果名称足够大,它可以决定条件并忘记一些抱怨者。但我认为这种立场是有害的。
根据我的经验,Google做出了正确的选择,从基础开始,然后为那些愿意体验完整界面的用户提供漂亮和增强的功能。
如果你选择使用通常不具有交互性的元素(
div
、span
等),请记住在元素上设置适当的角色(例如,role="link"
、role="button"
或更通用的role="command"
等),以便辅助功能软件知道你在做什么。说得对。点赞。
Google页面速度文档指出,你应该“避免对IE客户端的非链接元素使用:hover伪选择器”。
http://code.google.com/speed/page-speed/docs/rendering.html
另一方面,Gmail正在使用div!
但我仍然更喜欢锚点标签。
我认为这是因为其他标签上的:hover在IE6-中不起作用。
锚点=www世界虫洞。连接本地或远程HTML网页空间中的两个点。即使在JS不可用时。
否则,我同意Chris和Google的观点。如果我们谈论的是Web应用程序,任何可点击的元素及其母元素都可以:input、button、div、span等。
不过我必须说我们谈论的是渐进增强。一些Web应用程序,例如Google翻译、Gmail,即使没有JS也能工作。
绝对使用<button>,因为它表示“这将调用一个操作”。链接(<a>)表示“这是一个超链接。它将带你到另一个页面/资源”。
不要根据其默认样式选择元素。这与(例如)使用<h2>作为顶级标题没有什么不同,因为“当我使用<h1>时字体太大”。如果这是你想要的,你可以很容易地使按钮看起来像链接。
如果你*必须*使用错误的元素,至少要给屏幕阅读器提供一些帮助,并添加
role="button"
,就像TJ Crowder提到的那样。请参阅YUI Theater的此视频:常见的辅助功能错误
摘录自14:50
“当我有一个链接时,链接会说“我将转到一个新页面。”;因此它会告诉我那个页面在哪里。”
我不确定这一点。这里有一些需要注意的细微差别。
<a>元素是他所说的链接,但链接的含义更多:<area>、<link>。
并且<a>作为交互式内容元素,可以指向同一页面上的资源。
规范摘录
“链接是一个概念性结构,由a、area和link元素创建[…]
HTML中有两种链接
指向外部资源的链接[…]
超链接[…]
如果a元素具有href属性,则它表示超链接(超文本锚点)。
如果a元素没有href属性,则该元素表示链接可能放置在其他位置的占位符,如果它相关的话。[…]
如果某个站点在每个页面上都使用一致的导航工具栏,则通常链接到页面本身的链接可以使用a元素进行标记
<li> <a>示例</a> </li>
”
注意缺少的 href 属性。
是的,有一些细微差别——比如链接跳转到同一页面上的其他位置(即页面内导航)。
没有任何细微差别会改变链接或按钮的基本性质
— 链接是“跳转到某个位置”的界面
— 按钮是“执行某个操作”的界面
– 链接是“跳转到某个位置”或“跳转到某个位置并获取某些内容”。
否则,你说的确实是正确的。
div:hover 在 IE6 上是否有效?
它不起作用。
精彩的讨论,各位!
以下是 Ryan Fitzer 的更多想法:http://ryanfitzer.org/2011/08/to-be-or-not-to-be-an-anchor/
我过去常常过度使用锚点,试图在并非真正链接到任何位置的元素上从 ie6 获取 :hover 支持。
现在我不必再担心 ie6 了,我再也不会这么做了。
<command> 标签怎么样?它并非所有浏览器都支持,但也许它将是解决此问题的不错方案。
我更倾向于使用锚点标签,因为某些浏览器对 div 标签上的事件表现出不同的行为。
好的,
我看到很多有效的观点,但是当你构建 HTML/JS 音频播放器与 Flash 音频播放器时,你会怎么做?例如,我目前正在为一个客户的 Web 应用程序开发一个 UI,其中一个页面有一个音频播放器元素,用于播放语音邮件。它具有播放/暂停按钮、上一条消息和下一条消息按钮,以及消息已用/总时间显示。它还有一个用于搜索特定消息的搜索字段。
我目前正在使用此代码进行标记,但对我来说,它感觉不太对,而且 <button> 标签也存在盒子模型问题。
我更改了几次标记,最初使用 <a> 标签,然后是 <div> 标签,最后在进行更多搜索并阅读了一些文章/帖子后,我最终选择了 <button>。
我最好怎么做,因为对我来说,在我的脑海中,关于哪种是正确的方法一直存在着持续的斗争。由于我们客户的目标用户群是 MD,因此可访问性问题不太突出。