卡片型组件在文章列表等处经常使用。外观很简洁,但考虑到无障碍性,它具有出人意料的深层设计课题。
典型的卡片从上至下包含
- 图像
- 文章标题
- 文章摘要
- 详情链接
等纵向排列的布局实现模式。
设计时的主要考虑要点
1. 视觉顺序与 HTML 结构
屏幕阅读器基本上按照 HTML 的编写顺序进行朗读。WCAG 2.0 的成功标准 1.3.2(有意义的顺序,A 级别)认为,使视觉顺序与 HTML 顺序一致是基本原则。
不过,仅用 CSS 改变元素顺序本身并不违反 WCAG。即使视觉顺序与 HTML 源码顺序不同,只要内容仍可理解,就不存在问题。根据具体情况灵活判断很重要。
2. 图像处理方法
文章卡片中的图像在许多情况下是装饰性的。由于文章标题已经能够传达内容,所以不太需要朗读图像的描述。
当作装饰性图片处理时,仅需alt=""即可。
<img src="thumbnail.jpg" alt="">
3. 详细链接标签
应避免使用"详细了解"之类的通用文本,原因如下。
视觉问题
没有周围的上下文,无法判断这是什么链接
屏幕阅读器问题
使用链接列表功能进行列表显示时,所有项目都显示为"查看详情",无法区分
语音识别问题
当存在多个相同的文本时,需要通过编号进行选择,操作变得复杂
理想情况下,应该像"查看××的详细信息"这样,使链接单独就能清楚表达目的。不过本文介绍的是在保持"查看详细信息"这一设计不变的前提下的实现方法。
4. 卡片可点击区域
为了改善用户体验,我们经常需要使整个卡片可点击。实现方法有很多,但它们对可访问性的影响各不相同。
5. 卡片应该使用 article 还是 div
选择哪一个取决于内容的性质。
标签适用的情况:
- 卡片内容作为独立内容而独立成立
在这种情况下没有问题:
- 用作链接组的功能
- 卡片本身没有语义独立性
在通常的博客文章列表或产品列表卡片中,更为合适。但是,在使用多个的情况下,建议考虑屏幕阅读器的地标导航,并通过aria-labelledby或aria-label使每篇文章可被识别(WCAG 2.4.6,AA级)。
使用aria-labelledby时,请注意ID应为唯一值。
关于视觉顺序和HTML结构
模式1:使视觉顺序与HTML顺序一致
<article class="article-card" aria-labelledby="article-title">
<img src="thumbnail.jpg" alt="">
<h3 id="article-title"><a href="#" class="card-link">記事タイトル</a></h3>
<p>記事の概要...</p>
<a href="#" class="card-detail-link">
<span class="visually-hidden">記事タイトル:</span>詳細を見る
</a>
</article>
由于HTML的记述顺序与视觉顺序完全一致,因此简洁直观。
※ 虽然建议的首个元素为标题,但这不是绝对要求。在优先考虑视觉顺序一致性的情况下,此模式没有问题。
补充说明:
语音识别软件(Dragon、Voice Control等)根据屏幕显示的文本进行操作。使用 visually-hidden (sr-only) 可以保留视觉文本,从而实现语音识别操作。以下是链接标签处理中OK和NG模式的实现示例。
<!-- 以下は可視テキストがアクセシブルな名前に含まれているのでOK -->
<a href="#" id="link-text" class="card-detail-link" aria-labelledby="link-text article-title">
詳細を見る
</a>
<a href="#" aria-label="詳細を見る:記事タイトル">
詳細を見る
</a>
<!-- 以下は可視テキストがアクセシブルな名前に含まれていないのでNG -->
<a href="#" class="card-detail-link" aria-labelledby="article-title">
詳細を見る
</a>
<a href="#" class="card-detail-link" aria-label="記事タイトル">
詳細を見る
</a>
模式2: 使用 CSS order 调整视觉顺序
<article class="article-card" aria-labelledby="article-title">
<h3 id="article-title"><a href="#">記事タイトル</a></h3>
<p>記事の概要...</p>
<a href="#" class="card-detail-link">
<span class="visually-hidden">記事タイトル:</span>詳細を見る
</a>
<img src="thumbnail.jpg" alt="">
</article>
.article-card {
display: flex;
flex-direction: column;
}
.article-card img {
order: -1;
}
由于的第一个元素是标题,这在语义上是更加理想的结构。
对于装饰性图像(alt=""),不会影响阅读顺序(因为图像会被跳过)。
注意:
- 当图像具有含义且指定了 alt 属性时,由于视觉顺序和朗读顺序会改变,这种结构不合适。
- 由于键盘的Tab顺序遵循HTML的顺序,如果卡片内有多个可获得焦点的元素,请确保焦点顺序不会破坏逻辑流。
如果要让整个卡片都可点击
模式 3: 使用伪元素使卡片整体可点击
通过这种方法,使用标题链接的伪元素覆盖整个卡片,将"详细查看"作为视觉装饰转换为。
即使将"查看详情"保留为,并添加tabindex=\"-1\"或aria-hidden=\"true\",它也会在屏幕阅读器的链接列表和元素导航模式中产生噪音,因此我认为改用更好。
<article class="article-card" aria-labelledby="article-title">
<img src="thumbnail.jpg" alt="">
<h3 id="article-title"><a href="#" class="card-link">記事タイトル</a></h3>
<p>記事の概要...</p>
<span class="card-detail-link">詳細を見る</span>
</article>
.article-card {
position: relative;
}
.card-link::after {
content: '';
position: absolute;
inset: 0;
z-index: 1;
}
.card-link:focus-visible {
outline: none;
}
.card-link:focus-visible::after {
outline: 2px solid currentColor;
outline-offset: 2px;
}
/* カード内に複数のリンクがある場合の例 */
.article-card a:not(.card-link) {
position: relative;
z-index: 2;
}
优势:
- 保留语义结构
- 在屏幕阅读器中自然流畅地读出
- 可以在卡片内放置多个链接(如分类、标签、作者链接等)
缺点:
- 需要管理
z-index(但设置一次后就没有问题了)
模式4: 用包装整个卡片
在这种方法中,由于整个卡片都是一个链接,"查看详情"自然会成为。
<article class="article-card" aria-labelledby="article-title">
<a href="#" class="card-link">
<img src="thumbnail.jpg" alt="">
<h3 id="article-title">記事タイトル</h3>
<p>記事の概要...</p>
<span class="card-detail-link">詳細を見る</span>
</a>
</article>
优势:
- 实现简洁
- CSS 调整容易
缺点:
- 屏幕阅读器有时会将所有文本连接在一起朗读(尤其是在 VoiceOver 中会读成「文章标题文章概要...查看详情、链接」)
- 卡片内无法放置多个链接
各个模式的示例
总结
实现无障碍卡片型组件存在多种方法。重要的是要认识到,不存在「唯一正确的」实现模式,而是根据不同情况选择最优方案。
实现时应注意以下要点。
- 选择不会给实际使用者带来困难的实现方案
- 考虑图像含义、卡片用途和整个网站的结构
- 优先选择实用且易于维护的实现方式
从DTP跨越到Web世界,不知不觉中已掌握标签、前端开发、创意指导、无障碍设计等各项技能的"技术高手"。从Liberogic创业初期就活跃至今,如今是公司内部的"活百科"。最近沉迷于"能否在无障碍适配上更多依赖AI?"这样的思考,正在探索借助AI提示词提高效率的方法。技术实力和思维方式都还在不断进化中
Futa
IAAP 认证网络无障碍专家 (WAS) / 标记语言工程师 / 前端工程师 / 网络总监