Fieldset
Fieldset component is used to group several inputs that are related to each other in nature.
Grouping form elements inside of a form helps users understand that those form controls are related to each other in nature.
For example:
- User information: "First name", "Last name", "Date of birth".
- Trip details: "Origin", "Destination", "Departure date", "Return date"
- Contact details: "Telephone number", "Address", "E-mail address"
A fieldset is captioned by a legend and the legend should be the first element of the fieldset.
A container around the items (flix-fieldset__items) is required to control the form items, such as item spacing and
items layout.
Modifiers
-
flix-fieldset--error - Enables error state and highlights first info message as error message. Must be used in combination with respective form fields error state.
-
flix-fieldset--horizontal - Renders the form items horizontally.
-
flix-fieldset--no-wrap - When used with horizontal modifier, prevents items from wrapping to a new line on smaller screens.
-
flix-fieldset--item-space-{number} - Used to customize the space between items. All space options are available for fieldset item spacings.
Grouping radios
The most common use case for fieldsets is to group radios and checkboxes groups that share the same label (the legend).
When grouping radio groups it is recommended to use the role="radiogroup" attribute on the fieldset for
improved accessibility.
For groups of radios and checkboxes, it makes more sense to use flix-fieldset__info for error and info messages.
<fieldset class="flix-fieldset">
<legend class="flix-legend">Your favorite Ramen taste?</legend>
<div class="flix-fieldset__items">
<div class="flix-fieldset__item">
<div class="flix-radio">
<input class="flix-radio__input" type="radio" name="fieldset-0" id="shio" value="Shio"/>
<label class="flix-radio__label" for="shio">Shio</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio">
<input class="flix-radio__input" type="radio" name="fieldset-0" id="shoyu" checked="" value="Shoyu"/>
<label class="flix-radio__label" for="shoyu">Shoyu</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio">
<input class="flix-radio__input" type="radio" name="fieldset-0" id="miso" value="Miso"/>
<label class="flix-radio__label" for="miso">Miso</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio">
<input class="flix-radio__input" type="radio" name="fieldset-0" id="tonkotsu" value="Tonkotsu"/>
<label class="flix-radio__label" for="tonkotsu">Tonkotsu</label>
</div>
</div>
</div>
<span class="flix-fieldset__info" id="fieldset-0-infoError" aria-live="assertive"></span>
<span class="flix-fieldset__info" id="fieldset-0-info">Info message</span>
</fieldset>Error state
Fieldsets can have an --error modifier, that will make the first info message with danger color, so that should be
used for your error message. You must also add the respective error modifiers for the individual form inputs.
<fieldset class="flix-fieldset flix-fieldset--error">
<legend class="flix-legend">Your favorite Ramen taste?</legend>
<div class="flix-fieldset__items">
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--error">
<input class="flix-radio__input" type="radio" name="fieldset-2" id="shio-err" aria-errormessage="fieldset-2-infoError" aria-describedby="fieldset-2-info" value="Shio"/>
<label class="flix-radio__label" for="shio-err">Shio</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--error">
<input class="flix-radio__input" type="radio" name="fieldset-2" id="shoyu-err" aria-errormessage="fieldset-2-infoError" aria-describedby="fieldset-2-info" checked="" value="Shoyu"/>
<label class="flix-radio__label" for="shoyu-err">Shoyu</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--error">
<input class="flix-radio__input" type="radio" name="fieldset-2" id="miso-err" aria-errormessage="fieldset-2-infoError" aria-describedby="fieldset-2-info" value="Miso"/>
<label class="flix-radio__label" for="miso-err">Miso</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--error">
<input class="flix-radio__input" type="radio" name="fieldset-2" id="tonkotsu-err" aria-errormessage="fieldset-2-infoError" aria-describedby="fieldset-2-info" value="Tonkotsu"/>
<label class="flix-radio__label" for="tonkotsu-err">Tonkotsu</label>
</div>
</div>
</div>
<span class="flix-fieldset__info" id="fieldset-2-infoError" aria-live="assertive">Error message</span>
<span class="flix-fieldset__info" id="fieldset-2-info">Info message</span>
</fieldset>A few things to keep in mind when working with error states:
- Add appropriate
--errormodifiers to your fieldset and form elements to enable error visual appearance; - Add
aria-invalidto the inputs and fieldsets to inform assistive technologies that an error occurred; - Finally, connect any error messages with the invalid inputs using an
idandaria-errormessage; - Add
aria-live="assertive"to error messages to inform assistive technologies to read the error right away;
Horizontal layout
You can show the fieldset items side by side by using the horizontal modifier. By default they will wrap to a new line
if there is not enough space, but you can disable wrapping with the no-wrap modifier.
<fieldset class="flix-fieldset flix-fieldset--horizontal flix-fieldset--no-wrap" aria-label="User personal information">
<div class="flix-fieldset__items">
<div class="flix-fieldset__item">
<div class="flix-input">
<label class="flix-label flix-input__label" for="first-name">
First name
</label>
<div class="flix-input__container">
<input class="flix-input__field" id="first-name" type="text" aria-describedby="fieldset-6-info" value="Ash"/>
<span class="flix-input__feedback-icon" aria-hidden="true"></span>
</div>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-input">
<label class="flix-label flix-input__label" for="last-name">
Last name
</label>
<div class="flix-input__container">
<input class="flix-input__field" id="last-name" type="text" aria-describedby="fieldset-6-info" value="Ketchum"/>
<span class="flix-input__feedback-icon" aria-hidden="true"></span>
</div>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-input">
<label class="flix-label flix-input__label" for="age">
Age
</label>
<div class="flix-input__container">
<input class="flix-input__field" id="age" type="number" aria-describedby="fieldset-6-info" value="10"/>
<span class="flix-input__feedback-icon" aria-hidden="true"></span>
</div>
</div>
</div>
</div>
<span class="flix-fieldset__info" id="fieldset-6-info">Please tell us your personal information for non particular reason.</span>
</fieldset>Custom item space
You can use --item-space modifiers to customize the space between the items. All space options that are available for
the space helpers are also available for fieldset item space modifiers.
Simply add --item-space-{number} where number is a space name, the fieldset component will add proper space between
the items independently of item direction.
You can also use --item-space-{flush} to completely remove the space between the items;
<fieldset class="flix-fieldset flix-fieldset--item-space-half" aria-label="Agreement options">
<div class="flix-fieldset__items">
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--sm">
<input class="flix-radio__input" type="radio" name="agreed-8" id="yes-8" value="Yes"/>
<label class="flix-radio__label" for="yes-8">Yes</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--sm">
<input class="flix-radio__input" type="radio" name="agreed-8" id="ja-8" value="Ja"/>
<label class="flix-radio__label" for="ja-8">Ja</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--sm">
<input class="flix-radio__input" type="radio" name="agreed-8" id="sim-8" value="Sim"/>
<label class="flix-radio__label" for="sim-8">Sim</label>
</div>
</div>
</div>
<span class="flix-fieldset__info" id="fieldset-8-infoError" aria-live="assertive"></span>
</fieldset>Deprecated fieldset
The deprecated markup does not include the __items container to control items layout and spacing. Instead the items
spacing should be controlled individually with flix-fieldset__item--space-{number} modifiers which added a top or left
margin depending on orientation.
This was problematic on smaller screens when items had to wrap to a new line but kept theirs margins, causing a bug in the layout.
You should migrate to the newer markup as soon as possible, but for now the deprecated markup is still supported.
Examples:
<fieldset class="flix-fieldset flix-fieldset--horizontal">
<legend class="flix-legend">Are you a dog person?</legend>
<div class="flix-fieldset__item">
<div class="flix-checkbox">
<input class="flix-checkbox__input" type="checkbox" id="yes-deprec" aria-describedby="fieldset-4-info" value="agreed-0"/>
<label class="flix-checkbox__label" for="yes-deprec">
Yes
</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-checkbox">
<input class="flix-checkbox__input" type="checkbox" id="certainly-deprec" aria-describedby="fieldset-4-info" value="agreed-1"/>
<label class="flix-checkbox__label" for="certainly-deprec">
Certainly
</label>
</div>
</div>
<div class="flix-fieldset__item">
<div class="flix-checkbox">
<input class="flix-checkbox__input" type="checkbox" id="absolutely-deprec" aria-describedby="fieldset-4-info" value="agreed-2"/>
<label class="flix-checkbox__label" for="absolutely-deprec">
Absolutely
</label>
</div>
</div>
<span class="flix-fieldset__info" id="fieldset-4-info">Info message</span>
</fieldset><fieldset class="flix-fieldset" aria-label="Agreement options">
<div class="flix-fieldset__item">
<div class="flix-radio flix-radio--sm">
<input class="flix-radio__input" type="radio" name="agreed-9" id="yes-9" value="Yes"/>
<label class="flix-radio__label" for="yes-9">Yes</label>
</div>
</div>
<div class="flix-fieldset__item flix-fieldset__item--space-half">
<div class="flix-radio flix-radio--sm">
<input class="flix-radio__input" type="radio" name="agreed-9" id="ja-9" value="Ja"/>
<label class="flix-radio__label" for="ja-9">Ja</label>
</div>
</div>
<div class="flix-fieldset__item flix-fieldset__item--space-half">
<div class="flix-radio flix-radio--sm">
<input class="flix-radio__input" type="radio" name="agreed-9" id="sim-9" value="Sim"/>
<label class="flix-radio__label" for="sim-9">Sim</label>
</div>
</div>
</fieldset>