Honeycomb

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.

Your favorite Ramen taste?
Info message
<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.

Your favorite Ramen taste?
Error message Info message
<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 --error modifiers to your fieldset and form elements to enable error visual appearance;
  • Add aria-invalid to the inputs and fieldsets to inform assistive technologies that an error occurred;
  • Finally, connect any error messages with the invalid inputs using an id and aria-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.

Please tell us your personal information for non particular reason.
<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:

Are you a dog person?
Info message
<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>