I'm not exactly sure what the developer experience of this would be, but I expect it would make Portals significantly more powerful and able to be hot-swapped into different containers without disrupting either their internal state or even things like loaded iFrames. I expect others will be experimenting heavily with this now that there's platform support.
I'm the developer of react-reverse-portal, this will definitely be a real help!
Iframes particularly have always been a pain point, as people often want to reparent them to move things around the DOM, but they always reload completely when you do so which causes all sorts of issues. This new API says it explicitly _doesn't_ reload iframes, so we'll be able to drop that caveat immediately (for supporting browsers, but hopefully Safari/FF will follow suit soon). Looks great!
khana 6 days ago [-]
[dead]
notnullorvoid 3 days ago [-]
This will need refactoring before being enabled, and possibly might not be enabled at all because it would introduce a perf regression do to the necessary checks to branch between moveBefore or insertBefore.
This was brought up multiple times to the html spec authors, but no changes were made.
recursivedoubts 6 days ago [-]
htmx has supported moveBefore() since 2.0.3 in October of last year:
We initially asked for this new feature about two years ago and have worked with the Chrome team as they have implemented it. It is going to be a huge step forward for the web!
5 days ago [-]
CSSer 5 days ago [-]
Heads up, this page has overflow issues.
recursivedoubts 5 days ago [-]
have you tried restarting?
CSSer 5 days ago [-]
Is this some kind of joke?
dizhn 6 days ago [-]
Why am I getting rickrolled where it's supposed to show a demo of the feature on that page? :)
recursivedoubts 6 days ago [-]
have you tried restarting?
dizhn 6 days ago [-]
I tried singing along.
recursivedoubts 6 days ago [-]
oh, good, glad you fixed it
wlib 6 days ago [-]
The biggest benefit to this is that it makes one of the slowest parts of virtual DOM diffing (longest common subsequence) no longer required. After this becomes supported in the mainstream, not even signal-based frameworks will have to include VDOM algorithms. I know this because I remember pushing for this to be supported a few years ago — a nice reminder that the standards are evolving and that nothing stops you from being a small part of the effort.
Next up — DOM parts and standardized signals, unified.
spankalee 6 days ago [-]
DOM Parts + Signals will be an absolute game changer for the web platform.
How do you even bring this up in a way that it gets noticed by the right people? There's so many times I read niche parts of the DOM that I feel need serious enhancements. I use Blazor (WASM) a lot more these days, so a lot of that is masked from me now.
dimal 6 days ago [-]
Why would this eliminate the need for any VDOM algorithm? I could see how it would simplify VDOM diffing but not eliminate it altogether.
spankalee 6 days ago [-]
VDOM hasn't been needed for a long while, if ever.
You can do a lot better just checking if the template that/s rendering to a spot in the DOM is the same or different from the previous template. If it's the same, just update the bindings from the template, if it's different re-render the whole thing.
That's simpler and faster, but the one thing it leaves out is stateful reordering of lists. So you can have a specific re-ordering code path, which is simpler than a full VDOM, but if you want to preserve state like moveBefore() does, even that reordering gets pretty complicated because you can only preserve state for one contiguous range of nodes that you don't actually move - instead you move all the other nodes around them. moveBefore() just eliminates all that extra complexity.
There's also a couple of standards issues open for native reordering of siblings, like reorderChildren(). That would eliminate the re-ordering code completely.
theultdev 6 days ago [-]
there's other reasons for the vdom though.
vdom is necessary in react to abstract the view from the platform so it can be represented by react-dom and react-native[-x] bridges.
spankalee 6 days ago [-]
That has very little bearing on the web platform. I personally don't care for meta-platforms that abstract away the web.
theultdev 6 days ago [-]
It does have an impact on app development. I personally don't care for web-only libraries / frameworks.
spankalee 6 days ago [-]
I mean that's fine, but when mixed into a conversation on web standards and APIs it leads to a place where you don't care about any web-specific evolution including most progress on the DOM. You end up only caring about a future of WASM + WebGPU, etc. This is exactly where some of the original React core team said they wanted to go - they just wanted a network connected framebuffer.
Again, fine, but I personally prefer a vibrant web platform that evolves to meet the needs of web developers.
theultdev 6 days ago [-]
Don't get me wrong, I'm happy for the change. It will improve things overall, and more power to web-only implementations.
My only intent was to point out another function of the vdom being discussed.
For WASM+WebGPU, I doubt it will ever be up to the same accessibility and feel that react-native-web gives. Just look at Flutter.
nsonha 6 days ago [-]
I'm a web developer and the web api is bloated and ugly. React API is, or at least was, acceptable to work with.
wlib 6 days ago [-]
You can still have a framework-specific render tree that maps to the DOM that tracks changes with signals instead of diffing. We’re just saying that there’s no requirement for diffing algorithms anymore to performantly and correctly reconcile state to the DOM. Keyed children was the last place it was needed.
notnullorvoid 4 days ago [-]
Signal based libraries already don't need VDOM. It's possible that it'll allow faster reordering of elements that are already connected, but the added checks needed to see if an element is connected (need to use insertBefore if not connected) might also cause overall perf regression. The main thing is that it allows elements to be moved without triggering disconnect/connect.
spankalee 7 days ago [-]
This is going to be great for rendering libraries that do keyed loops and for some portal systems.
You'll be able to reorder items in a list while preserving focus, without reloading iframes, and keeping audio and video playing.
We have a draft PR for support in Lit, and will try to ship that as soon as possible.
jonkoops 7 days ago [-]
Also great for rich interactive experiences that use traditional server side rendering to a large degree, this would allow you to make something like the Spotify web application without the need for large client side heavy JavaScript to render things.
salve-for-tears 7 days ago [-]
Wow! This is actually an amazing feature. Rendering a list of items in which the order can change has always been annoying. I can see this feature greatly improving the situation.
Feathercrown 7 days ago [-]
Flexbox allowed this within a flat list, but this is much more applicable
arianvanp 7 days ago [-]
reordering elements with CSS does not reorder them in the accessibility tree and thus is not really a good option in my opinion.
paradox460 6 days ago [-]
I've actually abused this feature in the past to satisfy bone headed layout decisions from on high that would have a dramatic negative effect on accessibility
e40 7 days ago [-]
Any idea how long before this makes it into Firefox?
AshleysBrain 7 days ago [-]
Mozilla have a positive view of the API [1], but it doesn't look like development has started [2].
No movement since its creation on October 10, 2024
culi 7 days ago [-]
It's still an Emerging Web Specification. Seems a little premature to remove the feature flag tbh
AlexErrant 7 days ago [-]
It's stage 3... and "the existence of stage 4 is basically a formality"
> [stage 3] basically means "finished, pending editorial nit review---but since multiple implementations haven't happened yet, there's a reasonable chance that we'll discover something is broken, and need to fix the normative content
The editor of the playground shows you the live DOM in its editor.
sinibida 6 days ago [-]
Unrelated, but this is my first time knowing about RTCode.io, and it looks amazing! But it seems that there's not much information/documentations that I could search.
Would you mind sharing some if you are experienced with it?
tommiegannert 6 days ago [-]
Why isn't it better to redefine insertBefore of an already inserted element to being state-preserving? If I want to kill state, I can do a remove first.
Klaster_1 6 days ago [-]
This would break the WEB. JS DOM bindings are a backwards-compatible public API.
tommiegannert 6 days ago [-]
I reject that claim as-is. In what situations would it break? Standards evolve. Changes to cookies, iframes, newly required HTTP headers all "broke" the web. Not to mention Flash deprecation. But somehow we survived.
Sure, this would theoretically be a backwards incompatible change. But if no one is using insertBefore without really meaning moveBefore, it's not a concern in practice.
nitwit005 5 days ago [-]
You're both denying it would break, and saying it's okay for it to break, which are contradictory arguments.
tommiegannert 5 days ago [-]
Putting it your way, I'm saying it might break short-term, but long-term it would be fine.
etchalon 6 days ago [-]
This is one of those things you're shocked to find out didn't exist before.
sureIy 7 days ago [-]
In typical Chrome fashion, they shipped an API that is in status "Specification currently under development in a Working Group"
I don't understand the need for this awkward API.
Ok, `otherParent.append(existingIframe)` reloads the iframe, but that's just a legacy behavior. Why not toggle the new behavior by calling `existingIframe.holdMyBeer()`? This way I could just continue using .prepend/.append/.before/.after et — which by the way support multiple elements at once, unlike moveBefore.
Ridiculous choice, but I'm not even surprised anymore.
spankalee 6 days ago [-]
> I don't understand the need for this awkward API.
Well, it's clear you didn't take the time to try. There are multiple threads on this and related topics, with inputs from all browser vendors.
This has been a high-priority standards request from framework and rendering library maintainers for many, many years. Chrome is not at all being ridiculous.
notnullorvoid 4 days ago [-]
Shipping it in its current state does seem premature. The spec still hasn't addressed a major concern from rendering library authors, which was that an explicit check to see if a node is connected is now required to branch between using moveBefore or insertBefore, since moveBefore throws if used to place a disconnected node.
mary-ext 4 days ago [-]
isn't it only on disconnected-disconnected case? it'd still require a separate path but it seems like something you can just check once (the parent)
notnullorvoid 3 days ago [-]
According to the spec it throws in the following cases:
Parent - Moved Node
disconnect - connected
connected (Doc A) - connected (Doc B)
connected - disconnected
The last one is the most concerning one. Most of the top performing frameworks do child node reconciliation something like this https://github.com/WebReflection/udomdiff/blob/e58db3ad28b72.... Each node could be unmoved (no-op), new (disconnected), or moved from within the parent (connected). Now if one wants to leverage moveBefore each of these nodes needs to be checked for it's connection state.
sureIy 5 days ago [-]
You didn't read my comment.
I know what it's for, I don't agree with the API itself. Read my third paragraph.
AlexErrant 6 days ago [-]
It's stage 3... and "the existence of stage 4 is basically a formality"
> [stage 3] basically means "finished, pending editorial nit review---but since multiple implementations haven't happened yet, there's a reasonable chance that we'll discover something is broken, and need to fix the normative content
Honestly curious - Does anyone have a use case for this? I tried hard to figure out what this could be used for, but couldn't come up with anything.
AshleysBrain 7 days ago [-]
Previously if you moved an element anywhere else in the DOM for any reason - such as reordering elements, sorting a list, etc. - lots of kinds of elements would be reset: iframes reloaded, transitions/animations are cancelled, video playback is reset, focus is lost, even the scroll position is reset to the top. Some could be worked around (like saving the scroll position and restoring it), but others could not (like iframes being reloaded). Now with moveBefore() all these moves can be done while preserving the element state, which can dramatically simplify the usage of the DOM in some cases.
sublinear 7 days ago [-]
I'm thinking about better responsive UI designs that don't frustrate the user. Everyone hates cumulative layout shift as things load in and window resizes also require layout changes which are often implemented poorly.
I'm also thinking about situations where passing accessibility audits is nearly impossible and at odds with business and marketing insisting on complex designs that need to handle a lot of use cases on one page without making the user navigate to another page. Inevitably you find that there's a lot of display state in the DOM you can't serialize, and on the other end of the spectrum simple pages shouldn't need bloated JS web app frameworks just to maintain the state of a form.
For new projects I can see this significantly reducing the JS and CSS needed. Layout change isn't triggered just by screen width but user input state. Right now I see a lot of web projects with ugly CSS (relative positioning or sometimes mind bending stuff with grid/flex) and ugly JS doing error prone element attribute accounting that ultimately wouldn't be necessary if you could just restructure the DOM on the fly.
If you want an example for accessibility, since I think that's usually a big showstopper, many UI designs want z-indexy things such as context menus, tooltips, popups, notifications, modal forms, etc. that would not pass an audit because they're not properly contained within the structure of the page and technically live somewhere rattling around loosely in the <body> with a ton of CSS applied to complete the illusion.
curtisblaine 5 days ago [-]
If you don't do marketing / ads in your UI it's unexpectedly easy to make it easy to use.
If, instead, you force the user to do things he doesn't want to do in order to get access to the things he wants to do, it's inevitable that the UI becomes frustrating, no matter how much care you put into it.
sublinear 5 days ago [-]
Yeah that's not the kind of marketing I'm talking about. I'm talking about their influence on all the features required and overall design details.
If your requirements are entirely minimum viable product functional and you don't mind your UI looking incredibly ugly, I agree it is easy.
floydnoel 5 days ago [-]
i certainly prefer ugly UIs, that's why we are here instead of reddit after all.
jitl 7 days ago [-]
This is exciting
- move embedded iframe to lightbox for “full screen” and back
- drag and drop of elements without resetting their state
- I’m very curious if it works with contenteditable and/or input method editors. The specifics here are complex so I’m guessing it won’t work, but if it does it will unlock a new bag of tricks for dealing with various problems one encounters when building a rich editor like Notion
Springtime 7 days ago [-]
> move embedded iframe to lightbox for “full screen” and back
Presumably this would also preserve the state of animations, such as GIFs and objects with embedded animated documents (like SVG). With current methods these get reset (along with the already mentioned video state) which break the illusion of an element being transported elsewhere when the original can't be just literally moved.
paradox460 6 days ago [-]
> drag and drop of elements without resetting their state
Could recreate that famous old Mac OS X demo where a video keeps playing while minimized
Lerc 7 days ago [-]
I have a little test that has a DateStamp of 2011 that suggests I needed this functionality some time ago.
It's interesting that they added new functions to support the new (essentially correct) behaviour. I guess there are people out there that have used moving nodes as a way to delete hidden state.
peteforde 6 days ago [-]
This functionality, when it is widely available, solves the slowest and hardest part of the magic that DOM diffing libraries like morphdom provide.
Much is being made of how it will impact client libraries in other threads, but it's actually driving changes from the server which is most helped by this seemingly simple feature.
To make this real, imagine that you are connected to a collaborative (realtime multi-user) app and someone else drags to reorder an item in a list. Let's say that item has a text box that you're typing into. In today's browsers, all but the most clever implementations will clobber your changes. When this drops, the item you're typing into should be able to be programmatically moved to a different location in the DOM and you won't even lose focus.
That's a big freaking deal that makes server-rendered systems like StimulusReflex, LiveView, Hotwire and HTMX even more desirable options compared to SPAs.
jy14898 7 days ago [-]
https://reparent.jarhar.com/. Perhaps a good example is popping out a form when the user wants to navigate elsewhere to answer the questions.
culi 7 days ago [-]
This is a huge deal for SPA libraries which are, like it or not, fundamental to modern web development
I expect this and the View Transition API to have massive implications for the way libraries are written. And hopefully positive ones. Allowing libraries to "use the platform" more closely
jsiepkes 7 days ago [-]
I assume this is big news for htmx (and the likes)?
beardyw 7 days ago [-]
Htmx has experimental support.
panic 7 days ago [-]
Any layout system that modifies the DOM currently has to be careful not to touch certain elements (like focused text fields) if possible. Preserving state means you could treat these elements like any other, rebuilding the DOM out from underneath them as you please.
spiderfarmer 7 days ago [-]
If Chrome takes the lead it's probably all about moving ads around on the page.
knowitnone 6 days ago [-]
Have we seen any drops in Chrome marketshare?
tengbretson 7 days ago [-]
I haven't thought through how, but being able to move an element that has focus just has the feeling of something that could be exploited.
egberts1 7 days ago [-]
[flagged]
lhnz 7 days ago [-]
If it weren't for JavaScript we'd still be downloading binaries and running them unsandboxed on our computers.
wslh 7 days ago [-]
As a cybersecurity guy you should know that JavaScript is by far not the entire attack vector in the frontend landscape: the DOM, HTML, HTTP, CSS, browser implementations, etc are a most complete picture. JavaScript itself has evolved and is evolving from its basic roots.
incrudible 7 days ago [-]
Historically yes because we use unsafe languages just to parse HTML, CSS, HTTP but intrinsically those do not require unsafe things. For JIT the situation is different and without JIT performance would be problematic.
That said, the alternative to web apps is native platforms or other VMs which have the exact same problem except with less capital allocated towards mitigating it.
gruez 7 days ago [-]
>For JIT the situation is different and without JIT performance would be problematic.
Interesting results, but I am talking about the web as an application platform, not as the average users web browsing platform. I find it hard to imagine that users would accept e.g. something like Figma running without JIT, meaning that Figma would have no choice but to move native, thus running into the same problem. That said, for the average web user disabling the JIT by default may be reasonable.
quonn 7 days ago [-]
Explain?
ramses0 7 days ago [-]
Probably something like dom-swapping the google login page or whatever. If you can keep arbitrary CSS transitions running, I could imagine doing a bunch of weird stuff where you don't know exactly what box you're typing in to.
If you can run arbitrary JS on the Google login page then you could simply intercept the form submission and steal the credentials... Am I missing something?
AshleysBrain 7 days ago [-]
Is the ability to move elements preserving DOM state really the key to such attacks? Previously you could do the same but the iframe would reload - but if it's a small simple page, it could load very quickly, in which case it doesn't seem all that different to moving the iframe with its existing content.
jy14898 7 days ago [-]
> I could imagine doing a bunch of weird stuff where you don't know exactly what box you're typing in to.
What stops malicious JavaScript that would have used moveBefore() to just add key event listeners?
7 days ago [-]
qwertox 7 days ago [-]
If they could only fix the issue where resizing a text box almost grinds the entire OS to a halt, that would be nice.
Rendered at 05:38:17 GMT+0000 (Coordinated Universal Time) with Vercel.
https://github.com/facebook/react/pull/32036
I'm not exactly sure what the developer experience of this would be, but I expect it would make Portals significantly more powerful and able to be hot-swapped into different containers without disrupting either their internal state or even things like loaded iFrames. I expect others will be experimenting heavily with this now that there's platform support.
https://github.com/facebook/react/issues/12247 (2018-2020) describes some of the use cases, with one partial solution being https://github.com/httptoolkit/react-reverse-portal - the conversation around caveats of these approaches would be entirely different now!
Iframes particularly have always been a pain point, as people often want to reparent them to move things around the DOM, but they always reload completely when you do so which causes all sorts of issues. This new API says it explicitly _doesn't_ reload iframes, so we'll be able to drop that caveat immediately (for supporting browsers, but hopefully Safari/FF will follow suit soon). Looks great!
This was brought up multiple times to the html spec authors, but no changes were made.
https://github.com/bigskysoftware/htmx/blob/master/CHANGELOG...
https://htmx.org/examples/move-before/
We initially asked for this new feature about two years ago and have worked with the Chrome team as they have implemented it. It is going to be a huge step forward for the web!
Next up — DOM parts and standardized signals, unified.
Then there's a direct line to built-in declarative reactive templating: https://github.com/WICG/webcomponents/issues/1069
You can do a lot better just checking if the template that/s rendering to a spot in the DOM is the same or different from the previous template. If it's the same, just update the bindings from the template, if it's different re-render the whole thing.
That's simpler and faster, but the one thing it leaves out is stateful reordering of lists. So you can have a specific re-ordering code path, which is simpler than a full VDOM, but if you want to preserve state like moveBefore() does, even that reordering gets pretty complicated because you can only preserve state for one contiguous range of nodes that you don't actually move - instead you move all the other nodes around them. moveBefore() just eliminates all that extra complexity.
There's also a couple of standards issues open for native reordering of siblings, like reorderChildren(). That would eliminate the re-ordering code completely.
vdom is necessary in react to abstract the view from the platform so it can be represented by react-dom and react-native[-x] bridges.
Again, fine, but I personally prefer a vibrant web platform that evolves to meet the needs of web developers.
My only intent was to point out another function of the vdom being discussed.
For WASM+WebGPU, I doubt it will ever be up to the same accessibility and feel that react-native-web gives. Just look at Flutter.
You'll be able to reorder items in a list while preserving focus, without reloading iframes, and keeping audio and video playing.
We have a draft PR for support in Lit, and will try to ship that as soon as possible.
[1] https://github.com/mozilla/standards-positions/issues/1053
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=1923880
No movement since its creation on October 10, 2024
> [stage 3] basically means "finished, pending editorial nit review---but since multiple implementations haven't happened yet, there's a reasonable chance that we'll discover something is broken, and need to fix the normative content
https://github.com/whatwg/meta/issues/336#issuecomment-24874...
The editor of the playground shows you the live DOM in its editor.
Would you mind sharing some if you are experienced with it?
Sure, this would theoretically be a backwards incompatible change. But if no one is using insertBefore without really meaning moveBefore, it's not a concern in practice.
I don't understand the need for this awkward API.
Ok, `otherParent.append(existingIframe)` reloads the iframe, but that's just a legacy behavior. Why not toggle the new behavior by calling `existingIframe.holdMyBeer()`? This way I could just continue using .prepend/.append/.before/.after et — which by the way support multiple elements at once, unlike moveBefore.
Ridiculous choice, but I'm not even surprised anymore.
Well, it's clear you didn't take the time to try. There are multiple threads on this and related topics, with inputs from all browser vendors.
This has been a high-priority standards request from framework and rendering library maintainers for many, many years. Chrome is not at all being ridiculous.
I know what it's for, I don't agree with the API itself. Read my third paragraph.
> [stage 3] basically means "finished, pending editorial nit review---but since multiple implementations haven't happened yet, there's a reasonable chance that we'll discover something is broken, and need to fix the normative content
https://github.com/whatwg/meta/issues/336#issuecomment-24874...
This is not one of them.
I'm also thinking about situations where passing accessibility audits is nearly impossible and at odds with business and marketing insisting on complex designs that need to handle a lot of use cases on one page without making the user navigate to another page. Inevitably you find that there's a lot of display state in the DOM you can't serialize, and on the other end of the spectrum simple pages shouldn't need bloated JS web app frameworks just to maintain the state of a form.
For new projects I can see this significantly reducing the JS and CSS needed. Layout change isn't triggered just by screen width but user input state. Right now I see a lot of web projects with ugly CSS (relative positioning or sometimes mind bending stuff with grid/flex) and ugly JS doing error prone element attribute accounting that ultimately wouldn't be necessary if you could just restructure the DOM on the fly.
If you want an example for accessibility, since I think that's usually a big showstopper, many UI designs want z-indexy things such as context menus, tooltips, popups, notifications, modal forms, etc. that would not pass an audit because they're not properly contained within the structure of the page and technically live somewhere rattling around loosely in the <body> with a ton of CSS applied to complete the illusion.
If, instead, you force the user to do things he doesn't want to do in order to get access to the things he wants to do, it's inevitable that the UI becomes frustrating, no matter how much care you put into it.
If your requirements are entirely minimum viable product functional and you don't mind your UI looking incredibly ugly, I agree it is easy.
- move embedded iframe to lightbox for “full screen” and back
- drag and drop of elements without resetting their state
- I’m very curious if it works with contenteditable and/or input method editors. The specifics here are complex so I’m guessing it won’t work, but if it does it will unlock a new bag of tricks for dealing with various problems one encounters when building a rich editor like Notion
Presumably this would also preserve the state of animations, such as GIFs and objects with embedded animated documents (like SVG). With current methods these get reset (along with the already mentioned video state) which break the illusion of an element being transported elsewhere when the original can't be just literally moved.
Could recreate that famous old Mac OS X demo where a video keeps playing while minimized
https://fingswotidun.com/tests/appendNode/
It's interesting that they added new functions to support the new (essentially correct) behaviour. I guess there are people out there that have used moving nodes as a way to delete hidden state.
Much is being made of how it will impact client libraries in other threads, but it's actually driving changes from the server which is most helped by this seemingly simple feature.
To make this real, imagine that you are connected to a collaborative (realtime multi-user) app and someone else drags to reorder an item in a list. Let's say that item has a text box that you're typing into. In today's browsers, all but the most clever implementations will clobber your changes. When this drops, the item you're typing into should be able to be programmatically moved to a different location in the DOM and you won't even lose focus.
That's a big freaking deal that makes server-rendered systems like StimulusReflex, LiveView, Hotwire and HTMX even more desirable options compared to SPAs.
I expect this and the View Transition API to have massive implications for the way libraries are written. And hopefully positive ones. Allowing libraries to "use the platform" more closely
That said, the alternative to web apps is native platforms or other VMs which have the exact same problem except with less capital allocated towards mitigating it.
Not really, at least on desktops: https://microsoftedge.github.io/edgevr/posts/Super-Duper-Sec...
https://developer.mozilla.org/en-US/docs/Web/Security/Attack...
What stops malicious JavaScript that would have used moveBefore() to just add key event listeners?