DEV Community

Cover image for How The NEW <selectedcontent> HTML Element Changes Selects Forever
Arnold Gunter
Arnold Gunter

Posted on • Edited on

9 2 2 1 1

How The NEW <selectedcontent> HTML Element Changes Selects Forever

Hello, fellow web dev

If you’ve ever built a <select> element in HTML, you know the pain: only plain, lifeless text shows up.

It’s a UI crime, honestly.

Not only does it look awful, but the user experience suffers as well.

All you see is plain text and with icons or extra styling, users could scan options faster — but that’s not possible.

And exactly this functionality is what developers have been asking for for decades.

Boom, it’s finally here.

We can customize our <select>!

So let's have a look

  • How it works
  • How to style it
  • Real world examples
  • Browser support

I go deeper into new HTML features like this in my weekly newsletter. If you liked this post, you shouldn't miss this weeks edition.

How It Was Before

If you wanted a rich dropdown — icons, HTML, maybe even interactive content — you needed to fake the dropdown using a combination of:

<div> or <ul> for the options,
custom styling,
a little JavaScript to handle opening, closing, and selection.
If you would try to nest HTML code inside the <option> tag, any browser that seems to render it is either ignoring your inner HTML or treating it as text. You’re stuck with plain text there — no structure, no icons, no nothing.

The New Way

Normally a <select> would look like this:

<label for="language">Choose a programming language:</label><br>
<select id="language" name="language">
  <option value="html">HTML</option>
  <option value="css">CSS</option>
  <option value="javascript">JavaScript</option>
  <option value="python">Python</option>
  <option value="ruby">Ruby</option>
</select>
Enter fullscreen mode Exit fullscreen mode

We have our basic tag with nested options.

It’s just a standard <select> with some <option>s—nothing fancy. And when it’s closed, all you see is the plain text label.

So… let’s style this up and not make it look like we are stuck in 1996!

In the first step we insert the new <selectedcontent> just before the first <option> tag, wrapped in a <button>. Just like this:

<label for="language">Choose a programming language:</label><br>
<select id="language" name="language">
  <button>
    <selectedcontent></selectedcontent>
  </button>
  <option value="html">HTML</option>
  <option value="css">CSS</option>
  <option value="javascript">JavaScript</option>
  <option value="python">Python</option>
  <option value="ruby">Ruby</option>
</select>
Enter fullscreen mode Exit fullscreen mode

Everytime the selected option changes, HTML creates in the background a clone of the entire HTML inside the <option> tag via cloneNode().

Then it gets displayed in the closed <select> element.

Hold up — this won’t work yet. First, we need to unlock the new styling engine...

Read the full article here

Warp.dev image

The best coding agent. Backed by benchmarks.

Warp outperforms every other coding agent on the market, and gives you full control over which model you use. Get started now for free, or upgrade and unlock 2.5x AI credits on Warp's paid plans.

Download Warp

Top comments (8)

Collapse
 
xwero profile image
david duymelinck • Edited

Adding a button and a selectedcontent element seems much to just target the styling of the select trigger.

From MDN I understand the main goal is to limit interactive content in the selected option, to make the select trigger work as expected. If you need an element that is selectable and interactive aren't there better UI patterns? Like a dialog?

I think there should be more fine grained options than :open and :checked, but this feels like they are moving too much of the internals outside.

Collapse
 
arnoldgunter profile image
Arnold Gunter

Hey David, solid points—and I agree with the core of your concern: the line between styling and re-implementing behavior should be carefully guarded.

That said, <selectedcontent> isn’t trying to make selects interactive inside the options—it’s solving the problem of how the closed state of a <select> looks. For years, we’ve been stuck with “selected label as plain text”—no icons, no branding, no context. This finally breaks that visual barrier without needing to throw out the native behavior.

The button + <selectedcontent> approach might look heavy, but it's a deliberate trade-off: we retain accessibility, keyboard support, and native dropdown behavior—but with a customizable visual layer on top.

Dialogs are great when you're choosing between multiple complex options. But when you're selecting a language, theme, or emoji—and you just want to show a flag or icon next to it—why should we be forced into rebuilding a fake dropdown with JS?

IMO, this isn't breaking the abstraction—it's just giving devs a much-needed window into a black box we've been hacking around for two decades.

Curious to hear how you'd solve this differently while keeping native behavior intact?

Collapse
 
xwero profile image
david duymelinck • Edited

selectedcontent isn’t trying to make selects interactive inside the options

That was not what I trying to say. I was going of this paragraph on MDN:

The select button and all its content are inert by default so that if interactive children (for example, links or buttons) are included inside it, it will still be treated like a single button for interaction purposes.

As I understand that it is, going to be, possible to add interactive content and selectedcontent is the way to remove the pointer events or content that makes the select trigger change design.
So I think selectedcontent is a good thing, but it solves a problem that should not exist.

In the MDN examples the focus is on styling, so people are guided on the path that leads away from the main goal.
If they are going to use selectedcontent just for styling this is a slippery slope, as I see it.

I don't know enough of the inner workings of the select element to come up with a solution.
But they added the ::picker-icon and the ::checkmark.
It seems less intrusive to add more pseudo classes. But I guess that is not possible, I don't think the decision to add selectedcontent is taken lightly.

Thread Thread
 
arnoldgunter profile image
Arnold Gunter

Hey David, thanks for expanding—this is a super valuable take, and I really appreciate how you’re framing it.

You're right: the root issue is that the select element was never built for rich interaction, and now we’re patching over a legacy limitation. That quote from MDN nails the intent: make the trigger visually rich without breaking interaction semantics—which is historically a very hard balance in native UI components.

I totally get your concern about selectedcontent feeling like a workaround for a problem that maybe shouldn’t exist in the first place. But here’s the reality: devs have already been hacking selects with fake dropdowns, reinventing accessibility, keyboard nav, ARIA roles, and state management—just to show an icon next to a label.

So if we’re already halfway down the slippery slope, isn’t giving us a safe, native foothold better than pretending it’s not happening?

You're right that pseudo-elements like ::picker-icon and ::checkmark are cleaner and less intrusive. But those only target the decorative flourishes—they don't let you change the actual representation of the selected option, which is where real-world UX demands live.

I do agree with you on one key danger: if devs start stuffing interactive elements inside selectedcontent, misusing it like a slot for buttons and links, we’re going to see chaos. That’s where platform guidance matters more than ever.

But with the current implementation, we finally get a compromise: keep the native behavior, expose the visual layer. That’s progress, even if it’s not perfect.

Thread Thread
 
xwero profile image
david duymelinck • Edited

I agree that there should be a solution. Why not create a new select and call it dropdown? HTML and CSS come a long way since select was added.

The way the multiple attribute works in select breaks the dropdown visual. This is something else they could fix with a new element.
Why only fix some parts?

Thread Thread
 
arnoldgunter profile image
Arnold Gunter

Totally fair point—honestly, creating a new <dropdown> element with modern defaults might’ve been cleaner. But the platform tends to evolve existing elements instead of replacing them, probably for backwards compatibility.

Still, I agree—it feels half-solved. Would love to see a full rethink too.

Collapse
 
kelvincode1234 profile image
Precious Kelvin Nwaogu

Image description

i love the new set up, It better now

Collapse
 
rankmyai profile image
RankmyAI

Good!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

Feature flag article image

Create a feature flag in your IDE in 5 minutes with LaunchDarkly’s MCP server ⏰

How to create, evaluate, and modify flags from within your IDE or AI client using natural language with LaunchDarkly's new MCP server. Follow along with this tutorial for step by step instructions.

Read full post

👋 Kindness is contagious

Delve into this thought-provoking piece, celebrated by the DEV Community. Coders from every walk are invited to share their insights and strengthen our collective intelligence.

A heartfelt “thank you” can transform someone’s day—leave yours in the comments!

On DEV, knowledge sharing paves our journey and forges strong connections. Found this helpful? A simple thanks to the author means so much.

Get Started