正如我们在 完整的指南 中提到的,您可以将 <a href="">
链接环绕在您喜欢的任何 HTML 片段周围。我们称之为“块级链接”。就像您想要链接整个内容“卡片”,因为它可以创建一个大的可点击目标。
<a href="/article/"> <!-- display: block; -->
<div class="card">
<h2>Card</h2>
<img src="..." alt="...">
<p>Content</p>
</div>
</a>
关于这一点,Adrian Roselli
对于块级链接来说,最糟糕的事情可能是将所有内容都包裹在
<a href>
中。
[...]对于屏幕阅读器用户来说,在通过 Tab 键浏览控件时会读取整个字符串。在以下示例中,第一个链接包含标题、图像(未将其声明为图像)和文本块,大约需要 25 秒才能读取,然后才将其宣布为链接。在使用 Tab 键时,您并不总是知道控件类型,直到可访问名称完整。
(示例 是一张外观非常正常的卡片,包含标题、图像和段落。)
所以不要这样做。
另一种方法是让链接保持“正常”,就像标题一样。
<div class="card">
<h2><a href="/article/">Article</a></h2>
<img src="..." alt="...">
<p>Content</p>
</div>
扩展链接的“可点击区域”以覆盖整个区域。
.card {
position: relative;
}
.card h2 a::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
这适用于可点击区域,并解决了对屏幕阅读器用户造成的影响。
但还有另一个问题会损害这两种解决方案,那就是**文本选择**。您不能只是将光标放在卡片中的某个位置并正常选择文本。单击会激活链接,等待您在链接上mouseup
才会触发。您无法像预期的那样选择文本的内部部分。它不会完全阻止选择文本的能力,但它会使操作变得笨拙且令人烦恼。
我不确定这是否容易解决。也许有一些奇特的 JavaScript 解决方案可以检测您是否已开始选择文本,然后不触发点击,但如果您单击而不拖动,则它会跳转到链接。不过,关于这一点,我有一些顾虑。
更新:查看 Heydon 的文章《卡片》中的“冗余点击事件”部分。
总而言之,我认为块级链接就是一个坏主意。但我希望被证明是错的,并看到一个真正好的实现,可以解决所有这些问题。
我们不能在第二个解决方案中使用 ::after 伪元素上的 user-select: none 来解决选择问题吗?明天试试看。
使整个块可点击,但不包含在链接中?
根据我阅读的内容,我认为屏幕阅读器不会检测到这一点。但我可能完全误解了?
刚刚尝试了 user-select:none,没有用,因为它仍然会拦截指针事件。
这是我尝试解决这个问题时最接近的结果:https://codepen.io/dougwollison/pen/poJagLJ
基本上,通过将伪元素分层到其他所有内容的后面,文本是可选择的,而卡片的任何其他部分都会触发点击,但任何装饰性内容(如文本元素内部的边框、图标(未正确设置 z-index))以及文本元素上的任何填充都会覆盖可点击的空间。
老实说,考虑到这对用户来说可能有多么不一致(例如,文本元素角落缺少文本的区域),它可能弊大于利。
然后您又回到了起点,卡片不可点击。
不会起作用,因为伪元素将在所有内容之上。user-select 属性仅控制文本选择。如果任何内容“位于”文本之上,您就无法选择它:(
::after 的 z-index 是否可以在悬停在卡片上时更改?
您可以,但是如果您在文本上强制使用 z-index,您将无法“点击”它。您只能选择它。我们希望整个卡片可点击且所有内容都可选择:(
您可以使用
aria-labelledby
和aria-describedby
的组合来创建一个可链接的元素,该元素可以快速标记为标题元素,然后通过段落进行其他描述?然后通过在
a
标签中添加draggable="false"
,它可以在 Firefox 中使文本可选择(Firefox 允许您拖动链接,从而使a
中的文本不可选择)Codepen 示例:https://codepen.io/mikeybinns/pen/LYVQEyz?editors=1100
Mikey,我在下面有一条评论讨论了在此处使用 ARIA 的风险。从本质上讲,它会覆盖真实的链接文本,模糊其余内容,并剥夺语义。最好不要在此处依赖
aria-labelledby
和aria-describedby
。块级元素出于层次结构的原因而包裹内联元素。内联元素不应包裹块级元素。CSS 使得可以将 A 链接显示为:块级,因此没有太多必要破坏层次结构。
这允许用户点击卡片上的任意位置以访问 URL,同时还允许他们选择文本
链接文本不可选择(除了从链接外部进行区域选择外),但使用“阅读更多”、“省略号”甚至不可见的链接仍然有效。
建议改进屏幕阅读器是不是有罪?关于文本选择,对于“普通”链接来说,这是一个长期存在的问题,正如您所描述的那样,它在块级链接中变得更加严重。我仍然默默地希望浏览器允许使用 Alt 键保持解决方案来禁用链接,同时我选择文本。
我不确定我是否同意块级链接是一个坏主意。尽管文本选择问题确实不理想,但在观察“普通”网络用户浏览网站时(尤其是在移动设备上),人们期望块级链接,或者至少能够点击图像、标题、描述以及附近相关的任何内容。
我认为从块级链接内部选择文本的人数非常少,我不记得我什么时候这样做过。将其与用户体验的影响进行比较,即人们点击链接图像并等待页面加载,尽管事实并非如此,因为他们不得不点击标题——或者由于每个元素都是单独的链接而导致的可访问性烦恼。
以下是我通常如何处理“块级链接”:https://codepen.io/Manoz/pen/NWqybdN
我正在使用链接标签,并像本文中那样设置伪元素的样式。
唯一变化的是,当我想让某些元素可点击(例如标签)时,我只是调整它们的 z-index。
但“文本选择”问题仍然存在。
http://inclusive-components.design/cards/
类似帖子,更多答案
我喜欢 Heydon 如何使用 JavaScript 解决文本选择问题
使用“冗余点击事件”解决方案时,我遇到了 URL 在悬停时未显示的问题。
作为用户,我习惯于查看链接将我引导到哪里。
有什么办法可以解决这个问题吗?
当您使用伪元素方法时,您不会遇到此问题,但随后——再次——您无法选择文本。
最近发现了这一点,并且对“冗余点击事件”感到非常兴奋。只有当一位同事实现它时,我才意识到这不再允许用户在新标签页中打开链接了。感觉很奇怪。我们再次放弃了它,还没有找到更好的方法。
这在我们许多无障碍性测试中都出现过。我们通过向容器添加 data-href 属性和点击处理程序来解决此问题。我们允许容器内的点击冒泡,除非它们位于实际的
<a>
元素上。这将可点击的缩略图图像视为增强功能,同时避免了与重复链接相关的无障碍性问题。如果用户正在选择文本,则可以通过检查 window.getSelection().type === “Range” 来中止导航。到目前为止,它似乎运行良好!有趣的是,我昨天刚刚构建了完全相同的设置,并且认为我真的不应该这样做。现在我感觉很糟糕,要去修复它!
我手头没有现成的例子,而且有一段时间没用这种方式做过类似的事情了,但我认为,如果将点击事件附加到“.card”上,找到其中的然后打开链接,你仍然可以选择文本。
如果你可以使用 jQuery,可以尝试类似这样的代码
(移动设备真的需要添加一个使用直引号而不是花括号的“代码”键盘!现在没时间去修复这些……)
由于此功能对用户来说仅仅是一种便利,因此即使它可能由于 JS 错误或 JS 被禁用而无法工作也没关系。那里仍然有一个可点击的元素。
但情况可能已经发生了变化,就像我说的,已经有一段时间了,自从我上次这样做以来,触摸事件已经严重改变了这些部分的工作方式。
不过,在许多使用此结构的用例中,文本选择可能是一个次要问题,这些可能都是导航元素,而且在点击链接后很可能可以获得更完整的文本(意味着一个更好的复制文本来源)?
我可能会选择第二个选项——去年有人写了一篇关于这种模式的描述,称之为“突破按钮”,我想是因为它将可点击区域从其正常位置弹出。更简单,不需要 JavaScript,完全可访问。
https://mdn.org.cn/en-US/docs/Web/CSS/user-select
user-select 可能有用?
role="presentation"
或aria-hidden
能否用于其中一个元素?旧的 timwright.org 帖子:“……role="presentation"
不会从可聚焦元素中删除内容或语义定义。这意味着你的链接、按钮和输入将保持原样,以及所有内容……”这能否通过
aria-labelledby
和aria-describedby
解决?或者我错过了什么?示例:https://codepen.io/falldowngoboone/pen/LYVdvQx。我对此真的很好奇,因为我正在准备一个关于无障碍模式的演讲。
看起来像是用于标签的好主意,但对文本选择没有太大帮助。
我已经更新了 CodePen 以反映这一点。非常有信息量。谢谢!
Ryan,这里的问题是
aria-labeledby
覆盖了链接中的所有内容。添加aria-describedby
只能稍微缓解这个问题,因为它只在暂停后才会被宣布。屏幕阅读器用户通常不会等待更多内容,并且在页面上切换标签时可能会错过这些额外的上下文。这两个属性在向用户宣布值时也会忽略任何语义。如果你的卡片有列表或副标题或任何其他具有结构或语义的内容,这些信息将不会被传达。
请记住,一些屏幕阅读器用户会通过链接使用箭头键,并且不会被此阻塞。我在对 ARIA 相关问题的回复中讨论了这一点以及其他一些挑战。