Cards

  • These cards are flexed for older browsers and have progressive grid enhancement.
  • The image block comes second in the markup such that when a user uses the 2 key to skip to the h2, the image alt text isn't skipped over, as it logically belongs to the topic of the h2.
  • Wrapping an entire card within an anchor can be overwhelming when using a screen reader, as the reader will read through the entirety of the card for the link. Logically, the link text should be the h2. This link, therefore, has an ::after pseudo-element that covers the card.
    • The byline link is raised above the ::after by positioning it relatively.
    • The description is similarly raised in order to make the text selectable. But there is also an expectation of being able to click the entire card as the entire card highlights on hover. This gap is covered by the cards.js javascript file, which allows the user to both select the text or click through--if the click is < 200ms, the link is followed. Otherwise, the text can be selected.
  • The same :hover style for the card is applied when anything within the card is focused.
  • The :hover style is removed from the header link as the card itself is highlighted on hover.
  • Because of the small size, the byline link has additional padding for extra click area.

Cards

Simple cards with footers that have an additional link. The footer is optional.

_cmp.cards.scss
cards.js

Card Two

Description of the second item goes here

Description of the image
<div class="cmp-cards">
  <article class="cmp-cards__card">
    <div class="cmp-cards__text">
      <header class="cmp-cards__header">
        <h2><a class="cmp-cards__header-link" href="#">Card One</a></h2>
      </header>
      <p class="cmp-cards__description">This is the description for the first card</p>
      <footer class="cmp-cards__footer">
        <small class="cmp-cards__byline">By <a class="cmp-cards__byline-link" href="#">Someone</a></small>
      </footer>
    </div>
    <div class="cmp-cards__image">
      <img src="https://picsum.photos/400/200" alt="Description of the image">
    </div>
  </article>
  <article class="cmp-cards__card">
    <div class="cmp-cards__text">
      <header class="cmp-cards__header">
        <h2><a class="cmp-cards__header-link" href="#">Card Two</a></h2>
      </header>
      <p class="cmp-cards__description">Description of the second item goes here</p>
    </div>
    <div class="cmp-cards__image">
      <img src="https://picsum.photos/400/200" alt="Description of the image">
    </div>
  </article>
  <article class="cmp-cards__card">
    <div class="cmp-cards__text">
      <header class="cmp-cards__header">
        <h2><a class="cmp-cards__header-link" href="#">Card Three</a></h2>
      </header>
      <p class="cmp-cards__description">A longer description of the third item, the paragraph is just a bit longer here</p>
      <footer class="cmp-cards__footer">
        <small class="cmp-cards__byline">By <a class="cmp-cards__byline-link" href="#">Someone Else</a></small>
      </footer>
    </div>
    <div class="cmp-cards__image">
      <img src="https://picsum.photos/400/200" alt="Description of the image">
    </div>
  </article>
</div>

Cards with CTAs

  • In this example, the :focus style is removed from the header link and, instead, when focused it applies the button's :hover style.
  • The button and text within it is only visually relevant, so aria-hidden is true.
  • Focusable elements should not have aria-hidden="true", but in this example the focus is actually on the link in the header. This ensures that the text associated and read with the link is relevant while visually allowing the user to tab through the CTA button. The tabindex="-1" allows the user to actually skip over focusing the CTA button.
_cmp.cards.scss
cards.js
<div class="cmp-cards cmp-cards--ctas">
  <article class="cmp-cards__card">
    <div class="cmp-cards__text">
      <header class="cmp-cards__header">
        <h2><a class="cmp-cards__header-link" href="#">Card One</a></h2>
      </header>
      <p class="cmp-cards__description">This is the description for the first card</p>
      <footer class="cmp-cards__footer">
        <a class="cmp-cards__cta" tabindex="-1" href="#" aria-hidden="true">Read more →</a>
        <small class="cmp-cards__byline">By <a class="cmp-cards__byline-link" href="#">Someone</a></small>
      </footer>
    </div>
    <div class="cmp-cards__image">
      <img src="https://picsum.photos/400/200" alt="Description of the image">
    </div>
  </article>
  <article class="cmp-cards__card">
    <div class="cmp-cards__text">
      <header class="cmp-cards__header">
        <h2><a class="cmp-cards__header-link" href="#">Card Two</a></h2>
      </header>
      <p class="cmp-cards__description">Description of the second item goes here</p>
      <footer class="cmp-cards__footer">
        <a class="cmp-cards__cta" tabindex="-1" href="#" aria-hidden="true">Read more →</a>
        <small class="cmp-cards__byline">By <a class="cmp-cards__byline-link" href="#">Someone Else</a></small>
      </footer>
    </div>
    <div class="cmp-cards__image">
      <img src="https://picsum.photos/400/200" alt="Description of the image">
    </div>
  </article>
  <article class="cmp-cards__card">
    <div class="cmp-cards__text">
      <header class="cmp-cards__header">
        <h2><a class="cmp-cards__header-link" href="#">Card Three</a></h2>
      </header>
      <p class="cmp-cards__description">A longer description of the third item, the paragraph is just a bit longer here</p>
      <footer class="cmp-cards__footer">
        <a class="cmp-cards__cta" tabindex="-1" href="#" aria-hidden="true">Read more →</a>
        <small class="cmp-cards__byline">By <a class="cmp-cards__byline-link" href="#">Someone</a></small>
      </footer>
    </div>
    <div class="cmp-cards__image">
      <img src="https://picsum.photos/400/200" alt="Description of the image">
    </div>
  </article>
</div>