How should the new <selectedoption> element work?
Jake Archibald explores customizable web elements, presenting options for content synchronization between selections and displays. He seeks developer feedback to inform HTML specification discussions before the next OpenUI meeting.
Read original articleJake Archibald discusses the upcoming ability to fully style and customize elements in web development, focusing on how content should be managed when selections change. He presents various options for handling the synchronization of content between a selected option and its display in a user interface. The first option suggests that no automatic updates occur unless explicitly triggered, allowing developers to control when content is refreshed. The second option proposes automatic updates whenever the selected option changes, which could lead to excessive cloning and resetting of states. A debounced approach is also considered, which would reduce unnecessary updates but may introduce timing issues. Another option involves targeted DOM changes, allowing for more granular updates without resetting all content. Archibald seeks feedback from developers on these options, emphasizing the need for a consensus as this topic is actively discussed in the HTML specification. He encourages input through various channels, including social media and developer forums, to gather a broader perspective before presenting at the next OpenUI meeting.
- Jake Archibald is exploring customizable elements in web development.
- He presents multiple options for managing content synchronization between selected options and their displays.
- Options range from manual updates to automatic synchronization, each with potential pros and cons.
- Archibald seeks developer feedback to inform discussions in the HTML specification.
- Input can be shared through comments, social media, or developer forums.
Related
Don't Use JavaScript for That: Moving Features to CSS and HTML [video]
The video discusses the benefits of using HTML and CSS over JavaScript in web development, focusing on efficiency and inclusivity. It demonstrates creating custom switches with HTML checkboxes and CSS, emphasizing accessibility and styling techniques like "appearance: none".
Video with Alpha Transparency on the Web
Jake Archibald discusses challenges with web videos featuring alpha transparency, proposing a solution that splits video streams and utilizes WebGL for better performance, while providing encoding instructions for developers.
A better HTML input experience (custom elements and the AOM) (2017)
The article highlights accessibility challenges with custom web elements, advocating for the HowTo: Components project and the Accessibility Object Model (AOM) to improve semantic meaning and support for assistive technologies.
Sanding UI
Jim Nielsen compares software development to woodworking, highlighting iterative testing and user interaction. He resolved a UI issue caused by flexbox spacing by using padding, emphasizing continuous refinement for better user experience.
Canvases versus Documents
The article examines web design trends, advocating for readability over immersive text, criticizing cluttered homepages, praising clarity in well-designed sites, and urging designers to focus on meaningful features.
If the developer wants a <selectedoption>, they should fill it with <option> elements that correspond to the <option> elements that appear in the dropdown. Each option could reuse the <label for=""> pattern to associate them with their counterpart.
Then, when an option is selected by the end user, the corresponding option inside the <selectedoption> would get a `selected` attribute.
The default CSS would be:
selectedoption > option { display: none; } selectedoption > option[selected] { display: block; }
This gives complete control to the developer, works fine without JS, and wouldn't have shocking side effects.
As they say, "duplication is cheaper than the wrong abstraction".
1. Declarative camp, where people expect two differently stylable copies of `<option>` somewhere in `<select>`. I don't think the exact copying mechanism and timing is very important here, as long as it can be safely done and works without JS.
2. Programmable camp, where people want the full control over appearance and behavior. We can reasonably assume that JS is required for this camp, and they generally have better understanding of what gets rendered or not in the first place.
Given both requirements, it seems wise to couple the clone timing with the event processing, which most cases in the second camp would have to do anyway. In the other words, the `input` event would have the default behavior of full cloning, and that default behavior should be prevented via `e.preventDefault()`. The second camp will almost always use this option and can use their own `MutationObserver` or similar to implement edge cases described in the OP. The timing and extent for the default behavior can be then optimized without affecting the second camp. It is even possible to distinguish two camps via different values of the `appearance` CSS property.
Sidetrack: It seems that `<selectedoption>` indeed exists mainly to distinguish two camps? But that leaves many edge cases like multiple `<selectedoption>` elements I believe. Maybe something like `<select reflect="foo"><button><option id="foo">...</option></button>...</select>` might be more appropriate. (`<output>` was my initial thought, but `<option>` would be more regular since it can't nest.)
<select name="commenters">
<option value="annevk">Anne van Kesteren</option>
<option value="jakearchibald">
<label>Jake Archibald</label>
<selectedcontent>
<div>
<img src="profile.avif" alt="Jake's photo">
<div>Jake Archibald<br><small>@jakearchibald</small></div>
</div>
</selectedcontent>
</option>
<option value="sorvell">Steve Orvell</option>
</select>
The value attribute would be required when using these new sub elements. This structure feels familiar and progressive to me.Naively, I would imagine that the following JavaScript would cause 1 DOM update, 1 redraw of the option if the dropdown is open, and 1 redraw of the selected option:
document.querySelector('option:selected selectedcontent').innerHTML = 'Jake Archibald';
Obviously, things are different when using multiple. Maybe a `select > selectedcontent` element containing a copy of each `option > selectedcontent` element that is updated on change events.But furthermore, I think it should be possible to turn <selectedoption> mirroring entirely off, e.g. with an attribute like <selectedoption mirroring="none">, and I think most developers using reactive frameworks should prefer to do that.
If I'm using any reactive framework designed to do targeted DOM updates, I want my framework to be in complete control. When an option is selected, I'll populate <selectedoption> myself. When an <option> is modified, I modified it, and I know which <option> is selected, so I'll perform a targeted DOM update of <selectedoption> as well.
You had a whole separate podcast episode about how/why having the browser itself do targeted DOM updates is an enormous can of worms, mostly for attribute vs. property reasons. https://offthemainthread.tech/episode/putting-react-in-the-b... And anyway, every framework wants to handle mutations differently, and framework designers are in consensus that we haven't picked a clear winner yet. So, as nice as it would be if we had a replaceHTML API that everybody loved, we don't have that now, and we shouldn't hold up customizable <select> for this.
<selectedoption> mirroring is for folks who don't want to use any JavaScript (and I think that's a good thing). In that case, mirroring all updates automatically, synchronously, is the simplest thing that can possibly work.
Developers who want optimal performance want full control, and they just want to turn mirroring entirely off.
This shouldn't be a literal new element. It should be a psuedo-element like other component parts like `::-[engine]-slider-thumb` are. You can then style `select::selected-option` and not have to mangle your HTML or worry about mirroring HTML.
You can just not provide selectedoption or provide it in a limited way, and see what patterns emerge in how people use it in practice. Maybe it'll turn out that people want something completely different from selectedoption's current design. Maybe it'll turn out that people often want to display something different between the select menu and the select button and selectedoption doesn't actually bring much to the table.
So that leaves the various automatic options, either synchronous, debounced, or the fancy targeted version. This seems like a pretty straightforward complexity/performance tradeoff to me, with the synchronous version being the simplest (both to implement and to understand) and going up from there.
With that in mind, I'm inclined toward the middle option (changes are synced automatically, but batched in the next microtask) since it feels like the best balance of complexity/usability. Seems like it would eliminate some of the biggest performance footguns, without being too much of a bear to implement or too difficult to understand.
On the other hand, I would personally also be ok with no syncing at all, just the initial clone when an option is selected, if it would mean we get this feature sooner. Really looking forward to not having to roll my own dropdowns.
So the main target audience for selectedoption is probably people not using a framework, and using no or little JavaScript. That audience probably would want selectedoption to "just work" without having to manually call a function to reset things. So while option 1 seems like a reasonable option to me personally as someone who mainly works with React, it's probably not what most people using selectedoption would want.
Option 2 just has too much potential for introducing hard to debug and hard to fix performance issues, so I feel like it's automatically not the best choice. Its main advantage is that it's probably the most straightforward to understand/explain.
Option 4 would help with the performance issues, but it sounds like it would be a nightmare for browsers to implement. It would also be a bit difficult to explain to devs how exactly it works and what edge cases need to be considered (like mutating the selectedoption "fork" potentially causing issues).
So by process of elimination option 3 seems like the best to me. It solves the performance issues but it's still pretty easy to understand/explain. It's main disadvantage seems to be that from the perspective of code running synchronously it's possible for the selectedoption and option to get out of sync, but 1) it's a bit hard to imagine a practical use case for needing to do this kind of comparison and 2) simply waiting until the next microtask before doing the comparison would probably be an easy fix even if this is a problem in some cases.
For all of these options, it might be useful for there to be some way to intercept the default behavior. For example maybe there could be some event such that calling .preventDefault() inside an event handler has the side effect of preventing the selectedoption from being reset, if resetting it is not desired. Of course you don't need to use selectedoption at all if the automatic resetting is not desired, but maybe there will be some cases where you only want to make an exception in a few cases but generally do want the selectedoption default behavior.
I would strongly suggest this option unless there's a strong reason the browser must keep the elements in sync automatically.
Unless I'm mistaken, the other options could all be done in userland with a MutationObserver, a debounce method wrapping a timeout, and custom logic optimizing updates for specific attributes or changes.
I'm particularly worried about how automatic updates/cloning will work across different frontend frameworks. Today's more popular frameworks already diverge quite a bit with how they handle rerendering and DOM updates, and the next big framework to come along could take a more radical approach to rendering and interactivity.
In my opinion, anything that can reasonably be done in user code should be done there - at least until it causes enough problems that it needs to be solidified into browser specs. I'm always worried that the any clever built-in magic may work today but cause problems later, and because removing the spec is difficult most users would just skip the new <selectedoption> element all together.
It never fails to amaze me how many bad semi functional “select” controls I encounter on a regular basis. I must be part of the small minority that fills out forms entirely with the keyboard using the tab key and prefix matching.
Existing solutions solve enough use cases, and the remaining use cases can use javascript to build whatever they like.
To me it's a bad idea from the top.
Either leave reactive updates to frameworks, or develop a general built-in reactive framework. Building a one-off that introduces an all-new pattern into the browser seems like a perpetual headache.
option::picker-current { ... }
Please, just No!
The CSS for the style of the element belongs with the `select` tag. And all that should be needed to demark the selected option is a matching `value` attribute.
I get the sense that the people currently working on HTML and CSS are front-end designers and not programmers. We need functional design, polymorphism and simplicity, not just more kitchen sinks.
Related
Don't Use JavaScript for That: Moving Features to CSS and HTML [video]
The video discusses the benefits of using HTML and CSS over JavaScript in web development, focusing on efficiency and inclusivity. It demonstrates creating custom switches with HTML checkboxes and CSS, emphasizing accessibility and styling techniques like "appearance: none".
Video with Alpha Transparency on the Web
Jake Archibald discusses challenges with web videos featuring alpha transparency, proposing a solution that splits video streams and utilizes WebGL for better performance, while providing encoding instructions for developers.
A better HTML input experience (custom elements and the AOM) (2017)
The article highlights accessibility challenges with custom web elements, advocating for the HowTo: Components project and the Accessibility Object Model (AOM) to improve semantic meaning and support for assistive technologies.
Sanding UI
Jim Nielsen compares software development to woodworking, highlighting iterative testing and user interaction. He resolved a UI issue caused by flexbox spacing by using padding, emphasizing continuous refinement for better user experience.
Canvases versus Documents
The article examines web design trends, advocating for readability over immersive text, criticizing cluttered homepages, praising clarity in well-designed sites, and urging designers to focus on meaningful features.