'Accessible cards grid flow in HTML

Which HTML I should to write for the providing of the accessibility of cards flow (usually products, people, companies etc.)? Without acessibility, it will be something like

<div class"CardsFlow">
  <a class="Card"><!-- Title, image, etc. --></a>
  <a class="Card"><!-- Title, image, etc. --></a>
</div>

Maybe I should represent it as unordered list of links, but it is what I want ask.

<ul class"CardsFlow">
  <li><a class="Card"><!-- Title, image, etc. --></a></li>
  <li><a class="Card"><!-- Title, image, etc. --></a></li>
</div>

In Bootstrap 5 example, nothing related with acessibility (except alt of image) in template code of the card:

<div class="card" style="width: 18rem;">
  <img src="..." class="card-img-top" alt="...">
  <div class="card-body">
    <h5 class="card-title">Card title</h5>
    <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
    <a href="#" class="btn btn-primary">Go somewhere</a>
  </div>
</div>


Solution 1:[1]

Any content that consists of an outer container with a list of elements inside it can be identified to assistive technologies using the list and listitem containers respectively. - ARIA List item - developer.mozilla.org

ARIA listitem role can be used to identify items in list of elements. It used along with list role in container.

  <div role="list">
    <div class="card" style="width: 18rem;" role="listitem">
      <img src="..." class="card-img-top" alt="...">
      <div class="card-body">
        <h5 class="card-title">Card title</h5>
        <p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
        <a href="#" class="btn btn-primary">Go somewhere</a>
      </div>
    </div>
    ...
  </div>

Solution 2:[2]

This is how I've learned to do cards accessibly.

For the cards themselves, use list items, since it's semantically a list of content. Adding redundant ARIA roles can help some assistive tech preserve the semantics when you remove the default list styling.

For the card links, it's important to not put something like "click here" or "read more" in an <a> at the bottom of every card. Many assistive technologies allow users to quickly scan all of the links in a document, and in this mode, they lose the surrounding context for what the link is. The link text must be descriptive enough to make sense out of context. For this reason, it's good to make the title of each card the actual link itself:

ul.cards {
  margin: 0;
  padding: 0;
  display: grid;
  grid-template: auto / 1fr 1fr 1fr;
  gap: 1ch;
}
li.card {
  position: relative;
  list-style: none;
  padding: 1rem;
  border: 1px solid gray;
}
li.card h4 {
  margin: 0 0 1ch 0;
}
li.card img {
  display: block;
  max-width: 100%;
  margin: 0 0 1ch 0;
}
li.card p {
 margin: 0;
}
<section>
  <h3>Title of Cards Section</h3>
  <ul role="list" class="cards">
    <li role="listitem" class="card">
      <h4 class="card-title"><a href="#">Card Title</a></h4>
      <img alt="A kitten." src="https://placekitten.com/200/100">
      <p>Card description lorem ipsum dolor amit.</p>
    </li>
    <li role="listitem" class="card">
      <h4 class="card-title"><a href="#">Card Title</a></h4>
      <img alt="A kitten." src="https://placekitten.com/200/100">
      <p>Card description lorem ipsum dolor amit.</p>
    </li>
    <li role="listitem" class="card">
      <h4 class="card-title"><a href="#">Card Title</a></h4>
      <img alt="A kitten." src="https://placekitten.com/200/100">
      <p>Card description lorem ipsum dolor amit.</p>
    </li>
  </ul>
</section>

If you need the whole card to be clickable by people using pointer devices like a mouse, you can keep the same accessible markup and use a pseudo-element within the link to make the card area clickable:

ul.cards {
  margin: 0;
  padding: 0;
  display: grid;
  grid-template: auto / 1fr 1fr 1fr;
  gap: 1ch;
}
li.card {
  position: relative;
  list-style: none;
  padding: 1rem;
  border: 1px solid gray;
}
li.card h4 {
  margin: 0 0 1ch 0;
}
li.card img {
  display: block;
  max-width: 100%;
  margin: 0 0 1ch 0;
}
li.card p {
 margin: 0;
}
li.card a::after {
  content: "";
  display: block;
  position: absolute;
  inset: 0;
}
li.card a:hover::after {
  background: rgba(0,0,0,0.1);
}
<section>
  <h3>Title of Cards Section</h3>
  <ul role="list" class="cards">
    <li role="listitem" class="card">
      <h4 class="card-title"><a href="#">Card Title</a></h4>
      <img alt="A kitten." src="https://placekitten.com/200/100">
      <p>Card description lorem ipsum dolor amit.</p>
    </li>
    <li role="listitem" class="card">
      <h4 class="card-title"><a href="#">Card Title</a></h4>
      <img alt="A kitten." src="https://placekitten.com/200/100">
      <p>Card description lorem ipsum dolor amit.</p>
    </li>
    <li role="listitem" class="card">
      <h4 class="card-title"><a href="#">Card Title</a></h4>
      <img alt="A kitten." src="https://placekitten.com/200/100">
      <p>Card description lorem ipsum dolor amit.</p>
    </li>
  </ul>
</section>

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Madhan S
Solution 2 Sean