Accessible card component
With pure (S)CSS (no JavaScript, the pseudo-content trick)

When creating the card component, sometimes it’s advisable (or required by design) to make the whole card clickable. But how to do so without compromising the usability? Below I share a useful pseudo-content trick to make the whole card clickable and maintain its accessibility.
Problem statement
- the whole card needs to be clickable
- within the card there is also a “read more” link
- inside a card, there are other separate links to different URL-s
- you don’t want to harm the usability, e.g. allow the user to open all links in a new tab with a mouse right-click (context menu on touch devices)
- support custom styles for hover and focus states
- one last requirement: user should be able to select and copy the text within a card to the clipboard
How would you approach this task? Just a regular card component wrapped in an a element? Or maybe onclick in JavaScript directly on a div or article element (don’t do that!)?
How to handle such a case and maintain the accessibility in a simple and elegant way?
Possible solution
- Set
position: relativeon the container element - Set
position: absoluteon the link’s:afterpseudo-content - Set value of
0fortop,right,bottom, andleftproperties on link’s:afterpseudo-content - Combine it with
:focus-withinand:hoverto style different states - Enhance it even further and make the text selectable with
z-index - If you want to add other links inside a card, use styles from
card__separateto make it selectable (and/or clickable).
HTML
<div class="card">
<p>
<a href="#optional" class="card__separate">Optional</span>
</p>
<p>
<span class="card__separate">Lorem ipsum</span>
</p>
<a href="#card-link" class="card__link">Link</a>
</div>
SCSS
.card {
position: relative;
border: 3px solid green;
// Style hover and focus states.
&:hover,
&:focus-within {
border-color: red;
}
// Make the content selectable.
&__separate {
position: relative;
z-index: 2;
}
// Make the whole card clickable.
&__link::after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
content: "";
}
}
Demo
Check clickable area (start with "Button 1") and try tab keyboard navigation in the following example:
Credits & further reading
I first saw the pseudo-content trick technique on Inclusive Components website. Check it out for other solutions to card issues and more inclusive components examples.
About the author
Web developer, UX consultant. Making stuff for the web since 2005 🦄
Comments
Join the discussionNo comments yet. Be the first to comment.

