• Organism
  • CORE COMPONENT
  • Taxonomic name: O-CARD-SELECT
  • Extension: FORMS-EXTENDED-A
  • Added on: v4.6.0 (01/02/19)
  • Updated on: v5.6.0 (20/04/21)

Radio singlecard select, basic variant

Radio cards allow a single card selection to be made through the use of radios. Radio positioning can be either top left or bottom left.


Design and usage

Structure

  • Cards can contain a radio positioned either top left or bottom left aligned.
  • Cards can contain an image or icon alongside a label.
  • Do not use components that are selectable such as links, buttons, forms - these cards can only use images and plain text.

Labels

  • We advise keeping labels shorter, ideally no more than three lines maximum on a mobile device.

Notifications and errors

  • Notifications: Standard notification placement appears above card stack.

Accessibility and screen readers

  • Radio is mandatory.
  • Hit area is the whole card.
  • Colour is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element.
  • Aria-invalid must be used to indicate when an error has occurred with this element.
  • Aria-describedby must be used to link any help, instructional and/or error text with the element/form fields.

Non-JS requirements and considerations

  • Error states revert to standardised FW versions with notification appearing above stack of cards.

Placement

  • Stacking: Cards can fit a multitude of widths across the 12 col span. Depending on the layout requirements flexibility baked in.
  • Positioning: Cards can be laid out either horizontally, vertically and in carousels (desktop, tablet, mobile).
  • Carousels: Afforded on mobile for options amounting to greater than eight cards.
  • Adaptable card heights based on content and elements included. In instances of horizontal arrangement, stacking will inherent tallest card height for a particular row.

Desktop

  • Cards can span 4, 6, 8 or 12 grid column widths.
  • Horizontal (stacked) and vertical (side-by-side, carousel) card layouts and positioning included.

Tablet

  • Cards can span 4, 6 or 8 grid column widths.
  • Horizontal (stacked) and vertical (side-by-side,carousel) card layouts and positioning included.

Mobile

  • Cards can span 4 column widths.
  • Horizontal (stacked) and vertical (side-by-side carousel only) card layouts and positioning included.

Examples

Text only - two cols desktop / tablet

Interactive example

Code example

<fieldset class="m-form-row m-form-row--full-width o-radio-card-select">
	<legend class="a-label">...</legend>
	<div class="m-form-row__content">
		<ul class="a-list-plain l-columns [ Modifiers ]">
			<li class="l-columns__column m-card m-card-select a-radio t-accent-light t-accent-light--1">
				<label for="...">
					<input class="a-radio__input m-card-select__input" id="..." name="..." type="radio" value="..." />
					<span class="a-radio__label m-card-select__label"><span class="a-radio__label-inner a-heading a-heading--3 a-heading--semibold u-margin--top-none">...</span></span>
					<span class="a-radio__ui m-card-select__ui"></span>
				</label>
			</li>			<!-- disabled card -->
			<li class="l-columns__column m-card m-card-select a-radio t-accent-light t-accent-light--1 is-disabled is-unavailable">
				<label for="...">
					<input class="a-radio__input m-card-select__input" id="..." name="..." type="radio" value="..." disabled />
					<span class="a-radio__label m-card-select__label"><span class="a-radio__label-inner a-heading a-heading--3 a-heading--semibold u-margin--top-none">...</span></span>
					<span class="m-card-unavailable">
						<span class="a-heading a-heading--3 a-heading--semibold is-opaque">Unavailable</span>
						<span>for this reason</span>
					</span>
					<span class="a-radio__ui m-card-select__ui"></span>
				</label>
			<li>			...		</ul>
	</div>
</fieldset>

Image cards with bottom labels

Interactive example

Code example

<fieldset class="m-form-row m-form-row--full-width o-radio-card-select">
	<legend class="a-label">...</legend>
	<div class="m-form-row__content">
		<ul class="a-list-plain l-columns [ Modifiers ]">
			<li class="l-columns__column m-card m-card-select a-radio t-accent-light t-accent-light--1">
				<label for="...">
					<input class="a-radio__input m-card-select__input" id="..." name="..." type="radio" value="..." />
					<span class="m-card-image m-card-image--16x9">
						<img src="..." decoding="async" width="..." height="..." alt="" />
					</span>
					<span class="m-card-content m-card-select__content">
						<span class="m-card-content__inner">
							<span class="a-heading a-heading--3 a-heading--semibold">...</span>
							<span>...</span>
						</span>
					</span>
					<span class="a-radio__label m-card-select__label" aria-hidden="true"><span class="a-radio__label-inner">...</span></span>
					<span class="a-radio__ui m-card-select__ui"></span>
				</label>
			</li>			...		</ul>
	</div>
</fieldset>

Enhanced centred text with bottom labels

Image cards in carousel

Interactive example

Code example

<fieldset class="m-form-row m-form-row--full-width o-radio-card-select">
	<legend class="a-label">...</legend>
	<div class="m-form-row__content">
		<div class="l-columns l-columns--2-medium l-columns--4-large o-carousel o-carousel--all" data-module="o-carousel">
			<div class="l-columns__column m-card m-card-select a-radio t-accent-light t-accent-light--1">
				<label for="...">
					<input class="a-radio__input m-card-select__input" id="..." name="..." type="radio" value="..." />
					<span class="a-radio__label m-card-select__label" aria-hidden="true"><span class="a-radio__label-inner">...</span></span>
					<span class="m-card-image m-card-image--16x9">
						<img src="..." decoding="async" width="..." height="..." alt="" />
					</span>
					<span class="m-card-content m-card-select__content">
						<span class="m-card-content__inner">
							<span class="a-heading a-heading--3 a-heading--semibold">...</span>
							<span>...</span>
						</span>
					</span>
					<span class="a-radio__ui m-card-select__ui"></span>
				</label>
			</div>			...		</div>
	</div>
</fieldset>

Icon cards

Interactive example

Code example

<fieldset class="m-form-row m-form-row--full-width o-radio-card-select">
	<legend class="a-label">...</legend>
	<div class="m-form-row__content">
		<ul class="a-list-plain l-columns [ Modifiers ]">
			<li class="l-columns__column m-card m-card-select a-radio t-accent-light t-accent-light--1">
				<label for="...">
					<input class="a-radio__input m-card-select__input" id="..." name="..." type="radio" value="..." />
					<span class="a-radio__label m-card-select__label m-card-select__label--floating"><span class="a-radio__label-inner">...</span></span>
					<span class="m-card-image m-card-image--icon">
						<img src="..." decoding="async" width="..." height="..." alt="" />
					</span>
					<span class="m-card-content m-card-select__content">
						<span class="m-card-content__inner">
							<span class="a-heading a-heading--3 a-heading--semibold">...</span>
							<span>...</span>
						</span>
					</span>
					<span class="a-radio__ui m-card-select__ui"></span>
				</label>
			</li>			...		</ul>
	</div>
</fieldset>

Valid

Error

Disabled

With help

Icons cards with top labels

Note: The images on these select cards are hidden on mobile view, on tablet with more than 4 cards, and on desktop with more than 6 cards.

Interactive example

Code example

<fieldset class="m-form-row m-form-row--full-width o-radio-card-select">
	<legend>...</legend>
	<div class="m-form-row__content">
		<ul class="a-list-plain l-columns [ Modifiers ]">
			<li class="l-columns__column m-card m-card-select a-radio">
				<label for="...">
					<input class="a-radio__input m-card-select__input" id="..." name="..." type="radio" value="..." checked="checked" />
					<span class="a-radio__label m-card-select__label"><span class="a-radio__label-inner">...</span></span>
					<span class="m-card-image m-card-image--icon-below">
						<img src="..." decoding="async" width="..." height="..." alt="..." />
					</span>
					<span class="a-radio__ui m-card-select__ui"></span>
				</label>
			</li>			...		</ul>
	</div>
</fieldset>

Development and test

Notes for developers

When creating a set of singlecard select radios, they must be contained within a single fieldset where the legend is the question/title for the whole group.

Within a group of radios the name attribute must be common between all the radios, but the id remains unique to the page.

When disabling form elements, do not solely rely on the is-disabled class, but ensure that the disabled attribute is also set on the relevant form element or input. If an entire set of form elements is to be disabled, the is-disabled class and disabled attribute should be added directly to the fieldset instead, and not to each individual element within it. However if only one element from the set is disabled, then the class and attribute should be applied to that element only.

The is-invalid class can also be added alongside is-disabled to fade the opacity of the card and display a message on an overlay; this message is set within the m-card-disabled span following the a-radio__ui span.

If the native form validation needs to be disabled, set the novalidate attribute on the form.

Other information

The entire card is clickable; for this reason, the contents within the card have been converted to span tags to ensure the code validates. Take care when adding additional elements to ensure this principle is followed.

Radio singlecard select rows must not be nested inside other cards with a dark accent colour background, as the results could be unpredicatble.

Accent colours

Do not use within areas with t-card-accent classes applied as this could cause the font colours to display incorrectly.

Aria usage for errors and help text

To aid screen reader users in completing forms without error and also with understanding and fixing any errors that have occured, some additional aria attributes are now recommended to be applied across all form fields/rows.

All form row help, explanatory text, form row instructions and form row errors must have a unique id assigned to them and be appropriately linked to either the individual form input or the form row using aria-describedby. This ensures that the help text is read out immediately on focus of the form input/fieldset. When there is more that one item that requires referencing within the aria-describedby attribute the id values must be supplied in the form of a space separated list. For example if there is an error with id of 'err1' and help text with id of 'help1' the value for the aria-describedby attribute would be 'err1 help1'.

All inline form error messages should start with the hidden text 'Error: ' so that when read by out by a screen reader it is immediately clear that the text being read is an error message.

All erroring form fields (or fieldset if a group or radios/checkboxes) must have aria-invalid="true" set on them, ensuring that when a user focus' on an errored form field, the field will be announced as invalid, so the user is then aware that there in an issue that requires fixing.

When linking help or errors, or even adding aria-invalid to the markup careful consideration must be taken as to where it is most appropriate to apply the value. The following rules should be used to decide where the attribute(s) should be applied.

  • Single form field - All attributes should be applied directly to that form field
  • Group of form fields but only one in error or help text applies to only one - Apply the attribute(s) to the only field in error or where the help text applies
  • Group of form field where all in error or the help text applies to all - Apply the attribute(s) to the groups surrounding fieldset (form row)

There may situations where more than one of these rules applies to the overall form row for example a date range where the instruction text applies to both fields so should be linked to the fieldset for the date range but one of the two fields is in error so the error should be linked to just that field not to the fieldset.

Important messages

To help those using assistive technologies, make sure that success/error messages which need to be announced to users have their aria attributes updated to role="alert" and/or aria-live="assertive".

Using autocomplete

Users appreciate when websites save them time by automatically filling common fields like names, email addresses and other frequently used fields, plus it helps to reduce potential input errors, especially on virtual keyboards and small devices.

Browsers use many methods to determine which fields they can auto-populate based on previously specified data by the user, and you can give hints to the browser by providing both the name attribute and the autocomplete attribute on each input element.

Further details can be found in the developer notes on the form introduction page.

Extension component

This component forms part of the 'forms-exteneded-a' extension and so requires an additional stylesheet to be loaded in order to be used; include the following code in the header of your page to attach the relevant additional stylesheet:

<link media="all" href="./assets/[ theme type ]/[ release version ]/[ organisation ]/[ theme name ]/css/forms-exteneded-a.css" rel="stylesheet" />

Notes for testers

  • Ensure that all radios have a related label. It should be really clear which label applies to which radio by using background shading to group the label and the radio together.
  • Ensure carousel controls and movement remain fluent regardless of browser type and / or orientation. Check further carousel functionality against standard expectations laid out on the card carousel documentation page.

Classes overview

The following table gives you a quick overview of the CSS classes that can be applied.

Class Outcome Required Applied to Comments
.o-card-select Base styling for a group of singlecard select radios Yes fieldset  
.m-card-select Class to add to card to add required styles Yes .m-card  
.m-card-select--basic Class to add to basic variant card to add required styles where whole card acts as a link   .m-card  
.m-card-select__input Additional class specific to radio input in o-card-select context Yes .a-checkbox__input  
.m-card-select__label Additional class specific to radio label in o-card-select context Yes .a-checkbox__label  
.m-card-select__label--floating Class to float radio to top left for cards with no supporting text label (eg icon cards)   .a-radio__label  
.m-card-image--icon-below Additional class to position icon correctly at the bottom of a card   .m-card-image  
.m-card-select__ui Additional class specific to radio ui in o-card-select context Yes .a-checkbox__ui  
.is-unavailable Class to add to disabled card to add unavailable overly and message   .m-card.is-disabled  
.m-card-unavailable Class for unavailable card overlay and message   .m-card-select > span  

Keyboard operations

TAB

Tabbing to an checkbox input should make the input clearly visually different so that the focus point on the page is obvious to the user.

CURSOR KEYS

With focus on the checkbox, pressing SPACE will select/deselect the checkbox.

Component releases

  • Added on: v4.6.0 (01/02/19)
  • Updated on: v5.6.0 (20/04/21)

Latest update:

  • updated: To improve page load and layout times the additional attributes decoding="async", width and height must be set on all inline images.
  • updated: Markup has changed to use the picture element to improve page performance by allowing different sized images to be served for different screen sizes.

Full version history

A full history of changes and enhancements detailing all minor and major updates to the component.

View full version history

Want something new in Framework, or to chat about an issue you're having with it?

Contact the team