skip to Main Content

I want to hide an optgroup element when it doesn’t have any option element which cannot be selected. In the example below the first optgroup element shall be shown and the second should be hidden.

optgroup {
    display: none;
}
optgroup:has(option:not(:disabled)) {
    display: unset;
}
<select id="location" name="location">
    <option value="" selected="">Standort wählen</option>
    <optgroup label="Kanton Luzern">
        <option value="buttisholz">Buttisholz</option>
        <option value="littau" disabled="">Littau</option>
        <option value="luzern">Luzern</option>
        <option value="malters" disabled="">Malters</option>
        <option value="schuepfheim">Schüpfheim</option>
    </optgroup>
    <optgroup label="Kanton Schaffhausen">
        <option value="schaffhausen" disabled="">Schaffhausen</option>
    </optgroup>
</select>

I have come up with this solution which seems to work (only tested in Chrome) but I am looking for a solution with just one statement instead of 2 if that is possible:

optgroup {
  display: none;
  }
optgroup:has(option:not(:disabled)) {
  display: unset;
  }

I tried this version which doesn’t work because it seems that the :enabled pseudo selector can only be used for input, select and textarea fields:

optgroup:not(option:enabled) {
  display: none;
  }

2

Answers


  1. Here’s a single-statement solution that should work across modern browsers and provide the desired behavior of hiding optgroup elements that do not have any non-disabled option elements.

    optgroup:not(:has(option:not(:disabled))) {
      display: none;
    }
    

    Here’s how it works:

    • The optgroup:not(:has(option:not(:disabled))) selector selects all
      optgroup elements that do not have a child option element that is not
      disabled.

    • The :has() pseudo-class is used to check if the optgroup element has
      a child option element that is not disabled.

    • The :not() pseudo-class is then used to negate this condition,
      effectively targeting the optgroup elements that do not have any
      non-disabled option elements as children.

    • The display: none; rule is then applied to the targeted optgroup
      elements, hiding them.

    Login or Signup to reply.
  2. Keep it simple and readable!

    use css :enabled

    optgroup:not(:has(option:enabled)) {
      display: none;
    }
    <select id="location" name="location">
      <option value="" selected   disabled > Standort wählen </option>
      <optgroup label="Kanton Luzern">
          <option value="buttisholz"       > Buttisholz </option>
          <option value="littau"  disabled > Littau     </option>
          <option value="luzern"           > Luzern     </option>
          <option value="malters" disabled > Malters    </option>
          <option value="schuepfheim"      > Schüpfheim </option>
      </optgroup>
      <optgroup label="Kanton Schaffhausen">
          <option value="schaffhausen" disabled > Schaffhausen </option>
      </optgroup>
    </select>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search