picocss / pico

Minimal CSS Framework for semantic HTML
https://picocss.com
MIT License
13.49k stars 390 forks source link

Dropdown in dropdown events not passing through due to ::before close pseudoelement #614

Open mwargan opened 1 day ago

mwargan commented 1 day ago

Please search for duplicate or closed issues first.

Describe the issue

When placing a dropdown in a dropdown, the click events of elements inside the parent dropdown get masked and non-clickable due to the ::before element that is used as the "click on background to close" handler.

Current Behavior

All elements within a dropdown containing another dropdown non-clickable except for the last child-dropdown.

Expected Behavior

The click events to work as expected

Reproduction URL

https://jsfiddle.net/f9v860hk/3/

<details class="dropdown">
   <summary> Select a phase of matter... </summary>
   <ul>
      <li><label><input type="radio" name="phase" value="solid"> Solid </label></li>
      <li><label><input type="radio" name="phase" value="liquid"> Liquid </label></li>
      <li>
         <details>
            <summary> This is a dropdown option </summary>
            <ul>
               <li><label><input type="radio" name="phase" value="gas"> Gas </label></li>
               <li><label><input type="radio" name="phase" value="plasma"> Plasma </label></li>
            </ul>
         </details>
      </li>
      <li>
         <details>
            <summary> This is a dropdown option 2 </summary>
            <ul>
               <li><label><input type="radio" name="phase" value="gas"> Gas </label></li>
               <li><label><input type="radio" name="phase" value="plasma"> Plasma </label></li>
            </ul>
         </details>
      </li>
   </ul>
</details>

Environment

Safari MacOS, probably others.

Suggested fix

/*
* Fix Option 1 - do not render ::before when details not open
*
*
*/
details:not([open]) > summary::before {
  content: none !important;
}

/*
* Fix Option 2 - do not render ::before on children
*
*
*/
details details:not([open]) > summary::before {
  content: none !important;
}

obviously more specific selectors would have to be used / written a bit better so as to avoid the use of !important, but I just didn't look into it much more yet.

mwargan commented 23 hours ago

Note my suggested fix fails in the case of having another dropdown as a direct child of details (rather than in a ul as I've shown in the original issue):

<details class="dropdown">
  <summary>Select a phase of matter...</summary>
  <details>
    <summary>This is a dropdown option</summary>
    <ul>
      <li>
        <label><input type="radio" name="phase" value="gas" /> Gas </label>
      </li>
      <li>
        <label
          ><input type="radio" name="phase" value="plasma" /> Plasma
        </label>
      </li>
    </ul>
  </details>
  <details>
    <summary>This is a dropdown option</summary>
    <ul>
      <li>
        <label><input type="radio" name="phase" value="gas" /> Gas </label>
      </li>
      <li>
        <label
          ><input type="radio" name="phase" value="plasma" /> Plasma
        </label>
      </li>
    </ul>
  </details>
</details>
mwargan commented 13 hours ago

There is another problem in rendering that causes any details elements as children of a dropdown to also render as a dropdown. This is due to this line details.dropdown[open] summary::before which selects all summary children.

mwargan commented 13 hours ago

There is another problem in rendering that causes any details elements as children of a dropdown to also render as a dropdown. This is due to this line details.dropdown[open] summary::before which selects all summary children.

mwargan commented 13 hours ago

There is another problem in rendering that causes any details elements as children of a dropdown to also render as a dropdown. This is due to this line details.dropdown[open] summary::before which selects all summary children.

I have issued a fix for this specific issue here https://github.com/picocss/pico/pull/615