Cards
Cards let you preview and share content quickly, without having to leave the page you're on
- Version:
- 0.1.0
- Status:
- Published
Introduction
The Card component is superficially similar to the Promo. However, while the promo acts as a teaser and links to a page with full information, the Card is self-sufficient and offers functionality in situ.
This functionality can include video playback, and options to share the card content via social media. Read the original GEL Card documentation for more.
Recommended markup
<h2>Heading introducing the set of cards</h2>
<ul>
<li class="gel-card">
<div class="gel-card__headline">
<h3>Card 1 Headline</h3>
</div>
<div class="gel-card__content">
<!-- an image, video, quotation, etc -->
</div>
<div class="gel-card__desc">
<!-- can include an attribution, timestamp, etc. -->
</div>
<div class="gel-card__toolbar">
<button type="button" aria-expanded="false">
<span class="gel-card__more-label">
<svg class="gel-icon gel-icon--text" focusable="false" aria-hidden="true">
<use xlink:href="path/to/gel-icons-all.svg#gel-icon-up"></use>
</svg>
More info
</span>
<span class="gel-card__close-label">
<svg class="gel-icon gel-icon--text" focusable="false" aria-hidden="true">
<use xlink:href="path/to/gel-icons-all.svg#gel-icon-no"></use>
</svg>
Close
</span>
</button>
<div class="gel-card__info" role="group" aria-labelledby="more-info-title-1">
<h4 class="gel-card__info-heading" id="more-info-title-1">More info</h4>
<!-- More info here -->
</div>
<button type="button" aria-pressed="false">
<span class="gel-sr">Love</span>
<svg class="gel-icon gel-icon--text" focusable="false" aria-hidden="true">
<use xlink:href="path/to/gel-icons-all.svg#gel-icon-love-loved-state"></use>
</svg>
</button>
<button type="button">
<span class="gel-sr">Add</span>
<svg class="gel-icon gel-icon--text" focusable="false" aria-hidden="true">
<use xlink:href="path/to/gel-icons-all.svg#gel-icon-add"></use>
</svg>
</button>
<button type="button">
<span class="gel-sr">Share</span>
<svg class="gel-icon gel-icon--text" focusable="false" aria-hidden="true">
<use xlink:href="path/to/gel-icons-all.svg#gel-icon-share"></use>
</svg>
</button>
</div>
</li>
<li class="gel-card">
<!-- another card's contents -->
</li>
</ul>
Notes
<ul>
and<li>
: Cards are typically presented as a set, and together must be marked up as an unordered list, with each card marked as a list item (<li>
). This enables structural and navigational cues in screen reader software[1].- Headings: Each card's primary (headline) link must be contained within a heading, each of the card's headline headings must be of the same level, and the set of cards must be introduced as a section within the document by a heading one level higher.
gel-card__headline
: This must appear first in the source order, although the card content will appear first visually. This is because the card's heading introduces the document section that constitutes the rest of the card. Avoid putting interactive content insidegel-card__headline
because this will create a reversed focus order.gel-card__desc
: This will contain prosaic content, such as a description, attribution, and/or timestamp. Some of these elements may be linked to other resources.aria-expanded
: You may need to provide additional, clarifying information for the card. Agel-card__info
element is hidden by default, but can be toggled into view using thearia-expanded
button. Note that thegel-card__info
element appears directly after thearia-expanded
button so that it is logically placed within browsing and focus order. The further action buttons will be the next Tab stops. Thearia-expanded
ARIA state attribute[2] identifies the button as a 'toggle button' in screen readers.role="group"
andaria-labelledby
: In order to reliably associate a label with thegel-card__info
element, a generic ARIA role is provided. The label itself is provided as a heading of the correct nesting level (<h4>
following<h3>
in the example) and connected togel-card__info
usingaria-labelledby
.- Love, add, and share: The remaining actions facilitated by
gel-card__toolbar
. Thearia-pressed
state attribute should be provided on the "Love" action, since this is a an "on/off" toggle. In the above example, the text label is visually hidden with thegel-sr
class. However, where there are fewer than three of these buttons present (and therefore more room), you should display the text labels visually as well as making them available to assistive technologies.
Card contents
There is a variety of content that may be included in cards. Here are some common examples:
An image
When an image is the focus of the card, it should be considered salient content and must include sufficient alternative text. For example, if the card's headline is "Winning nature photograph", the alternative text should not be:
- Omitted
- A mere repetition of the headline
Instead, describe what is in the photograph and what makes it relevant.
A video
If a video is provided, ensure the following:
- The video does not auto-play[3]
- The video player's controls are accessible by screen reader and keyboard
- Dialogue in the video is accompanied by closed captions
If an auxiliary play/pause button is provided, ensure that the button is accessible. See Video controls for more information.
A quotation
Quotations must be set out using the <figure>
and <figcaption>
elements. The <figcaption>
element must come after the quotation itself.
<figure>
<p>Are you the sort of person who gloats when you see a woman fall, or the kind that celebrates a magnificent recovery? #TeamMadonna</p>
<figcaption>J.K. Rowling</figcaption>
</figure>
Recommended layout
The minimum width for a card is 266px
. A set of cards can appear within a grid formation or as the content of a carousel component.
Grid formation
The most efficient way to arrange cards into a grid is to use the CSS Grid module. You must ensure that a fallback layout is in place where CSS Grid is not supported. In the following code, Flexbox provides that fallback.
.gel-cards {
display: flex;
flex-wrap: wrap;
}
.gel-cards > * {
flex: 0 0 266px;
margin: 0 1rem 1rem 0;
}
@supports (display: grid) {
.gel-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(266px, 1fr));
grid-gap: 1rem;
}
.gel-cards > * {
margin: 0;
}
}
Carousel formation
To achieve a carousel formation, the containing carousel element needs to have overflow-x: auto
and the cards list must not be allowed to wrap. This is best achieved using Flexbox. See Carousels.
Individual card layout
Each card in a set should share the same height, despite content across cards varying in quantity/length. In a Grid or Flexbox context, cards already stretch to fill the container's height. All that remains is to push the card's final child element (usually the toolbar) to the bottom of the card.
This must not be achieved using absolute positioning, because this is likely to interfere with zoom functionality. Instead, make the card a Flexbox context and give the toolbar element a top margin of auto
:
.gel-card {
display: flex;
flex-direction: column;
}
.gel-card__toolbar {
margin-top: auto;
}
The gel-card__headline
, containing the heading element, must come first in focus order hence it is first in source order. To move the gel-card__content
above it visually you can use order: -1
.
.gel-card__headline {
order: -1;
}
Media layout
To ensure the image or video has the best chance of fitting within the given space without distorting, it is recommended you use the object-fit
property as a progressive enhancement. In the following example, the height of the content area has been set to 10rem
and the width is assumed to be indeterminate/responsive.
.gel-card__content img,
.gel-card__content video {
height: 100%;
width: auto;
}
@supports (object-fit: cover) {
.gel-card__content img,
.gel-card__content video {
width: 100%;
object-fit: cover;
}
}
The 'More info' element
This element must be absolutely positioned over the card, which means the card itself must take position: relative
. The bottom
positioning of the element must match the height of the gel-card__toolbar
element so that element is not obscured while the element is visible.
.gel-card {
position: relative;
}
.gel-card__info {
position: absolute;
top: 0;
right: 0;
bottom: 2.5rem; /* height of the toolbar */
left: 0;
padding: 1rem;
background-color: #F1F1F1;
overflow-y: auto;
}
Also note overflow-y: auto
. This is provided in case the content inside the 'More info' element is taller than its height. Since the element is not allowed to grow, it must be scrollable instead.
High contrast
How the component looks with a Windows High Contrast Mode theme active. Transparent outlines and borders that become visible in Windows HCM are used to demarcate the Card from some of its subcomponents. An outline style supplements the background-color
focus style that is eliminated.
Recommended behaviour
Aside from the toolbar behaviour, the card's behaviour will depend on the content it houses. See Card contents for pointers.
The 'More info' button
The 'More info' button toggles the visibility of an element containing the additional information for the card. This element must be hidden
by default. When 'More info' is clicked for the first time, hidden
becomes false
and aria-expanded
becomes true
.
In plain JavaScript, a simple function will suffice:
moreBtn.addEventListener('click', function () {
moreElem.hidden = !moreElem.hidden;
moreBtn.setAttribute('aria-expanded', !moreElem.hidden);
});
In addition, it should be possible to close the class="gel-card__info"
element using the Esc key. In this scenario, focus needs to be returned programmatically to the button.
moreElem.addEventListener('keydown', function (e) {
if (e.which === 27) {
moreElem.hidden = true;
moreBtn.setAttribute('aria-expanded', 'false');
moreBtn.focus();
}
});
Reference implementation
Astronomy Photographer of the Year 2018
-
Living Space
Taken in Pagham, West Sussex, Whyte's photograph aims to show how accustomed we have become to the loss of night sky views because of light pollution, with the unlit street lamps allowing for awe-inspiring views.
Runner-up: Andrew Whyte
More info
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla sollicitudin posuere mauris, at sagittis odio aliquam sed. Nunc neque diam, euismod ut purus et, scelerisque vulputate tortor. Donec non commodo turpis. Nunc ac magna in diam molestie posuere eget eu elit. Suspendisse ut lectus porta eros dapibus tempor. Curabitur tempus purus eu consequat semper. Ut a lectus non metus imperdiet finibus. Sed vestibulum enim congue, finibus augue ut, dictum justo.
-
Speeding on the Aurora Lane
A hazy auroral band is seen drifting across the sky above Sirkka, Finland, seeming like a road disappearing over the horizon.
Winner: Nicolas Lefaudeux
More info
Vestibulum consectetur, lectus sed porta pulvinar, turpis nunc placerat nisl, non blandit augue leo in nunc. Vivamus in mi lectus. Vivamus ex orci, finibus non massa nec, viverra sollicitudin nibh. Nunc semper imperdiet ante, et mattis magna hendrerit a. Quisque libero nibh, hendrerit at tortor vitae, cursus elementum diam. Donec auctor molestie imperdiet. Vivamus venenatis mauris ut ante volutpat fringilla. Duis ullamcorper ac libero sed iaculis. Duis pulvinar leo at feugiat dapibus. Aenean sagittis felis massa, sodales ullamcorper tellus consectetur ac.
-
Castlerigg Stone Circle
Turner's image depicts standing stones illuminated by moonlight, while auroras beyond the mountains gives the appearance that the hills are emitting an ethereal green glow.
Runner-up: Matthew James Turner
More info
Quisque sit amet magna lacus. Donec in fringilla velit. Curabitur vulputate magna euismod turpis luctus bibendum. Donec fringilla risus eget felis aliquet, vel vestibulum nibh bibendum. In laoreet ut nisi nec gravida. Nullam scelerisque posuere mollis. Donec ac mauris maximus, placerat enim vitae, placerat libero. Maecenas eget magna quis diam faucibus suscipit at et velit. Nulla placerat vehicula nunc in maximus. Nulla euismod neque vel imperdiet dignissim.
Related research
This topic does not yet have any related research available.
Further reading, elsewhere on the Web
"Basic screen reader commands for accessibility testing" by Léonie Watson, https://developer.paciellogroup.com/blog/2015/01/basic-screen-reader-commands-for-accessibility-testing/ ↩︎
aria-expanded
(state) — W3C, https://www.w3.org/WAI/PF/aria-1.1/states_and_properties#aria-expanded ↩︎"Why Autoplay Is An Accessibility Issue" — abilitynet.org.uk, https://www.abilitynet.org.uk/news-blogs/why-autoplay-accessibility-issue ↩︎