Description
In the proposed appearance:base improvements for <select>
, we want to support the use case of rendering the full DOM contents of the currently selected <option>
into the select's button and let the author style it differently from the way it is styled in the <option>
without the use of script.
The currently proposed way to support this, as designed in OpenUI, is to have a <selectedoption>
element which copies contents from the selected <option>
and replaces its children with those contents every time that the selected <option>
changes.
There have been two ways of doing this which have been discussed:
- Call cloneNode on the selected
<option>
, and replace the light DOM children of<selectedoption>
with the result of cloneNode.- Authors can style the
<option>
and<selectedoption>
separately by selecting for those elements in their selectors. Since the cloned contents are in the light DOM, there is no new syntax needed.
- Authors can style the
<selectedoption>
has a UA shadowroot. Call cloneNode on the selected<option>
, and replace the contents of the<selecedoption>
's shadowroot with the cloneNode result. Since this could leak the shadowroot, we will use the proposed sanitizer API on the cloneNode result before appending it to the shadowroot. In order to let authors style all the content in the shadowroot, we will create a pseudo element which goes to the content of the UA shadowroot, and add new syntax to CSS to allow for these descendants of the pseudo element to be selected.
Here's a quick example which shows the usecase and what the API would be like in solution 1 vs solution 2. It is a country picker where we only want to render the picture of the country flag in the button without the text next to it in the dropdown.
<select>
<button type=popover>
<selectedoption></selectedoption>
</button>
<datalist>
<option>
<img src="country1.jpg">
<span>Country 1</span>
</option>
<option>
<img src="country2.jpg">
<span>Country 2</span>
</option>
</datalist>
</select>
Solution 1 CSS:
selectedoption > span {
display: none;
}
Solution 2 CSS:
selectedoption::selectedoption-content > span {
display:none;
}
This topic was previously discussed here: #9284