# Accessible card component

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

1. Set `position: relative` on the container element
2. Set `position: absolute` on the link’s `:after` pseudo-content
3. Set value of `0` for `top`, `right`, `bottom`, and `left` properties on link’s `:after` pseudo-content
4. Combine it with `:focus-within` and `:hover` to style different states
5. Enhance it even further and make the text selectable with `z-index`
6. If you want to add other links inside a card, use styles from `card__separate` to make it selectable (and/or clickable).

### HTML

```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

```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:

<iframe width="100%" height="300" src="https://jsfiddle.net/damianwajer/hbv2zajs/embedded/result,html,css/" allowfullscreen="allowfullscreen" allowpaymentrequest frameborder="0"></iframe>

## Credits & further reading

I first saw the pseudo-content trick technique on [Inclusive Components](https://inclusive-components.design/) website. Check it out for other solutions to card issues and more inclusive components examples.
