Relatively New Things You Should Know about HTML Heading Into 2025
Relatively New Things You Should Know about HTML Heading Into 2025 êŽë š
Not all of this is like absolutely brand spanking new just-dropped-in-2024 stuff. Some of it is, but generally itâs relatively new stuff thatâs all pretty great. Iâm pointing things out that I think are really worth knowing about. Itâs possible you havenât kept up too much with HTML developments as it tends to, rightfully, move a lot slower than CSS or JavaScript.
A group of details elements can behave like an accordion, among other improvements, but still have accessibility limitations
Weâve had cross-browser <details>
/ <summary>
support since 2016, but only recently have the abilities started to expand and clean up.
For one, you can make an âexclusiveâ accordion by grouping them together via the name
attribute:
<details name="group"><summary>One</summary> ... </details>
<details name="group"><summary>At</summary> ... </details>
<details name="group"><summary>A</summary> ... </details>
<details name="group"><summary>Time</summary> ... </details>
Me, I mostly think the only-one-open-at-a-time thing is an anti-pattern (as do others), mostly because itâs weird to close something a user may have intentionally opened via side effect. But the web is a big place and certain specific designs I can see needing it to be effective so I donât hate that it exists. At least I think using the term âaccordionâ is now appropriate in this context, but that there are still potential accessibility issues. Like imagine using this for a FAQ section where each question would normally be a header like <h3>
, well, the semantics of that <h3>
is wiped out by the <summary>
, which is a âbuttonâ, so thatâs not great.
Hereâs an example of the accordion pattern being used with a group of horizontally laid out details elements. If more could be opened, it could cause horizontal scroll which I sure we can all imagine also sucks.
Note that those <details>
elements are in a flexbox layout and are themselves display: flex;
and only recently has that improved. (See Stephanie Stimacâs article on recent improvements.)
Ya know how the inside of a <details>
is:
<summary>
- ⊠and whatever else
The âwhatever elseâ can be one or more elements, and there isnât any particularly clean way of selecting them. This is a CSS thing, but now weâve got a ::details-content
pseudo-element selector to get our hands on all that HTML in case it needs similar treatment (imagine fading it all in or out).
Hereâs a great demo of using that, as well as other brand new CSS features, to make honest-to-god animating open/close details elements with arbitrary content in just HTML and CSS.
Styleable Selects are Coming
Browsers canât just all the sudden make every aspect of a <select>
and <option>
s styleable, otherwise historical CSS that didnât apply to them all the sudden does and it would wreak untold havoc on websites. The web doesnât like to roll like that, and I applaud it for that backwards compatibility.
So⊠there needed to be an opt-in to make it work. A new element can work for that, which for a hot minute seemed like it would be <selectmenu>
. But the progressive enhancement story for that basically sucked. So the new opt-in looks like it will be CSS triggered:
select,
::picker(select) {
appearance: base-select;
}

web-dot-dev
)Once youâve opted in, you can apply styling to elements inside the <select>
pretty freely, opening up huge doors to designing that experience.
There is some other funky things to know so Iâd suggest reading this whole article. Even some new (tricky) HTML!
<select class="country-select">
<button>
<selectedoption></selectedoption>
</button>
<option value="" hidden>
<figure></figure>
<span>Select a country</span>
</option>
<option value="andorra">
<img
src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Flag_of_Andorra.svg/120px-Flag_of_Andorra.svg.png"
alt=""
/>
<span>Andorra</span>
</option>
...
</select>
My favorite episode of Off the Main Thread this year was about styleable selects and all the interesting details behind them that will have knock-on effects.
Oh â also you can slap a line into a select menu
I kinda love how the old school name
attribute was used with <details>
for the accordion behavior.
And speaking of old school elements, you can put an <hr>
within a <select>
to just draw a line there (a âhorizontal ruleâ as it were). Youâve still got <optgroup label="label">
for more emphatic grouping, but sometimes a line is all you need.
<select>
<option>apple</option>
<option>orange</option>
<option>banana</option>
<hr>
<option>pepper</option>
<option>squash</option>
<option>broccoli</option>
</select>
You Can Open/Close a Popover with a Button Alone
No JavaScript is required to make the opening and closing of a popover work.
<button popovertarget="the-popover">Open Popover</button>
<div popover id="the-popover">
I'm a popover.
<button popovertarget="the-popover">Close Popover</button>
</div>
If youâd prefer that the popover be closed by just a click anywhere outside of it (thatâs called a âlight dismissâ) then update the popover attribute to popover="auto"
and thatâll do it.
The âtargettingâ you can see happening with those buttons is an example of an âInvokerâ, which is poised bring great power to HTML in coming years.
You canât close a popover with a form submission like you can a <dialog>
, but a popover probably isnât a great place for a form anyway so thatâs fine. Another interesting sidenote is you can make a <dialog popover>
if you like, getting you this button behavior for free.
There are quite a few differences between dialogs and popovers, and both are awfully useful. Perhaps the most important two features being the focus trap potential and the fact they are promoted to the âtop layerâ of the rendered site, meaning no futzing with z-index
.
The situation weâre in with popovers is that you pretty much need to be OK with either centered or edge-based positioning for them for now, like dialogs. They are just begging for anchor positioning, but the current guess is 2026 for interop on that.
Checkboxes can be Toggle Switches
Itâs as easy as:
<input type="checkbox" switch>
Although only Safari supports it for now and itâs not actually specced yet so it could be said they jumped the gun a bit. Main discussion here (whatwg/html
). And I guess we should call it a âswitchâ to be proper.
Iâm a fan here because the absolutely correct implementation of a toggle/switch was easy to get wrong from an accessibility standpoint, and this seems⊠hard to get wrong.
Daniel Yuschick has an article digging into the details. I like the idea that pseudo elements specific to this UI will be exposed, like ::thumb
and::track
, but I canât tell you what the status of that is right now. Even the official demos in Safari Nightly Preview with the flag turned on arenât rendering properly for me.
Wrap your Search
This will be easy to remember. Got an area of your site that is meant for searching? Wrap it.
<search>
</search>
Itâs the same as doing <div role="search">
, but my bet is that youâll actually remember to do it.
You probably donât need noopener noreferrer on links anymore
Iâve used linters on projects that help ensure that a link like:
<a
href="https://google.com"
target="_blank"
>
</a>
Has attributes like this as well:
<a
href="https://google.com"
target="_blank"
rel="noopener noreferrer"
>
</a>
Ben Werd (werd.io
)

The problem was, that actually gave the opened pages rights to their referrer: it opened a security hole that could potentially have leaked user information or opened the door to phishing.
This is not new â2025â information, but Iâm only just learning that this isnât really needed anymore. Chrome was the last to automatically apply this behavior to _blank
links and that was 2021. Iâve been doing it as I have a linter that always warns me about it, so in case your browser support targets agree, you might want to check those linter settings.
Declarative Shadow DOM Paves the Way for Better Web Component Frameworks
It used to be that if you wanted a Web Component to use Shadow DOM, the only way to do it was for it to be rendered by JavaScript. This meant that Web Components that wanted or needed to use Shadow DOM had no Server Side Rendering (SSR) story at all. That was a big gap, as all the major UI frameworks have coalesced on the idea that SSR is a good idea for many reasons (performance (perceived and actual), resilience, SEO, hosting options, etc).
Now weâve got Declarative Shadow DOM and the gap has closed.
I think itâs cool to see the Shadow DOM at work with no JavaScript at all:

chriscoyier
)What I hope weâll see in 2025 and beyond is frameworks actually help use this. It feels like foundational technology that mostly isnât expected to be written by hand by authors, but instead used by libraries/frameworks to build great authoring experiences around.
React 19 was the last framework to fully correctly support Web Components, so perhaps weâll see frameworks do more than support them now but embrace them. I would expect to see a âNext.js of Web Componentsâ at some point.
Import Maps
I used to be fond of point out that a line like this isnât standard JavaScript.
import React from "react";
That looks like ES Modules code, but the fact that the value in quotes doesnât start with an absolute URL or a .
(a relative path) means itâs⊠not. Itâs just a convention that we all got used to writing because JavaScript bundlers understand it to mean âthatâs a thing from npm so I should go look for it in the node_modules
folder.
Thatâs changed now, since you can, via HTML Import Maps, map the value âreactâ to something else via Import Maps.
So if you executed that JavaScript above from an HTML file that included an import map like this:
<script type="importmap"> {
"imports": {
"react": "https://esm.sh/react@18",
"reactdom": "https://esm.sh/react-dom@18"
}
}
</script>
It would work and import the JavaScript from those locations instead. This opens up the door for not needing to use a bundler and still having the benefit of an abstraction for importing dependencies. Having the possibility to avoid tooling can be huge for long term maintenance of projects.
Donât Sleep on the inert
Attribute
You can make an element, and the entire chunk of DOM under it, ignored completely from an interactivity perspective, just by by using the inert
attribute. Itâs quite powerful. No clicks, no focus, the element(s) are gone from the accessibility tree, nothing can be selected, heck, the on-page âfindâ command wonât even find text within there.
If youâve got any reason at all to put stuff in the DOM but have it essentially behave as if it isnât there, make it inert
until you are ready for it not to be. Imagine a multi-step form that is all in the DOM right away, but only one step at a time is not inert, so future or previous form controls arenât accidentally used until ready.
Iâd tell you this is ideal for implementing modals, but you get this behavior for free, and easier because it can be placed anywhere, just by using <dialog>
.
Keep your find-on-page working properly
Another interesting attribute here. Weâve long had hidden
as an attribute (even though itâs kinda weak). The change here is it taking a value, like hidden="until-found"
. That will hide the element as hidden
does, but the content within it will still be findable with on-page text search. When it is found, ~itâs on you to react to the DOM event beforematch
to un-hide (by removing the attribute) the content so it can be seen~ the hidden
attribute is removed automatically, plus youâve got the beforematch
event to hook into if you need to do additional work.
Hereâs the demo from chrome for developers, which you might need to try in Debug View (web-dot-dev
) for it to trigger properly.
Youâd think this would be useful for <details>
elements in how they hide content, but this behavior is baked into them. This is more solid evidence for using native features â because they get the details right (generally) rather than you needing to replicate them.
Multi-Page View Transitions
You have to opt-in to this via CSS like:
@view-transition {
navigation: auto;
}
Then once you have, regular olâ clicked links that move to a new page (on the same domain) can have view transitions. That is, youâll see the page use a fade effect by default. But this unlocks an amazing amount of animation control over the transition between those two page loads.
Iâm listing this as an HTML feature, because I find most of the useful-ness of multi-page view transitions are unlocked in the HTML. For instanceâŠ
<!-- homepage -->
<div class="card">
<h3
style="view-transition-name: post-title-087afd"
>Blog Post Title</h3>
<p>...</p>
<a href="/blog-post">Read the article Blog Post Title</a>
</div>
<!-- blog post -->
<article>
<h1
style="view-transition-name: post-title-087afd"
>Blog Post Title</h1>
<p>...</p>
</article>
Above, Iâm imagining the âcardâ as a component that is generated from data and is likely one of many on the page. So it requires having a unique view-transition-name
, and really the only good opportunity to apply that is in HTML.
Responsive Video is catching up to Responsive Images
With the <picture>
element in HTML we get the ability to use the <source>
element within and control exactly when we swap out to different source images. Itâs a powerful concept that can offer big performance wins.
That idea actually originally came from a concept with the <video>
tag, but then that was bizarrely removed from (most) browsers. But now itâs back thanks to some serious work by Scott Jehl and others he convinced to help the revival along.
You can do media
attribute control the sources, which will probably mostly be used for width query stuff, but it can do anything media can do. Scott wrote up some examples here, like:
<video autoplay controls playsinline muted loop>
<source media="(orientation: landscape)" src="sunset-landscape-1080.mp4">
<source src="sunset-portrait-1080.mp4">
</video>
HTML Imports are Coming Back
Just kidding they totally arenât.
Did we miss anything?
Any newfangled HTML out there youâve been eyeing up or using?