Skip to content

Fieldset

A container that groups related form elements, including labels, controls, and helper text, to create accessible and organized input sections. Fieldsets improve the structure and clarity of complex forms.

Usage

Use fieldsets to logically group related inputs, such as multiple options within a survey or sections of a settings form. Each fieldset should include a descriptive legend or label to maintain accessibility and provide context for users navigating the form.

API Reference

Component attribute(s)

x-h-fieldset
x-h-legend
x-h-field-group
x-h-field
x-h-field-content
x-h-field-title
x-h-field-description
x-h-field-error

Attributes

x-h-field

AttributeValuesRequiredDescription
data-disabledbooleanfalseApplies a disabled style to the field and label. Does NOT disable inputs.
data-orientationvertical
horizontal
responsive
falseChanges the alignment of the label and input.

x-h-field-description

AttributeValuesRequiredDescription
data-hide-on-errorbooleanfalseWhen enabled, the description will be hidden when the input is invalid, and the error message will appear instead.

Modifiers

x-h-legend

ModifierDescription
labelMakes the legend text smaller.

Examples

html
<form>
  <div x-h-field-group>
    <fieldset x-h-fieldset>
      <legend x-h-legend>Card Payment</legend>
      <p x-h-field-description>Enter your card and billing information</p>
      <div x-h-field-group>
        <div x-h-field>
          <label x-h-label for="formCardName">Name on Card</label>
          <input x-h-input id="formCardName" placeholder="John Doe" required />
        </div>
        <div x-h-field>
          <label x-h-label for="formCardNumber">Card Number</label>
          <input x-h-input type="text" id="formCardNumber" placeholder="2141 9614 2401 7895" required />
          <p x-h-field-error>Enter your 16-digit card number</p>
          <p x-h-field-description data-hide-on-error="true">This is just a demo. Do NOT enter your real card number.</p>
        </div>
        <div class="grid grid-cols-3 gap-4">
          <div x-h-field>
            <label x-h-label for="formCardMonth">Month</label>
            <div x-h-select>
              <input id="formCardMonth" x-h-select-input placeholder="MM" required />
              <div x-h-select-content>
                <div x-h-select-option="'01'" data-value="01"></div>
                <div x-h-select-option="'02'" data-value="02"></div>
                <div x-h-select-option="'03'" data-value="03"></div>
                <div x-h-select-option="'04'" data-value="04"></div>
                <div x-h-select-option="'05'" data-value="05"></div>
                <div x-h-select-option="'06'" data-value="06"></div>
                <div x-h-select-option="'07'" data-value="07"></div>
                <div x-h-select-option="'08'" data-value="08"></div>
                <div x-h-select-option="'09'" data-value="09"></div>
                <div x-h-select-option="'10'" data-value="10"></div>
                <div x-h-select-option="'11'" data-value="11"></div>
                <div x-h-select-option="'12'" data-value="12"></div>
              </div>
            </div>
          </div>
          <div x-h-field>
            <label x-h-label for="formCardYear">Year</label>
            <div x-h-select>
              <input id="formCardYear" x-h-select-input placeholder="YYYY" required />
              <div
                x-h-select-content
                x-data="{
                  years: (() => {
                    let year = new Date().getFullYear();
                    let allYears = [];
                    for (let y = 0; y <= 10; y++) allYears.push(year + y);
                    return allYears;
                  })(),
                }"
              >
                <template x-for="year in years">
                  <div x-h-select-option="year" :data-value="year"></div>
                </template>
              </div>
            </div>
          </div>
          <div x-h-field>
            <label x-h-label for="formCVV">CVV</label>
            <input x-h-input id="formCVV" placeholder="123" required />
          </div>
        </div>
      </div>
    </fieldset>
    <div x-h-separator data-orientation="horizontal"></div>
    <fieldset x-h-fieldset>
      <legend x-h-legend>Delivery time</legend>
      <p x-h-field-description>The date and time when the package will be delivered to you</p>
      <div x-h-field-group>
        <div class="grid grid-cols-2 gap-4">
          <div x-h-field>
            <label x-h-label for="delivery-dp">Date</label>
            <div x-h-date-picker>
              <input type="text" id="delivery-dp" required />
              <button x-h-date-picker-trigger aria-label="Choose date"></button>
              <div x-h-calendar></div>
            </div>
          </div>
          <div x-h-field>
            <label x-h-label for="delivery-tp">Time</label>
            <div x-h-time-picker>
              <input type="text" id="delivery-tp" x-h-time-picker-input required />
              <div x-h-time-picker-popup></div>
            </div>
          </div>
        </div>
      </div>
    </fieldset>
    <div x-h-separator data-orientation="horizontal"></div>
    <fieldset x-h-fieldset>
      <legend x-h-legend>Billing Address</legend>
      <p x-h-field-description>The billing address associated with your payment method</p>
      <div x-h-field-group>
        <div x-h-field data-orientation="horizontal">
          <span x-h-checkbox>
            <input type="checkbox" id="formShippingCheckbox" checked />
          </span>
          <label x-h-label for="formShippingCheckbox" class="font-normal">Same as shipping address</label>
        </div>
      </div>
    </fieldset>
    <fieldset x-h-fieldset>
      <div x-h-field-group>
        <div x-h-field>
          <label x-h-label for="formComments">Comments</label>
          <textarea x-h-textarea id="formComments" placeholder="Add any additional comments" class="resize-none"></textarea>
        </div>
      </div>
    </fieldset>
    <div x-h-field data-orientation="horizontal">
      <span class="flex-1"></span>
      <button x-h-button data-variant="primary" type="submit">Submit</button>
      <button x-h-button data-variant="outline" type="button">Cancel</button>
    </div>
  </div>
</form>

Invalid field with error message

When you type something in the input below, it will no longer be invalid and the error message will disappear.

html
<form>
  <fieldset x-h-fieldset>
    <div x-h-field-group>
      <div x-h-field>
        <label x-h-label for="errorMessage">Invalid</label>
        <input x-h-input id="errorMessage" placeholder="Input invalid" required />
        <p x-h-field-error>The input cannot be empty</p>
      </div>
    </div>
  </fieldset>
</form>

Field with description and error message

When you type something in the input below, the error message will dissapear and the description will be shown.

html
<form>
  <fieldset x-h-fieldset>
    <div x-h-field-group>
      <div x-h-field>
        <label x-h-label for="descError">Word</label>
        <input x-h-input id="descError" placeholder="Something" required />
        <p x-h-field-error>Must not be empty!</p>
        <p x-h-field-description data-hide-on-error="true">This filed holds random text.</p>
      </div>
    </div>
  </fieldset>
</form>

Responsive field

You may need to resize the window to see it switching between horizintal and vertical.

html
<form>
  <fieldset x-h-fieldset>
    <div x-h-field-group>
      <div x-h-field data-orientation="responsive">
        <label x-h-label for="responsiveDemo">Word</label>
        <input x-h-input id="responsiveDemo" placeholder="Something" />
      </div>
    </div>
  </fieldset>
</form>

Horizontal field

html
<form>
  <fieldset x-h-fieldset>
    <div x-h-field-group>
      <div x-h-field data-orientation="horizontal">
        <label x-h-label for="horizontalDemo">Word</label>
        <input x-h-input id="horizontalDemo" placeholder="Something" />
      </div>
    </div>
  </fieldset>
</form>

Horizontal field with description and error message

In horizontal orientation the label stays beside the input, while the error and description are shown below the input. When you type something in the input below, the error message will disappear and the description will be shown.

html
<form>
  <fieldset x-h-fieldset>
    <div x-h-field-group>
      <div x-h-field data-orientation="horizontal">
        <label x-h-label for="horizontalDescError">Word</label>
        <input x-h-input id="horizontalDescError" placeholder="Something" required />
        <p x-h-field-error>Must not be empty!</p>
        <p x-h-field-description data-hide-on-error="true">This field holds random text.</p>
      </div>
    </div>
  </fieldset>
</form>

Disabled field with enabled input


html
<form>
  <fieldset x-h-fieldset>
    <div x-h-field-group>
      <div x-h-field data-disabled="true">
        <label x-h-label for="visuallyDisabled">Label Disabled</label>
        <input x-h-input id="visuallyDisabled" placeholder="Input still active" />
      </div>
    </div>
  </fieldset>
</form>

Disabled field with disabled input


html
<form>
  <fieldset x-h-fieldset>
    <div x-h-field-group>
      <div x-h-field data-disabled="true">
        <label x-h-label for="visuallyDisabled">Label Disabled</label>
        <input x-h-input id="visuallyDisabled" placeholder="Input inactive" disabled />
      </div>
    </div>
  </fieldset>
</form>