W3C

– DRAFT –
WCCG TPAC meeting

10 November 2025

Attendees

Present
keithamus, lea, ydaniv
Regrets
-
Chair
-
Scribe
bkardell

Meeting minutes

WICG/webcomponents#1114

Reference Target

alice:

alice: it's a small issue, it's about what happens if the reference target it invalid

alice: what is the actual label.control here?

Alice: This example has a broken reference target, so it returns and logs null... There seemed to be consensus that that makes sense -- if you have comments?

annevk: I think it would make sense if it was consistent

Alice: right now as written, and I believe as implemented in the 3 engines, this logs null. I am no longer sure that that is right because ... there is linked issue - whatwg html 11577 where we were talking about adding more of idl getter/setter attributes - for htmlFor, etc

Alice: there was discussion in that issue which caused me to rethink this. That combined with some comments keithamus made -- it's kinda funky that we have to do this resolution of the reference target and then recursively resolve this and retarget back up... it's awkward in the spec language and implementation

alice: it's not clear what value that adds. Given that it is a getter and a setter - button.popovertarget = 'my popover' there is a oddness that you are not getting that back because it's invalid... it is more like a content attribute than the end point of an algorithm

anqevk: that is not very compelling to me. The thing that made me change my mind was because of the lifetime of custom elements - you might set the idl attribute to an element that isn't yet initialized - the getter would return null, but then after it is initialized it would return something else

Alice: but this would not do that

annevk: we're agreeing on the result but for different reasons

westbrook: If set a popover target element as a div that doesn't have popover attribute - does it return the element?

emilio: yeah, it won't trigger the popover probably

emilio: in general it only returns the generic get attr associated element right now

emilio: there's another question about whether it should return null if it could never be a popover - like if it is not an HTML element...

annevk: I think it probably should return an svg element because we might want to do svg custom elements

Alice: so I think it should return the element now

<justinf> OT, but: please, please SVG custom elements

emilio: I could go both ways but I think it makes sense

Alice: I'm not seeing the value in doing it the other way

emilio: especially the argument about "it's in the document but not initialized" seems pretty compelling as a reason

Proposed Resolution: don't resolve the reference target when computing the value of the atto-associated element

<sorvell> Are we using the speaker queue?

annevk: ???

<westbrook> Trying.

<emilio> annevk: HTMLLabelElement.control takes the same input

sorvell: my concern is a developer expectation with these things returning a value and that value serving the purpose that is expected. If I have a label control I expect that that is a thing that is label able. If I have a popup I expect that it has popup behavior. I worry about this violating that - it's not totally concrete but "user expectation" is a reason I would think might be useful for returning null. Lifecycle doesn't

concern me - it is common in web components. The dynamism is just something we have to deal with. I don't have a _super_ strong opinion - just a sense that developers expect it

rniwa: we want shadow root to stay consistent. you want to construct the shadow root lazily in some cases - we don't want the behavior and methods to be entirely different if it is connected or not - you want to have a separation of concerns between the IDL attribute and the shadow Dom status

emilio: whether the element exists or not or is displayed- - htmlelement.control doesn't check if it is displayed. It will already return you its host. I don't think returning the internal element is an option, so I think it is probably more consient to not care about what the shadow root state is in any way.

<frehner> +1

<sorvell> I think that seems ok to me then.

<lea> +1. No strong opinion either way, but I would find it surprising to have a shadow root element returned (or null if said shadow DOM element doesn't exist) since this is part of the element's public API

alice: (asking sorvel to clarify)

sorvell: Emilio just convinced me... we should do the simple thing and not care about what is in the shadow root

alice: I'm not sure where we landed on control...

emilio: I think it would be inconsistent if we didn't do the same?

annevk: control checks - it returns whatever label would click on... but now we're kind of changing how some of that works. I feel like now that we're rethink that, that should evolve along the same way

Alice: my thought on that is that if you have a fancy-input, you have a thing that wraps and input element - that is acting as an input - as a label able element.. the label is labeling the fancy-input by way of the input that it wraps. That's why I think label.control should return the fancy-input

annevk: Even if it isn't uprgraded

Alice: So it will optimistically lie?

westbrook: it's like what popover does

Alice: but that's a getter and a setter

annevk: it's been proposed and it would be very weird if for element returned one thing and control did not

keithamus: we could know that it could be a custom element based on the tagname

rniwa: it's conceivable that these getter only things gain a setter - we don't want to block ourselves in the future, so being consistent between them makes sense

<keithamus> whatwg/html#11577

<astearns> +1 rniwa

alice: it's conceivable these things get a setter, but it is completely within our control whether we do that or not

keithamus: is there a chromium use counter for control?

westbrook: it seems we're 70% or more in favor of the resolution we started with

alice: I don't have strong feelings about it, except I would like control to work the way it does now in checking whether the currently labeled element is labelable

sorvell: we should be consistent ... we should just assume if you've made the connection it's going to be satisfied at some point.

annevk: I like adding the set of labelleble element by just all custom elements

Alice: so it is spec-wise labelleable if it has a dash

rniwa: potentially labelable

emilio: the check is already lying in a way

emilio: I think it would be weird if you pointed it to div id works differently than my-div does

emilio: if we get into Compat problems, I guess the tag name check is the less bad of the alternatives, but it is very unlikely that we hit any Compat issues with it. Maybe someone checking for form being null?

annevk: form was kind of over engineered

Emilio: we should remove the label able check - if we are constrained the tag name check

<sorvell> +1 to loosening the spec requirements around these things in general, if possible.

annevk: It feels a little weird, but I'm open to it

<MichaelWarren> +1 to removing the checks for consistency

<emilio> svk rmiq

<emilio> PROPOSED: Loosen the type checks in HTMLLabelElement.control and .form if not compat constrained. Otherwise consider all potentially-custom-elements as labelable / potentially-a-form

<keithamus> +1

RESOLUTION: Loosen the type checks in HTMLLabelElement.control and .form if not compat constrained. Otherwise consider all potentially-custom-elements as labelable / potentially-a-form

Reference Target Phase 2

<emilio> WICG/webcomponents#1111

<emilio> alice: referencetarget explainer originally referred to two phases (1 and 2)

<emilio> ... phase 1 was the shadow root property that allowed you to redirect all attributes to a single element

<emilio> ... like fancy-input use case is the obvious one

<emilio> ... I want the host element to act as the element it's wrapping

<emilio> ... it's a common pattern for button / input / popover / ...

<emilio> ... phase 2 was the idea of a referencetarget map

<emilio> ... the idea that the reference would be forwarded from the host depending on the attribute itself

<emilio> ... so you'd have a catch-all referencetarget="input", then an aria-label to a different label

<emilio> ... so I tried to rephrase the referencetarget explainer in terms of the use cases

<emilio> ... phase 1 was pretty clear but phase 2 I'm less clear about

<emilio> ... the cases I could come up with is aria-active-descendant

<emilio> ... (for combobox-like things)

<emilio> ... so an input that has its active-descendant set to an option (like autocomplete option or what not)

<emilio> ... the other one is aria-labeled/described/etc-by

<emilio> ... so you're referring to the host and there's some content within the shadow root which you don't want to contribute to the name when it's referring to something else

<emilio> ... so the question is are there other use cases other than those where referencing the host itself wouldn't work?

<emilio> westbrook: at one point we got an example with card components

<emilio> alice: was that an aria-text situation?

<emilio> westbrook: yes

<MichaelWarren> +1 to table map

<emilio> ... but as a consumer of this, I think once we have referencetarget at large we'll start getting the map use cases

<emilio> ... so proposal to table it for now because lacking referencetarget prevents you from thinking on those terms

<sorvell> +1

<emilio> ... completely open to disagreement but might be better to table for now in terms of where to spend the time on

<emilio> rniwa: tabling this until there's more evidence of other use cases sounds good

<emilio> westbrook: seems like the chromium implementation is close to shippable

<emilio> alice: yeah the others are prototype

<emilio> alice: would be good what other use cases arise

<emilio> keithamus: I'm a bit cautious of the syntax here so happy to defer

<emilio> emilio: there's precedent for exportparts, syntax-wise

@sheet

<Kurt> https://docs.google.com/presentation/d/10SagxoHUY9JBlMK2dXej1atndwQdpVEz0YmmJ52dLBg/edit?usp=sharing

<emilio> Kurt: I made also a lot of changes to the explainer and also a spec PR too

<emilio> ... It's basically two attributes (type=module and specifier="foo")

<emilio> ... to the <style> element

<emilio> ... then it creates an importmap entry globally

<emilio> ... the others is <template shadowrootadoptedstylesheets=""> attribute

<emilio> ... with specifier, or a URL that's in the module

<emilio> ... it's in experimental web platform features in chrome canary

<westbrook> 👏👏👏

<emilio> Kurt: there's a bunch of details to figure out, timing details

<emilio> ... also lifetimes of the blobs and so on

<emilio> ... thursday noon japan time will be discussed with WHATWG

<emilio> ... @sheet is a bit tabled for now, no resources to commit to it right now

<emilio> ... I think it can be useful, and a prototype in chromium

<emilio> ... if anyone wants to pick it up that'd be cool

emilio: can you import a declarative css module from an @import - do we need extra syntax for that? it seems like something that would be interesting to do

<justinf> A: no. @import doesn't work with modules yet

Kurt: no- it currently throws an error...

emilio: not about @import inside the module, I was talking about can you actually reference an existing module from an inline @import. Like @import(...)

justinf: are you talking about inside of css

emilio: yes

lea: in js we specify that imports have to be either fully formed or start with a dot - specifically so you can tell the difference. But in CSS even today it would be treated as a URL... It seems very weird tho to not

emilio: we would have to add another function

westbrook: If I have created a reference able declarative module called Justin, and later include an inline style tag and inside of that it says @import(Justin) would it work? That's not a css module, but it's referencing one - it seems like something we should;d be able to do

justinf: the reason I am saying it is the same, this uses the module map. They are modules - they are the same things that you would import in the javascript module map. we've always wanted to enable that - if we need to add another function...

Kurt: yeah, we would have to add a new function

<astearns> @import module(justin) versus @importmodule

<sorvell> `@import module(foo)`

<Zakim> lea, you wanted to ask about CSS imports and import maps

emilio: if you add something to the module map which has already been referenced - CSS generally works more dynamically, but maybe it doesn't have to

annevk: there are other things in HTML like fetch - should they be able to hook into the module map

<emilio> lea: I think it's important architecturally to get this right

<emilio> ... to be able to use the specifier everywhere

<emilio> ... everywhere you can import a url from JS you can use the import

<emilio> ... I don't see it as a nice to have

<emilio> sorvell: To directly respond, I agree but importmap totally goes with modules, not urls

<emilio> ... so I don't necessarily think @import having a different way to specify a module

<emilio> ... is problematic

<emilio> lea: I think we agree on that

<emilio> sorvell: it'd be nice to have but in general I dislike the ordering requirement and snapshotting requirement

<lea> +1 sorvell, I totally missed the ordering requirement

<justinf> +1

<westbrook> +1

<emilio> ... I could give you things in whatever order I wanted

<emilio> ... I think that'd match the CSS expectations

<lea> absolutely, 100%. Pretty sure there's a TAG design principle about this actually

<emilio> annevk: Also connection time must be wrong, because at connection the <style> is element

<emilio> Kurt: it's when the sheet is already parsed

<emilio> sorvell: to me if you're going to use `<style>` it should behave like CSS

<emilio> ... otherwise let's use <script>

<emilio> rniwa: so the import map is global, which one wins on conflicts?

<emilio> Kurt: the first defined one

<emilio> annevk: yeah the module map is per-global

<emilio> justinf: it's actually critical for the design

<emilio> keithamus: does this allow you to override the stylesheet of a third-party component?

<emilio> rniwa: yeah that seems a bit problematic

<emilio> justinf: they can just do that, put an import map and override everything

<emilio> westbrook: same with CSS if you have custom functions and mixins

<emilio> emilio: that's very odd

<emilio> westbrook: but let's talk about that on thursday

<emilio> Kurt: there's an inline-style CSP

<emilio> ... which is respected for <style>

<emilio> ... which does get respected

<emilio> emilio: that solves the third-party component injects into your global map

<emilio> ... but not what keithamus was saying

<emilio> keithamus: I think if you're in control of the component you could not use this feature

<emilio> rniwa: yeah but that'd be a bit bad

<emilio> justinf: the only components that would use it is the SSR system

<emilio> rniwa: that's how you do it if the feature as proposed is implemented

<emilio> ... as the feature is currently proposed it allows random styles into the components

<emilio> ... seems like this creates a new feature

<emilio> justinf: a component can just inject styles all over the place

<emilio> ... is there any new

<emilio> annevk: It's the other way around

<emilio> ... which is theoretically possible by hooking .attachShadow() I guess

<emilio> sorvell: I can do this from a component already

<emilio> annevk: that's not the issue

<emilio> keithamus: it's the opposite problem

<emilio> westbrook: let's say I sneak applepay.js in the component map

<emilio> ... from the page I can nerf the applepay component

<emilio> keithamus: yeah you've completely erradicated the component in that regard

<emilio> ... you are inserting a google maps / apple pay component

<emilio> ... what level of control do you have over that?

<emilio> sorvell: I can use an element in my custom-element that has been defined above

<emilio> justinf: declarative shadow root already has this problem, closed shadow roots can be tweaked by markup

<emilio> ... these are features intended for that, it's going to be meant for everything

<emilio> ... you'd need an iframe to get extra protection

<emilio> westbrook: one step further, it's not this feature, this begins to speak to a well organized path for customization, e.g. if I proactively use the module name is "very-cool-color-picker"

<emilio> ... there's a lot of possibility for that

<emilio> lea: I think the concern is overriding it by accident

<ntim> (where can i find the full agenda and relevant issues/docs?)

<emilio> justinf: re. @sheet, I think deferring it makes sense

<westbrook> https://docs.google.com/document/d/1KeqMzuPHzHXTGR2zXmOHQydMUgVm2Y8onZHVmygAQFc/edit?tab=t.0

<emilio> lea: is the namespace different between js and css?

<emilio> Kurt: yes, module map is keyed by type

<emilio> lea: I wonder if a lot of the issues could be addressed by the browser not fetching the url multiple times

<sorvell> changing loading behavior seems exceptionally hard

<emilio> lea: and you get FOUC and so on

emilio: browsers won't fetch the same url twice - the main issue with shadow Dom is that they do not block rendering on the shadow Dom sstylsheets being loaded

emilio: that does seem fixable to me to be honest ... the main issue that I think Kurt is interested in fixing with @ sheet is that you can skip multiple fetches

lea: I remember there was some kind of issue where you get glitches

emilio: the general render blocking ability is based on link tags in the head, mainly...

emilio: to be fair that can be worked around by the component itself - you can add an onload handler and just do that yourself

justinf: but this whole feature is for before that

emilio: you can definitely hide the host until the style loads

justinf: that defeats the whole purpose of ssr

emilio: totally unrelated to ssr - I agree it doesn't solve that

<Zakim> emilio, you wanted to react to lea

<Jxck> no short break ?

<westbrook> I was going to ask about a short break after this topic.

<emilio> nicolo-ribaudo7: Global namespaces might be useful, but is there a desire to make it local to the component somehow?

<emilio> justinf: the entire purpose of this feature is the global ns

<emilio> ... otherwise you can't share styles across shadow roots

<emilio> ... to me without the global namespace this is not useful

<emilio> Kurt: you can fake it by using the namespace identifier

<emilio> ... hacky but not great

<emilio> nicolo-ribaudo7: on the JS case we're trying to define multiple modules from the same file

<emilio> westbrook: that's very close to what @sheet is intended to do

<emilio> MichaelWarren: I was making a comment related to westbrook's earlier intervention, opt-in customizability seems nice

<justinf> This is the wrong feature for customizing someone else's shadow root styles

justinf: but it does that, right?

<emilio> ... It'd be good for a hint for name conflicts

justinf: that's what people were saying

<emilio> Kurt: seems like a good idea to warn on naming conflicts

<justinf> bkardell: it does it in the same sense that service workers let you customize a libraries JS

<emilio> keithamus: can we go back to specifiers vs urls?

<emilio> ... so specifiers on shadowrootadoptedstylesheet="" awaits?

<emilio> Kurt: no you don't get styles, the adopted stylesheets being sync guarantees the order and soon

<emilio> ... if you need async behavior you can use the scriptable

<emilio> westbrook: is it possible to use a placeholder?

<emilio> keithamus: maybe it could register an empty stylesheet and then the module specifier would replaceSync() on the existing sheet?

<emilio> ... for the url case does it fetch?

<emilio> Kurt: no just looks at the module map

<emilio> keithamus: Is that problematic for authors?

<emilio> ... because console warnings aside it's a silent failure

<emilio> ... so feels a bit dangerous

<emilio> Kurt: these are all kinda tricky

<emilio> ... we either do several non-great options

<emilio> ... then first-one-wins works weirdly but seems fixable

<emilio> ... other than that it seems you'd get a FOUC

<emilio> justinf: For the main intended use case an SSR system would never emit a wrong specifier

<emilio> ... we'd generate synthetic specifiers for empirically created constructable stylesheet objects

<emilio> ... we'll create a reference, emit it...

<emilio> ... the secondary use case would be to try to share module contents within SSR and inline content

<emilio> ... e.g you SSR a page and then a script

<emilio> ... in that case if the JS loaded before the SSR then you emit in your page

<emilio> ... a bit of a niche use case

<emilio> ... but would be cool if it works

<emilio> sorvell: There might be a 60/70% capabilities overlap with mixins

<justinf> I don't understand how they overlap at all

<emilio> ... I think they're amazing

<justinf> this feature is for inlining shared CSS modules

<emilio> ... to do a lot of similar type of customization

emilio: the js module map - the whole define it later so that it works could be done with the existing ... imagine you do this in js - you would have a global window.stylsheet map - you would lazily create them until someone does replaceSync on them - that also unlocks using @import in these modules... the main problem with the current @import - each @import has its own stylesheet, but if they use a module they should clearly not use

those kind of semantics
… especially if we add a different syntax - I think we don't have those issues, it's just essentially a constructible stylesheet... that would let us sidestep

emilio: we could disallow non-module imports - that gets some of the way there. that may be a good model to work off of

keithamus: would you just have to set a flag if you've done replacing once?

<justinf> unblocking @import would be huge

emilio: that might be a useful mental and spec model for how it works - it works the same way as you would implement in js, which is nice

<emilio> rniwa: Was going to point out the same issue that emilio just proposed solving

<emilio> keithamus: @import doesn't work now

<justinf> The @import decision was just to defer them. That's what they throw for now

<emilio> rniwa: It'd be ideal to fix it

<emilio> justinf: yeah we made them throw just for that, but yeah the issue is the semantics of @import not matching JS modules

<emilio> keithamus: seems like a path forward could be we implement @import module() then remote @import

<emilio> ... doesn't seem like a blocker for this functionality I guess

<emilio> rniwa: yeah as long as it's forward compatible

<emilio> Kurt: yeah if we have some @import module()...

<emilio> ... we could expose exported sheets

<emilio> ... but yeah this doesn't prevent us from this or the existing CSS modules

<emilio> keithamus: Do you think you got enough to go off of?

<emilio> Kurt: yeah this was great

<emilio> ... lot of folks have contributed to this

<JRJurman4> <Taking a 5 minute break>

<sorvell> To quickly illustrate the point about @mixin:

<sorvell> <style>@mixin --font-inherit() { input, button, textarea, select { font: inherit; }}</style>

<sorvell> <div><template shadowrootmode="open"><style>:host { @apply --font-inherit(); }</style>...</template></div>

<justinf> template slides: https://docs.google.com/presentation/d/1r0AXWbP8RadIBuIFl-hC3O8G6YhTlguxKyluDIWil7g/edit?usp=sharing

<westbrook> https://docs.google.com/document/d/1KeqMzuPHzHXTGR2zXmOHQydMUgVm2Y8onZHVmygAQFc/edit?tab=t.0

Templates

Slideset: https://docs.google.com/presentation/d/10SagxoHUY9JBlMK2dXej1atndwQdpVEz0YmmJ52dLBg/edit and archived PDF copy

<emilio> justinf: [goes over the slides]

emilio: I think some of the scheduling stuff probably needs a fair bit of work to at least define relevant cases... the big question is when are these tasks run?
… do they run on rAF?
… I am assuming you want that by default, but you need to hook it up somewhere
… then what happens when I move it around or something - should I update the order or..?

justinf: you don't want a child to render each time - you render asynchronous, so you can assume by the next micro task. The asunchornicity confuses a lot of people
… nested tasks would get put on the queue and get executed in order so you can observe in the very next line that something was set
… it's a new kind of timing - it's way earlier than animation frame or micro task. Way back I think we used to talk about nano task - this might be like that. Native elements can already do this

emilio: I am a bit concerned about standardizing the precise mutations that happen with these. If you have nested things and conditionals - are we creating a new subtree when that value flips? I think depending on the use case you might have different ideas

justinf: there is a particular model here which is that for a child part - where composition and nesting comes in - it checks to see whether it has already stamped out that template already, and if it has it can recurse and update those values
… out of that all composition and control flow just fall out
… if you flip back and forth on some tertiary you will rerender

<westbrook> How might timing relate to https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/EventPhases/explainer.md

emilio: isn't that a little confusing for developers - if they want an error message if it is valid, the tree changes - the original Dom from that condition isn't the same... there are ways around that I guess, you can talk about class or something

justinf: this is the predominant model of web development - even though the things like react talk about diffing, if you you switch to a completely different v-dom fragment there's a really good chance you're going to replace that whole subdom

justinf: I don't think it is confusing, it is the main thing today

emilio: I guess it forces you to go fully to that model where your event listeners too are in there because otherwise your listeners can get destroyed too

justinf: there are ways to bind a node into a spot or refs ...(?? didn't get it, sorry)

<sorvell> wrt scheduling, we already have the custom element reaction queue that might be a helpful model, at least for reference

<emilio> MichaelWarren: The render() method would be in HTMLElement, but in the example would be ShadowRoot?

<westbrook> justinf: refs, imperatively created elements, etc would support some level of imperative event binding that didn't loose the binding when DOM fragments might change under the binding code unexpectedly.

<emilio> ... it's very attractive to have a single function to hook for SSR

<emilio> justinf: you are correct that the reason why lit can do ssr is because it just calls render()

<emilio> ... this could be a way to have a semi-universal ssr

<emilio> MichaelWarren: if we have a templating engine it'd be good to have a standardized feature set

<emilio> ... because frameworks that are running in servers need something else

<emilio> justinf: another thing SSR engines would do is patching to patch the render() method

<emilio> ... this can help users of SSR a ton

<emilio> rniwa: I think we should probably try to make this approachable

<emilio> ... I get that to get something comparable to what frameworks are doing we need all of it

<emilio> ... I think we need to make this smaller

<emilio> justinf: I intentionally bypassed a lot of the HTML syntax

<emilio> ... questions that showed up for DOM Parts

<astearns> +1 to finding a minimally useful first step

<emilio> ... maybe we could try to make this more of a map than a concrete proposal

<emilio> +1

<emilio> ydaniv: one of the biggest problems of JS templating today is something that I opened an issue with WHATWG is that they replace DOM and reduce user agency

<emilio> ... one of the more important things for me is to be able to maintain state

<emilio> ... kind of like moveBefore()

<emilio> ... so if we could make that work somehow

<emilio> ... if this could render dom but maintain my states that'd be a great winner

<emilio> justinf: I think this would be useful to have in an issue

<emilio> ... I think it'd be useful to use moveBefore() when possible

<emilio> ... we should talk about it

<emilio> justinf: One thing I'd like is to get a co-champion that could work on this

<trusktr> Hello! I had hand raised in the call. I wasn't able to join here until now. We for sure don't need Dom parts or scheduling up front to have templating.

<emilio> trusktr: The TemplateResult could be passed dom, and schedule can use requestAnimationFrame(), DOM Parts can already be decoupled

<emilio> justinf: parts are more of an spec concept rather than a public API

<emilio> ... you need to explain the behavior

<emilio> trusktr: DOM parts about framework authors and reactivity systems

<emilio> ... they need that access to wire things together

<emilio> ... the typical user doesn't care about how the DOM is updated

<emilio> anne: You still need to specify how its done

<emilio> ... the public API is usually the simpler bit

<emilio> rniwa: yeah the processing model is the hardest part

<emilio> ... foregoing parts would remove some issues

<emilio> ... the main complexity is there

<emilio> ... at the end of the day even if it's a black box it needs to be spec'd

<emilio> trusktr: right but then there's only the question of the order, internally it'd be a setAttribute() call

<emilio> rniwa: yeah but still needs to be well defined because MutationObserver can observe

<emilio> justinf: yeah there's also the need to extend this

<emilio> ... I really want to make this usable by framework authors

<emilio> ... either existing or others, and the DOM Parts API is critical for that

<westbrook> https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md

HTML modules

<westbrook> WICG/webcomponents#1059

<westbrook> WICG/webcomponents#645

<emilio> https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md

<emilio> Jayson: tldr is that we think this is still too early for standardizing HTML modules

<emilio> ... I think HTML modules are different from HTML includes

<emilio> ... People kinda understand it as HTML import

<emilio> ... we need to solve that before but that's a separate topic

<emilio> ... some customer problems we run into

<emilio> ... the problems is repetitive HTML chunks in the DOM tree (can I define it once and just reference it through the doc)

<emilio> ... reusing HTML in multiple places

<emilio> ... All these are actually HTML include, not HTML modules

<emilio> ... in our opinion HTML module should be a system that can import / export resources defined in HTML, that works fine with ES modules

<emilio> ... HTML module similarly we have html with and without scripts, style, template, custom element definitions, scoped custom element registry

<emilio> For modules they want to make the contents dynamic

<emilio> ... the dynamic part can range for content attributes / event handlers / etc

<emilio> ... coming back to HTML modules, even if we standardized them right now it wouldn't solve the more common problems

<emilio> ... e.g. modularizing a template is not possible r/n

<emilio> ... so most of what customers actually ask for is html include

<emilio> ... there's also an existing declarative partial update proposal

<emilio> ... that might be able to address some of the problems

<emilio> ... I would be curious to look into how that proposal could interact with html modules

<emilio> ... so our conclusion is that html modules is relatively low priority with all the other specially declarative capabilities that we are lacking

<emilio> ... can be useful for ergonomics too but that should not be the main motivation

<emilio> ... I believe in a few years when we have templates we could come back for HTML module to move this forward in an easier way

<emilio> ... I think there are use cases that we haven't explored so if you have thoughts feel free to reach out

<emilio> ... or if moz or webkit have more ideas in mind

<emilio> ... thanks

<emilio> keithamus: thanks for going in to the presentation of why we shouldn't do this, I think it was very interesting

<emilio> ... one of the motivating cases about compression

<emilio> ... devs don't want to repeat a blob of HTML and over the wire cost

<emilio> ... I don't think that's a problem that we should be solved

<emilio> ... gzip is very good at this

<emilio> ... so this repetitive HTML in the DOM tree probably should not be something we solve for

<emilio> ... most servers support gzipping arbitrary content without much cost and shared compression dictionaries

<justinf> keithamus: many of these repeated chucks have slight variations, so they need some sort of HTML template

<justinf> but this isn't a HTML Modules feature

<emilio> anne: Not sure HTML modules would get us there but it could also help with memory usage

<emilio> ... we are not trying to deduplicate actual dom nodes

<trusktr> The main goal that I feel causes the concept of HTML Modules to exist is the wanting for Declarative Custom Elements

emilio: there are already several things that can be deduplicated and shared

<emilio> anne: Yeah was just wonder if there would be some optimization possible in the engine for that kind of pattern

<emilio> justinf: I think that's a bit different from html modules

<emilio> rniwa: I tend to agree that it's probably early for HTML includes, we want declarative custom elements first, and HTML import without that feature is really convoluted

<emilio> ... because we need to design it so that it's compatible with it but we still don't have a model for that

<Zakim> rniwa, you wanted to react to keithamus

<emilio> Jayson: agreed, we need those capabilities

<emilio> justinf: declarative custom elements is something where the only agreement is that we need imports for

<emilio> ... so you import the template and you use import that from JS, so if we had HTML modules it could unleash an explosion of these declarative elements with vue and polymer-like systems to inform the declarative custom elements design

<emilio> rniwa: I think that'd be backwards, we don't want to standardize something to allow experimentation

<justinf> https://heximal.dev/

<emilio> justinf: it's a container format right? I have a whole system that I built which is kinda polymer on top of lit or somesuch

<emilio> ... it's cool but I don't want to work on it because there's no way to load these into the page

<emilio> ... otherwise the only way to load these into the main page

<lea> +100 to justinf, have faced the same issues myself in the past, several times

<emilio> ... putting HTML into the module graph would be huge, vue could use it

<emilio> ... as an ergonomic container format

<emilio> anne: You say just but I think we've figured out that it's not "just"

<emilio> justinf: not sure, you should be able to have a declaration and import it and give it a name

<emilio> ... as opposed to being aware of their custom element definitions inside and so on

<emilio> anne: The whole thing about what the container format looks like / does and not is very tricky

<emilio> ... you need this model for detached parts

<emilio> ... and it was hard to figure out

<emilio> ... you might end up making choices that don't interact well with declarative custom elements

<emilio> justinf: I think a lot of the requirements we have for native declarative custom elements are the same for userland, you need this ?? dom and connect to be called

<emilio> ... so you need the element that defines the element to be able to execute

<emilio> ... I think we have a lot of other competing priorities but I think they'd be very useful

<emilio> lea: regarding gzip and the preliminary state-of-html results show that html reuse and templating are at the top of content-related pain points

<emilio> ... it's clear that gzip is not enough

<emilio> ... and that there's a need for better primitives here

<emilio> ... reusing a footer across pages is different than importing html into a custom element

<westbrook> emilio: gzip is one argument that is less powerful, but the other arguments are not excused for it.

<emilio> keithamus: Yeah just want to mention that the over-the-wire cost is not a problem to solve here

<emilio> ... might not even just be a dx

<emilio> ... even in the examples you pointed out the use cases are wildly different

<emilio> ... wasn't implying gzip solves all these problems

<emilio> ... just that over-the-wire cost

<emilio> ... is not something that we should solve here

<emilio> anne: not sure that gzip solves reusing a footer across documents and such

<emilio> keithamus: shared compression dictionaries work for that tho

<emilio> justinf: but yeah that again is html include not module

<emilio> rniwa: yeah this feature is very easy to scope-creep

<emilio> keithamus: we need to both gather use cases but also the why

<emilio> ... because the over-the-wire cost is not a valid response, having slightl variations on the same piece of content is, but fairly different

<emilio> ydaniv: there's a precedent on SVG (<use>)

<justinf> we're still talking about HTML Includes, not HTML Modules though...

<emilio> ydaniv: people can already abuse <use> and <foreignObject> and embedding HTML

<justinf> <use> is an include, not a module

<emilio> ... lots of other problems but we're talking about a lot of extra capability

<lea> ydaniv: my kooky proposal I just mentioned: whatwg/html#11463 😅

<emilio> ... people use the <use> element a lot

<emilio> ... we know how it works

<justinf> Here's a bunch of HTML Module use cases I put together for Jayson that would only need to import/export and use userland features internally: https://gist.github.com/justinfagnani/33c83d8b886e3ed2c362911263e40080

<sorvell> the value, if there is any right now, is about populating the module graph with a reference-able resource of a particular type.. in this case html/dom

<justinf> +1

<emilio> emilio: <use> is different in SVG1 and SVG2, not sure the semantics are what you want (doesn't expose the cloned node to the regular DOM)

<emilio> keithamus: justinf mentioned also that this is includes not modules

<emilio> westbrook: what about getting a group about getting a group to discuss declarative custom elements and html modules?

<justinf> here's my personal map of how these features depend on each other: https://www.mermaidchart.com/play?utm_source=mermaid_js&utm_medium=editor_selection&utm_campaign=playground#pako:eNqNVE1vnDAQ_SsWlXqz-nHoRw6VCssmkbJqtETKoduDA5NiyWBkk6Zp1f9eGxuvAXuX5bDgefPmzXhm_iYlryC5SB4Zfy5rInp0sz-0SP0q3uBOHcjvh2TzbYdu9fsh-YEw_uKMuH6pBOkpbz0UMgQFCEoY_TOY0Rt0NUI1yW

<justinf> vUQ9Mx0gMmHbXOd_YIfb29ViBDI-nPljCtojBvowYBpOzpL8DAoIG2xw9EAi4ZkRq8t9aru91NbgBWV6pgKNMwI8TxjIq0-5a2gC8FUX-V9RsZnUzpNPq5TLU5ThWoAiVOl0Cd133DJgE3R6ONp5UHYsmyhuqJgRiLJgBQMR4uiuNiGO-AsOE-o9JsM0TtC_fySfaqO-ylhFPLBgyy93LMbaBuuM5EOw4V2JlP13nxUIaDtkzfnSwF7XoMvztuevh6OFeV0ucoN-cjqx94Vqhld63TUUrppZIVxclMJuBAwSbuyzuRNan4M1ZjGXQvBjNS7XImuOpSKXVnXUILgjB0Dw-jBN50

<justinf> vNVjVBT7oIhZGc6Uabo6zrTIOBLeCgnE9_JYG9skPN14nnVO4wb9tHi3yE4LXrKt1u3IuPrmwnaN_VixIQ-WQfYvDI67Hj1Sxi5epekm36YhhCfVQLNP-Yfssw-dLMMYn93q1p6_S_P8o28_NX4xzsBui6YT32extNzeXUU6n4UYq794oqDgSoui_TGIYWJjswZ_3DXxWsmxSttt_jZ9v65KK3rrzPSccLOjEW244SJUaQVIqajmpdBP8u8_QRkpfA

<justinf> yikes. sorry for the long url

<emilio> westbrook: would be good to have some focused sessions around some of these problems

<emilio> anne: Having a scoped focus would make it reasonable

<emilio> rniwa: yeah declarative custom elements can scope creep very easily

<emilio> justinf: also a lot of what people presume about this (it's faster, less size) might not hold true

<justinf> we need: whatwg/html#7367

<justinf> scriptEl.exports

<emilio> keithamus: yeah we need to figure out how having a custom element without script is useful

<emilio> annevk: You have the shadow tree

<emilio> keithamus: we have a lot of script, just in a different language

<emilio> rniwa: if you have a template engine then that would give you a JS-free modality

<emilio> justinf: just having expressions would allow injection

<emilio> keithamus: Is that something we need to resolve first

<emilio> ... so if we can't use declarative custom elements because script or templating

<emilio> ... we could solve these before solving for declarative custom elements

<emilio> justinf: that's why I want to do templates

<emilio> rniwa: to me solving template should be a good path forward for solving declarative custom elements

<emilio> ... but declarative custom elements could be explored without that

<emilio> keithamus: yeah not sure how with the current functionality would make a declarative custom element useful

<emilio> ... or associate it with script after it's been instantiated

<emilio> anne: yeah we're likely to need that too

<emilio> ... didn't XBL have inline script

<emilio> justinf: also prototype patching, script.exports

<emilio> lea: wanted to say that for declarative custom elements I see two directions / goals

<emilio> ... one is simpler custom elements for basic things

<emilio> ... and also as a serialization target for SSR

<emilio> ... if the goal is simple things easy there's you need props / expressions and slots

<emilio> ... then you don't need scripting / expression

<emilio> ... as for ssr then we need a more complex API

<justinf> another plug for Heximal as an example DCE system: https://heximal.dev/#components

<emilio> keithamus: on your first point, simple custom elements, I don't think such a thing exists

<emilio> ... actually implementing a custom element with the current feature set wouldn't be possible that isn't trivial to do with existing elements, we'd have less than a handful of use cases

<emilio> lea: that might be right but if we can get 90%?

<emilio> ... what about specifying the delta to the definition?

<emilio> keithamus: that goes back to the question of how you associate script with the definition

<Jayson> The slide earlier: https://docs.google.com/presentation/d/1eKio8ZvoeBqMe0Ao161hE-RaGGRagYTZ28KKL6xOkAg/edit?usp=sharing

<sorvell> we need an... intelligent design.

<trusktr> F

<trusktr> f

<trusktr> f

<trusktr> Sorry, Edge bug, blocks the input on iOS

<trusktr> That's where optional JS helps. I think having HtML Templating before DCE would make DCE much more desirable at that point

Summary of resolutions

  1. Loosen the type checks in HTMLLabelElement.control and .form if not compat constrained. Otherwise consider all potentially-custom-elements as labelable / potentially-a-form
Minutes manually created (not a transcript), formatted by scribe.perl version 248 (Mon Oct 27 20:04:16 2025 UTC).

Diagnostics

Succeeded: s/bty/by

Succeeded: s/ti/it

Succeeded: s/yeah the processing model is the simplest part/yeah the processing model is the hardest part/

Succeeded: s/html reuse and templating are the top priorities/html reuse and templating are at the top of content-related pain points/

Maybe present: alice, annevk, anqevk, emilio, justinf, Kurt, rniwa, sorvell, westbrook

All speakers: alice, annevk, anqevk, emilio, justinf, keithamus, Kurt, lea, rniwa, sorvell, westbrook

Active on IRC: alice, anne, astearns, bkardell, emilio, frehner, Jayson, JRJurman4, justinf, Jxck, keithamus, Kurt, lea, MichaelWarren, nicolo-ribaudo7, ntim, rniwa, sorvell, trusktr, westbrook, ydaniv