Declarative Shadow DOM
webkit.org
webkit.org
I think this should all work outside <template> tags. Re-remembering how they worked slowed down my comprehension some. The MDN article[2] was a solid refresher.
[1] https://nolanlawson.com/2023/01/17/my-talk-on-css-runtime-pe...
[2] https://developer.mozilla.org/en-US/docs/Web/Web_Components/...
Also, it's still possible to shoot yourself in the foot, especially if you have a large/complex stylesheet repeated across multiple shadow roots. (Not because of the repetition – that's optimized in browsers [1] – but rather because of the number of DOM nodes affected.)
That said, I still think the perf benefits of shadow DOM have been undersung. And Declarative Shadow DOM makes it way more useful.
[1]: https://github.com/whatwg/dom/issues/831#issuecomment-585489...
There's been a bunch of hand waving that the reason we still don't have this is because they needed a solution for encapsulation and a solution for SSR. Now we have both. Can we please finally deliver on something people have been asking for since the mid 2000s?
[0]: https://github.com/WICG/webcomponents/blob/gh-pages/proposal...
The only relation here is that with some critical feature done like this and shadow selection, there will be more time to work on Template Instantiation.
its been in the pipeline since 2017 with little major movement on it, while a bunch of things developers didn't actually ask for have managed to have more precedence. Whenever I've pressed for reasons for this, it gets hand waved away that they need solutions for SSR and encapsulation. We have both now.
Honestly should have shipped day one with Web Components, would have made it far more compelling. It has always felt like such a big miss to me by the standards bodies that this didn't get attention.
Then I wanted to start building non-JS websites. And suddenly "Web" Components just weren't an option. Now I've dug even further to SSR, and the shortcoming is painful. I don't want to use Next.js, I want to use HTML. I want standards.
Maybe in 4-5 years this will finally be a solved problem...
> Maybe in 4-5 years this will finally be a solved problem...
Of course it won't. And of course it won't be HTML.
Thing is, Webkit wanted to start with HTML and with all things declarative [1] Google wanted to "move fast".
Result? The need a few dozen more standards to patch deficiencies in WC design, and most of those standards involve piling more and more Javascript on top. See this 2022 status report: https://w3c.github.io/webcomponents-cg/2022.html
So now we are in year 12 of this catastrophe, and you are expecting it to end in another 4-5?
If you want to build non-JS sites, web components won't save you. They require JS. They cannot work without JS.
You're much better off using Next, Nuxt, SvelteKit, SolidStart, Marko... Anything that doesn't use them.
[1] https://twitter.com/rniwa_dev/status/1352322006448947203?s=2...
As an example of what you can use the Shadow DOM for - it works fine as the node to render a React app/component in. So if you need a couple of React components on a page to not affect each others style, you can do React.createRoot(myShadowRoot) and they’re fully encapsulated.
A virtual DOM is just an abstraction in JS; whereas the shadow DOM is a feature of the browser engine. They are not really comparable, a shadow DOM _is_ the DOM. The confusion may come from the fact that it can be used in custom elements where MVCs might be involved again.
In contrast, the Shadow DOM is a real browser concept and that affects everything the browser does. Until that arrived, embedding was challenging because anything you added could affect the rest of the document in some way. Now we have a way to put something into an arbitrary location and guarantee that it won’t leak out, and that frees browser developers to make some performance optimizations.
https://developer.mozilla.org/en-US/docs/Web/Web_Components/...
As a practical example, think about social media embedding where people need to write code which is safe to put on millions of pages. Obviously that was possible but it was tedious, and browser developers identified numerous performance hotspots around it over the years. This allows that to be simpler and safer, which is always a great combination.
Except that it does leak in practice. My company uses shadow DOM, but then to style stuff these use a lot of `--var`s, and apparently those penetrate the shadow DOM so you can still break other components inadvertently. (Admittedly when I saw that cluster* I retreated to the backend so my experience is limited)
These days I'm more open to anything. It's definitely a bit exciting everytime I need to parse something with Shadow DOM, a lot more work to really understand what the page is. Last thing I had to parse was chrome://gpu, and it took 3 hours instead of 1 hour to do the job, but could have been worse. But it was at least possible. Sometimes though, with closed shadowroot, the page has gained a resistance to userscripts (as this commenter reports[1]), and this seems purely evil/bad/totalitarian, in a distinctly un-web way!
Weirdly Web Components and Shadow DOM are both tools in the same effort, but Web Components is trying to get everything clearly onto the page, and Shadow DOM has always felt like trying to hide a lot of the page; as someone who loves the web as an interchange of information, Web Components seemed interesting & enriching & useful & value add, and Shadow DOM seemed like a tightening/winnowing/control thing, that didn't express my values. More neutral today, and seeing things like CSS styling performance wins it's clear there are solid technical wins for the platform, but especially closed Shadow DOM feels so overtly control-oriented & totalistic in design, in direct counter to the openness / togetherness / intertwingularity that made the web so interesting & rich & unique a computing space. (It still remains unclear to me that closed shadow-root disappearing into your own pocket universe ought to be permitted, but I'm not as scared as I was.)
This is useful when you need to apply constraints on teammates, same as applying a linter to your project's CSS. You need to guarantee your internal components work well together.
If your style is more "make a component and throw it over the wall for people to use," making everything "public" may be a better approach.
But most web components will never be public or shareable, and that's OK.
The result is that teams need to coordinate their updates and deploy them simultaneously, slowing down the development process. This problem has been recognized in the Web Components community, and some initiatives are underway to address it, such as Scoped Custom Element Registries.
Scoped Custom Element Registries provide a way to isolate the scope of custom elements, preventing name collisions and enabling individual teams to work independently on their components without affecting the rest of the page. This approach has the potential to improve the development process for organizations with multiple teams and streamline the deployment of updates.
However, this solution is not widely adopted yet, and it may take some time to gain traction. In the meantime, organizations may need to develop their own internal guidelines and procedures to manage custom element name collisions and coordinate their updates.
Custom Elements on the other hand are useful for attaching behavior to HTML, sort of like jQuery plugins.
Not at all sold on the frameworks promoting using Shadow DOM for every button or whatnot.
https://gist.github.com/mgerdts/f508ae81795097397106156fa291...
While I get that the purpose of the shadow roots is to provide isolation, is there a simple way to break through that isolation without manually walking the DOM tree and traversing all of the .shadowRoot elements?
It seems Gerrit wraps most elements with a shadow root. For someone that doesn't do front-end development, is there an explanation for how this is helpful?
Also allows you to update the style sheet from anywhere in your js and it’ll effect all the shadow doms that adopted it
When I first started writing/exploring Shadow DOM API I felt so weird writing inline `class`, but then again, it's just a syntactic sugar for prototype functions.
You felt weird using standard ES6 syntax? Did you prefer writing Thing.prototype.method = function(){}... ? Or Derived.prototype = Object.create(Base.prototype)?
* Declarative streaming with slots: https://enamel.pages.dev/
* A countdown timer without client-side JS: https://dash.deno.com/playground/how-to-crash-a-browser
The second one is mine, it's a massive hack and definitely shouldn't be done as it creates opens a new element every second and never closes them; but it was fun to see if it was possible.
It isn't like IE was completely lacking of innovation. To wit, div/span/XMLHttpRequest/BorderBox. Lots of things did come from there. I remember they used fieldset and legend in a much cleaner way, too.
Yep, Microsoft invented Ajax, so in a sense it was IE that made the Web 2.0 possible
I also want to add that I have little love for IE. Same for some of the other things that Microsoft have done. I just find it odd the juxtaposition of why some of that behavior is fine today, as long as it is someone else doing it.
And I don't mean that they are evil or some such. But rising in those ranks almost certainly embeds some behaviors.
Having said that, I’m using Vim. Mostly because I love it but I also can’t imagine using a closed source editor.
The modern analog to that is certainly not Safari.
But really, diverting this discussion to their technical progress (spotty as it is, they do have some there), misses the larger point: by banning non-webkit browsers from their platform, they're engaging in precisely the sort of anti-competitive behavior that Microsoft demonstrated.
Is there a direct analogy here? Like ie only on the windows phones?
Apple, in this case, is similarly seen as abusing its position in the US mobile market by not merely bundling Safari with iOS, but going a step further, and preventing any competition to its own browser by banning competing browser engines.
For a whole range of processes leveraging and protecting the existing Windows monopoly against the threat posed by browsers, Java, and other applications, not just (or even primarily) for “embedding IE with Windows.”
The findings of fact regarding the MS antitrust violations are here availabld [0], bundling IE with Windows is part of bullet E (of A-I) under “Microsoft’s Response to the Browser Threat”.
[0] https://www.justice.gov/atr/us-v-microsoft-courts-findings-f...
Surely there is more to it than that. What am I missing?
https://developer.chrome.com/blog/a-new-experimental-feature...
My outstanding question here is: how do people reuse components across sites with different themes? Do they have to pass styles across the shadow boundary via JS? Or do they just give up on cross-project reuse or theming?
This is the proposal for scoped elements: https://github.com/WICG/webcomponents/blob/gh-pages/proposal...
It appears custom CSS properties pierce through as well. https://open-wc.org/guides/knowledge/styling/styles-piercing...
It might have been fixed recently, have a look.
This is great not just to understand more about what’s happening when browser-specific stuff goes sideways, it’s also a really good place to take design inspiration for encapsulating your own stuff. Besides scoping styles and fully isolating children as implementation details, the native implementations often make judicious use of `part` and `slot` aspects of the relevant/related APIs to handle interop with the non-encapsulated parts of their interface. In a lot of ways this allows elements (both native and custom) to provide much stronger contracts than the mostly tag soup that HTML tends to be by default. And it’s especially great that the interface for this is largely (if not totally now?) how built in behavior works, so writing code that targets the browser has the same privileges and the same limitations as the equivalent code the browser provides.
This reason to be add it seems, really out of touch with reality.
I mean, most of html is not available, or horrendously borked in email clients. Hence the continuation of table within table within table to make anything other than plain text.
The "One Outlook" convergence allegedly draws nigh and that will be really interesting to see how much of the "MSO-style" rendering survives.
Not sure about what you say on traditional Outlook supporting WebView2 rendering; searching isn’t finding me even a single mention of it, although I’d expect it to be very big news in the email industry. https://www.litmus.com/blog/a-guide-to-rendering-differences... was posted from six months ago and is basically unaltered from what one would have said in 2007 (and not much from what one would have said in 2000).
Part of why I'm mostly certain it never used MSO is that it really does seem to share a lot of code with its iOS and Android counterparts and there's no way Microsoft bothered to port MSO to iOS and Android.
Strangely-Aged Enterprise Desktop Outlook noticeably switches to WebView 2 when opening emails from Microsoft's (stupidly named) Viva Insights service (formerly Enterprise Cortana emails) and Yammer emails (now sometimes stupidly called Viva Engage in Teams). (It's mostly noticeable as a "hiccup" in email loading because the MSO view loads first and faster and then the much slower to initialize Chromium-based Web View does its slow pop-over replacement with an extra bonus loading spinner; it is not the best user experience.)
Again, I don't know if it is just hardcoded whitelisted domains from Microsoft's dumb "Viva" brands or if there is an opt-in switch more generally useful. I just know that the renderer switch is annoyingly obvious when I see it and I'm seeing it surprisingly often lately.
https://stackoverflow.com/questions/36194675/windows-10-mail... seems to agree both (a) that it’s MSO, and (b) that it lacks VML support.
https://www.caniemail.com/clients/outlook/#windows-mail is practically the same as https://www.caniemail.com/clients/outlook/#windows (see also https://www.caniemail.com/scoreboard/), and I wouldn’t be surprised if the differences between the two are entirely mistakes.
Outlook for Android, iOS and Mac OS X (now for macOS) have never used MSO.
—⁂—
It could be interesting to look at the headers of your emails (including true MIME headers and <meta http-equiv> tags in an HTML part) that trigger WebView2 rendition. I can imagine something like the old `X-UA-Compatible: IE=edge` way of avoiding compatibility mode and deliberately opting into the most recent rendering engine on IE.
I haven't seen a Viva Insights email in a few days, but I was reminded it does have a full add-on installed and I wouldn't be surprised if it was much more its add-on doing the work and it was very specific to those emails as well. (Possibly it is even the same add-on managing both.)
https://github.com/mozilla/standards-positions/pull/740
> Neutral stance: We're not convinced that the complexity this feature introduces upon the HTML parser carries its weight in terms of usefulness for web developers. There's also a risk that the processing model is not compatible with a future declarative custom elements feature as it was developed in isolation. Having said that, the proposal is a reasonable approach for this functionality that takes into account the various constraints and security considerations that come with changing the HTML parser.
> Positive Stance: This is a reasonable proposal which takes into account the various constraints and security considerations that come with changing the HTML parser.
Hopefully that's a sign of things to come! (Fingers crossed)
Besides, if you need components, web components are probably the last thing you want to reach for.
Edit: Also, none of the major frameworks, and very few of the new frameworks target web components for many reason fully ignored by browser vendors. They can "consume" them (that is embed them in code), but at most compile to web components, reluctantly. And still provide components and SSR, and have for years.
I really feel like html has been totally forgotten by the power that be that work on CSS...
That... Can be useful but kinda problematic
Yes, this is exactly about being able to use shadow dom (for its performance and modularity benefits) without any javascript running in client side
I've been doing 100% of my UI work using vanilla Web Components for years now, and what I generally recommend is to avoid the use of shadow dom unless there's a good reason for it.
The CSS parts API is difficult to work with, and if you want to use a CSS framework like bootstrap etc... you end up importing all the CSS into the component's shadow context.
Web Components with the light dom work great, they're an effective encapsulation mechanism. I'm not sure why most examples you see with WC go straight to shadow DOM.
It isn't necessary for most components and adds an lot of styling complexity.
For application development, I prefer the light DOM.
<div>
<template shadowroot="open">
<style>
:host {
border: 3px solid blue;
}
:host(:hover) {
border-color: pink;
}
</style>
Hello World
</template>
</div>Some form of declarative CSS module scripts would help a lot. A feature request for that here: https://github.com/WICG/webcomponents/issues/939
I guess ... isn't really the thing to do there, as the parts redacted are not only important but it seems to me much more likely to be supported. Although maybe I am overly pessimistic about email clients?
I chuckled reading this. It’s like someone landed in 2020 and learned web development while being completely unaware of events in the preceding decade.
Server side rendering is about dynamically generating HTML code. Client side rendering generates DOM objects in memory, and only rarely generates HTML strings. And then there’s actual rendering, which generates pixels on a display.
People who aren’t familiar with web development often conflate these concepts.
Note that they mean SSR specifically here vs. just server-generated web pages. Server-rendering of component updates is a post-SPA innovation (2018?), so it still seems worth explaining for most web developers.
Absolutely not true. I was doing this in 2009 and so were many other people (albeit through janky XMLHttpRequest via PHP polling ways).
My assumption is that the WebKit team understands their average web developer (which may be notably different than an average HN developer) enough to know whether an explanation is worthwhile.
If you’re talking about something like just React (the view layer), you can certainly go back well beyond 2010.
If you’re talking about something more full-featured, like Next.js today, the oldest I can think of is Ember with its FastBoot, which was becoming usable by the end of 2014 and well-established by mid-2015 (even if 1.0 took until mid-2017—and there was a major internal restructuring to how building worked). https://blog.emberjs.com/inside-fastboot-the-road-to-server-... is good background on that, showing also the attitudes of the time. https://blog.emberjs.com/tag/fastboot/ for the other couple of posts about it.
To quote Rich Harris, the author of Svelte, on the whole web component saga: "It's almost as if congealing 2010-era best practices in the platform before we'd finished exploring this territory was a mistake" [1]
[1] https://twitter.com/Rich_Harris/status/1513668040784814084
We have always been able to break complex tasks down into multiple, simpler job descriptions. That doesn't mean each person is limited to doing at most one of them.