Card-type components are often used in lists of articles, etc. Although they look simple, there are surprisingly deep design issues when considering accessibility.
A typical card from above
- image
- Article Title
- Article Summary
- More details link
Let's consider an implementation pattern for a vertical layout.
Main points to consider when designing
1. Visual Order and HTML Structure
Screen readers generally read HTML in the order it is written.Success Criterion 1.3.2 (Meaningful Sequence, Level A)So,The basic principle is to match the visual order with the HTML order.This is what we are saying.
However, changing the order in CSS does not in itself violate WCAG. There is no problem if the visual order and the HTML order are different, as long as the content is understandable. It is important to be flexible and make decisions based on the situation.
2. How to handle images
Images on article cards are oftendecorativeThe article title is enough to convey the content, so there is little need to read out the image description.
When treated as a decorative imagealt=""is enough.
<img src="thumbnail.jpg" alt="">
3. Details link label
Generic text like "Learn more" should be avoided for the following reasons:
Visual issues
It's hard to tell what a link is without the surrounding context
Screen reader issues
When displayed in a list using the link list function, all links are labeled "View details" and are indistinguishable (WCAG 2.4.4 Link Purpose, Level A)
Voice Recognition Issues
If there are multiple identical texts, you will need to select them by number, which makes the process complicated.
Ideally, the link should have text that makes its purpose clear from the link alone, such as "See details about XX," but here we will cover how to implement it if you want to reproduce the "See details" design exactly.
4. Clickable areas of cards
For UX purposes, it's often desirable to make the entire card clickable. There are several ways to achieve this, each with different impacts on accessibility.
5. Should cards be articles or divs?
The choice depends on the nature of the content.
<article>Suitable when:
- The card content stands as an independent piece of content
<div>If that's OK:
- It simply acts as a group of links
- The cards themselves have no semantic independence
For general blog post list or product list cards,<article>However, multiple<article>When using, please take into consideration the landmark movement of the screen reader.aria-labelledbyoraria-labelIt is recommended that you use a CSS3 tag to identify each article (WCAG 2.4.6, Level AA).
aria-labelledbyIf you use this, make sure the ID is a unique value.
Visual Order and HTML Structure
Pattern 1: Match visual order to HTML order
<article class="article-card" aria-labelledby="article-title">
<img src="thumbnail.jpg" alt="">
<h3 id="article-title"><a href="#" class="card-link">Article Title</a></h3>
<p>Article Summary...</p>
<a href="#" class="card-detail-link">
<span class="visually-hidden">Article Title:</span>View Details
</a>
</article>
It's simple and intuitive, as the HTML order matches the visual order perfectly.
※ <article>The first element in a header is preferred, but not an absolute requirement. If you prioritize consistency with the visual order, this pattern is fine.
supplement:
Speech recognition software (Dragon, Voice Control, etc.) works based on the text displayed on the screen.visually-hidden (sr-only)By using this, visual text is preserved and operation by voice recognition is possible. In addition, here are examples of OK and NG patterns for link label support.
<!-- The following is OK because the visible text is included in the accessible name -->
<a href="#" id="link-text" class="card-detail-link" aria-labelledby="link-text article-title">
View Details
</a>
<a href="#" aria-label="View Details: Article Title">
View Details
</a>
<!-- The following is NOT OK because the visible text is not included in the accessible name -->
<a href="#" class="card-detail-link" aria-labelledby="article-title">
View Details
</a>
<a href="#" class="card-detail-link" aria-label="Article Title">
View Details
</a>
Pattern 2: Adjust the visual order with CSS order
<article class="article-card" aria-labelledby="article-title">
<h3 id="article-title"><a href="#">Article Title</a></h3>
<p>Article Summary...</p>
<a href="#" class="card-detail-link">
<span class="visually-hidden">Article Title:</span>View Details
</a>
<img src="thumbnail.jpg" alt="">
</article>
.article-card {
display: flex;
flex-direction: column;
}
.article-card img {
order: -1;
}
<article>is a semantically more desirable structure, since the first element of becomes the heading.
Decorative images (alt=""), the reading order is not affected (because images are skipped).
Notice:
- If the image is meaningful and has an alt attribute, this structure is not suitable as it changes the visual and reading order.
- Keyboard tab order follows HTML order, so if you have multiple focusable elements within a card, make sure the focus order doesn't break the logical flow.
If you want the entire card clickable area
Pattern 3: Making the entire card clickable using pseudo-elements
This method uses a title link pseudo-element to cover the entire card, with the "Learn more" button as visual decoration.<span>to.
Click "View details"<a>As it istabindex="-1"oraria-hidden="true"Even so, it will be noisy in the link list of a screen reader or in element navigation mode, so<span>I think it would be better to do this.
<article class="article-card" aria-labelledby="article-title">
<img src="thumbnail.jpg" alt="">
<h3 id="article-title"><a href="#" class="card-link">Article Title</a></h3>
<p>Article Summary...</p>
<span class="card-detail-link">View Details</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;
}
merit:
- Preserves semantic structure
- Reads naturally by screen readers
- Multiple links can be placed within a card (categories, tags, author links, etc.)
Cons:
z-indexManagement is required (but once set up there is no problem)
Pattern 4: The entire card<a>Surround with
This way, the entire card becomes a single link, so "View details" becomes a natural choice.<span>It will be.
<article class="article-card" aria-labelledby="article-title">
<a href="#" class="card-link">
<img src="thumbnail.jpg" alt="">
<h3 id="article-title">Article Title</h3>
<p>Article Summary...</p>
<span class="card-detail-link">View Details</span>
</a>
</article>
merit:
- Simple to implement
- Easy CSS adjustments
Cons:
- Some screen readers may read all the text concatenated together (especially VoiceOver, which reads "Article title, Article summary...See details, Link").
- You cannot place multiple links in a card
Samples of each pattern
summary
There are multiple approaches to implementing accessible card-type components. The important thing is that there is no "only correct" implementation pattern.The optimal solution varies depending on the situationThat is what it means.
When implementing, it is important to keep the following in mind:
- Choose an implementation that will not cause problems for the actual users
- Consider the meaning of the image, the purpose of the card, and the overall structure of the site.
- Prioritize practical and maintainable implementations
He jumped from DTP to the web world and quickly became a "master of craftsmanship" with a mastery of markup, front-end design, direction, and accessibility. He's been active in a variety of fields since Liberogic's founding and is now a living dictionary within the company. Recently, he's been obsessed with exploring efficiency improvements using prompts, wondering, "Can we rely more on AI for accessibility?" His technology and thinking are still evolving.
Futa
IAAP Certified Web Accessibility Specialist (WAS) / Markup Engineer / Front-end Engineer / Web Director