data-show-when

Conditionally show or hide form sections based on another field's value. Hidden elements get hidden and inert attributes to bypass validation. Covers data-show-when and data-hide-when.

Overview

The data-show-when and data-hide-when attributes let you conditionally display form sections based on the value of another field. Hidden sections receive the hidden and inert attributes, which removes them from the tab order and bypasses any validation constraints inside. This is a combined page covering both attributes.

<select name="account-type"> <option value="personal">Personal</option> <option value="business">Business</option> </select> <fieldset data-show-when="account-type=business"> <legend>Business Details</legend> <input name="company" placeholder="Company name"> </fieldset>

How It Works

Add data-show-when or data-hide-when to any element inside a form. The init script:

  1. Parses the attribute value to extract the field name and optional target value
  2. Finds the referenced field within the closest <form> ancestor (or the document if no form exists)
  3. Attaches delegated change and input event listeners on the form
  4. Evaluates the condition on every field change and toggles hidden and inert on the conditional element
  5. Runs an initial evaluation on page load to set the correct visibility state
  6. Sets data-conditional-init to prevent double-binding

Because hidden elements receive the inert attribute, any required fields inside them will not block form submission. This lets you safely add validation to conditional sections without worrying about invisible required fields.

Attributes

Attribute Format Description
data-show-when "name=value" or "name" Shows the element when the named field matches the value (equality check) or has any value (truthy check).
data-hide-when "name=value" or "name" Hides the element when the condition is met. The inverse of data-show-when.
data-conditional-init boolean Set automatically to prevent double-binding. Do not set manually.

Condition Syntax

The attribute value supports two formats:

Syntax Meaning Example
name=value Equality check — the named field must have this exact value data-show-when="account-type=business"
name Truthy check — the named field has any non-empty value, or the checkbox is checked data-show-when="newsletter"

Hide When (Inverse)

Use data-hide-when for the inverse logic — the element is visible by default and hides when the condition matches.

<label> <input type="checkbox" name="gift" value="yes"> This is a gift </label> <form-field data-hide-when="gift=yes"> <label for="receipt">Send receipt to</label> <input type="email" id="receipt" name="receipt"> </form-field>

Radio Buttons

Conditions work with radio button groups. The condition evaluates against the currently selected radio value within the named group.

Delivery
Shipping Address
<fieldset> <legend>Delivery</legend> <label><input type="radio" name="delivery" value="pickup"> Pickup</label> <label><input type="radio" name="delivery" value="ship"> Ship</label> </fieldset> <fieldset data-show-when="delivery=ship"> <legend>Shipping Address</legend> <input name="address" placeholder="Street address"> </fieldset>

Truthy Check (Checkbox)

Omit the =value part to use a truthy check. For checkboxes, this means the element shows when the checkbox is checked. For text inputs and selects, it shows when the field has any non-empty value.

<label> <input type="checkbox" name="newsletter"> Subscribe to newsletter </label> <form-field data-show-when="newsletter"> <label for="freq">Frequency</label> <select id="freq" name="frequency"> <option>Weekly</option> <option>Monthly</option> </select> </form-field>

Supported Field Types

Conditions can reference any of the following field types by their name attribute:

  • Select — matches the selected option's value
  • Radio buttons — matches the checked radio's value within the named group
  • Checkboxes — equality check against the checkbox value, or truthy check against checked state
  • Text inputs — equality check against the current value, or truthy check for non-empty

Scope

The condition resolver looks for the referenced field within the closest <form> ancestor. If the conditional element is not inside a form, the resolver searches the entire document. This scoping prevents conflicts when multiple forms exist on the same page.

<!-- Scoped to closest <form> ancestor --> <form> <select name="plan"> <option value="free">Free</option> <option value="pro">Pro</option> </select> <fieldset data-show-when="plan=pro"> <legend>Pro Features</legend> <input name="api-key" placeholder="API key"> </fieldset> </form>

Validation Bypass

When a section is hidden, the inert attribute is applied alongside hidden. This means:

  • All required fields inside the hidden section are excluded from form validation
  • Users cannot tab into the hidden section
  • Screen readers skip the hidden content entirely
  • Click events inside the hidden section are blocked

When the section becomes visible again, both hidden and inert are removed, restoring full interactivity and validation.

Styling

Hidden conditional elements use native hidden and inert attributes. The default browser behavior of hidden is display: none, which already works without any custom CSS.

/* Hidden conditional sections use native hidden + inert */ [data-show-when][hidden], [data-hide-when][hidden] { display: none; } /* Optional: transition when revealing */ [data-show-when], [data-hide-when] { transition: opacity 0.2s ease; }

All behavior is gated on data-conditional-init. Without JavaScript, the conditional sections render in their default visible state — progressive enhancement.

Accessibility

  • The hidden attribute removes the element from visual display and the accessibility tree
  • The inert attribute ensures hidden content is completely non-interactive — no focus trapping in invisible fields
  • Required field validation is automatically bypassed for hidden sections, preventing invisible validation errors
  • Screen readers will not announce hidden conditional content
  • When content is revealed, focus order follows the natural DOM position
  • Event delegation on the form level avoids attaching listeners to individual fields
  • Without JavaScript, all sections are visible — progressive enhancement ensures no content is lost