Choice wrapper
The choice wrapper can be used when users need to select either none, one or multiple options from a list while having additional information/content about the options to choose from.
This component is a stylish wrapper for .flix-radio
and .flix-checkbox
components.
In order to use it you must organize your inputs as such:
- Each input element must be inside another container called
.flix-choice-wrapper__item
; - The items must be direct children of a container called
.flix-choice-wrapper
; - If you wish to wrap the choice items with a fieldset, add the
.flix-choice-wrapper__fieldset
class to it; - The fieldset that groups
radio
elements may haverole="radiogroup"
to make this grouping explicit to screen readers; - For even more accessibility points, add a
legend
to the fieldset to make the purpose of the inputs clear, you may visually hide the legend with theflix-sr-only
helper.
These will render the default horizontal layout of the choice wrapper.
<fieldset class="flix-choice-wrapper__fieldset">
<legend class="flix-legend flix-sr-only">Ramen types</legend>
<div class="flix-choice-wrapper">
<div class="flix-choice-wrapper__item">
<div class="flix-radio">
<input class="flix-radio__input" type="radio" name="example" id="example-choice-wrapper-shio" aria-describedby="choice-more-info" value="Shio"/>
<label class="flix-radio__label" for="example-choice-wrapper-shio">
<div class="flix-h4 flix-h4--space-flush">Shio</div>
<div class="flix-text flix-space-half-top">It consists of an amber-tinted soup base made from salt, chicken, fish, vegetables and sea weed.</div>
</label>
</div>
</div>
<div class="flix-choice-wrapper__item">
<div class="flix-radio">
<input class="flix-radio__input" type="radio" name="example" id="example-choice-wrapper-shoyu" aria-describedby="choice-more-info" checked="" value="Shoyu"/>
<label class="flix-radio__label" for="example-choice-wrapper-shoyu">
<div class="flix-h4 flix-h4--space-flush">Shoyu</div>
<div class="flix-text flix-space-half-top">Shoyu Ramen simply refers to ramen served with a soy sauce-based broth that is usually in clear, brown color.</div>
</label>
</div>
</div>
<span class="flix-choice-wrapper__info" id="choice-more-info">Extra information related to the component</span>
</div>
</fieldset>
Modifiers
flix-choice-wrapper--error
- Adds danger colored borders to the `flix-choice-wrapper`. Don't forget to add `--error` to your children `.flix-radio`'s and `.flix-checkbox`'es too.
flix-choice-wrapper--column
- Renders the `flix-choice-wrapper` on a vertical layout, most useful on small screens or if you have more than 3 options;
You can display additional information that is related to the choice within flix-choice-wrapper__info
element connecting it with the relevant inputs using an id
and aria-describedby
.
Guidelines for handling error state:
When a form is submitted and returns an error you should:
- Add
--error
modifiers for visual clarity; - Add
aria-invalid="true"
to invalid inputs; - Connect the inputs and the error message with the
aria-errormessage
attribute; - Add
aria-live="assertive"
and anid
to the error message element, to ensure it is read by the screen reader as soon as the error occurs.
<fieldset class="flix-choice-wrapper__fieldset">
<legend class="flix-legend flix-sr-only">Ramen types</legend>
<div class="flix-choice-wrapper--error flix-choice-wrapper">
<div class="flix-choice-wrapper__item">
<div class="flix-radio flix-radio--error">
<input class="flix-radio__input" type="radio" name="example-err" id="example-choice-wrapper-shio-err" aria-describedby="choice-more-info-err" required="" aria-invalid="true" aria-errormessage="choice-err-msg" value="Shio"/>
<label class="flix-radio__label" for="example-choice-wrapper-shio-err">
<div class="flix-h4 flix-h4--space-flush">Shio</div>
<div class="flix-text flix-space-half-top">It consists of an amber-tinted soup base made from salt, chicken, fish, vegetables and sea weed.</div>
</label>
</div>
</div>
<div class="flix-choice-wrapper__item">
<div class="flix-radio flix-radio--error">
<input class="flix-radio__input" type="radio" name="example-err" id="example-choice-wrapper-shoyu-err" aria-describedby="choice-more-info-err" required="" aria-invalid="true" aria-errormessage="choice-err-msg" value="Shoyu"/>
<label class="flix-radio__label" for="example-choice-wrapper-shoyu-err">
<div class="flix-h4 flix-h4--space-flush">Shoyu</div>
<div class="flix-text flix-space-half-top">Shoyu Ramen simply refers to ramen served with a soy sauce-based broth that is usually in clear, brown color.</div>
</label>
</div>
</div>
<span class="flix-choice-wrapper__info" id="choice-err-msg">Something went wrong</span>
<span class="flix-choice-wrapper__info" id="choice-more-info-err">Extra information related to the component state</span>
</div>
</fieldset>
Column layout using checkboxes and expandable content:
- To make expandable content, you should wrap the content with the
.flix-choice-wrapper__content
; - Toggle the
.flix-choice-wrapper__content--expanded
modifier to show and hide the content depending on the input checked state; - You may use the
classTogler
plugin or ad you own logic to toggle the class (likely the case if your choices are radios).
The expandable content works best on column layout, but the default layout also supports it.
<fieldset class="flix-choice-wrapper__fieldset">
<legend class="flix-legend flix-sr-only">Payment method</legend>
<div class="flix-choice-wrapper flix-choice-wrapper--column">
<div class="flix-choice-wrapper__item">
<div class="flix-checkbox">
<input class="flix-checkbox__input" type="checkbox" name="payment-method" id="method-credit-card" aria-describedby="payment-method-info" data-toggle="credit-card-content" data-toggle-class="flix-choice-wrapper__content--expanded" checked=""/>
<label class="flix-checkbox__label" for="method-credit-card">
<div class="flix-h4 flix-h4--space-flush flix-space-half-top">Credit Card</div>
</label>
</div>
<div class="flix-choice-wrapper__content flix-choice-wrapper__content--expanded credit-card-content">
<div class="flix-form-row">
<div class="flix-input">
<label class="flix-label flix-input__label" for="card-number">Card Number</label>
<div class="flix-input__container"><input type="text" id="card-number" class="flix-input__field"/></div>
</div>
</div>
<div class="flix-form-row flix-grid">
<div class="flix-col flix-input">
<label class="flix-label flix-input__label" for="expiration-date">Expiration date</label>
<div class="flix-input__container"><input type="text" id="expiration-date" class="flix-input__field"/></div>
</div>
<div class="flix-col flix-input">
<label class="flix-label flix-input__label" for="card-cvc">CVC</label>
<div class="flix-input__container"><input type="text" id="card-cvc" class="flix-input__field"/></div>
</div>
</div>
<div class="flix-input">
<label class="flix-label flix-input__label" for="card-holder-name">Card holder name</label>
<div class="flix-input__container"><input type="text" id="card-holder-name" class="flix-input__field"/></div>
</div>
</div>
</div>
<div class="flix-choice-wrapper__item">
<div class="flix-checkbox">
<input class="flix-checkbox__input" type="checkbox" name="payment-method" id="method-paypal" aria-describedby="payment-method-info"/>
<label class="flix-checkbox__label" for="method-paypal">
<div class="flix-h4 flix-h4--space-flush flix-space-half-top">PayPal</div>
</label>
</div>
</div>
<div class="flix-choice-wrapper__item">
<div class="flix-checkbox">
<input class="flix-checkbox__input" type="checkbox" name="payment-method" id="method-klarna" aria-describedby="payment-method-info" data-toggle="klarna-content" data-toggle-class="flix-choice-wrapper__content--expanded"/>
<label class="flix-checkbox__label" for="method-klarna">
<div class="flix-h4 flix-h4--space-flush flix-space-half-top">Sofort</div>
</label>
</div>
<div class="flix-choice-wrapper__content klarna-content">
<div class="flix-input">
<label class="flix-label flix-input__label" for="klarna-email">E-mail</label>
<div class="flix-input__container"><input type="email" id="klarna-email" class="flix-input__field"/></div>
</div>
</div>
</div>
<span class="flix-choice-wrapper__info" id="payment-method-info">Extra information related to the component state</span>
</div>
</fieldset>