W3C

– DRAFT –
Custom Attributes for all

12 November 2025

Attendees

Present
alisonmaher, christianliebel, frehner, JakeA, jugglinmike, kizu, lea, LeoLee, noamr, plinss, ydaniv
Regrets
-
Chair
Keith Cirkel, Lea Verou
Scribe
noamr

Meeting minutes

keithamus: use case first. I want to find a way to have lifecycle hooks for attributes

<JRJurman> room is muted

keithamus: prior to the react rewrite at github, we used mutation observers to respond to attribute changes. kind of an "HTML mixin"

<kizu> Room is muted in Zoom

keithamus: e.g. <form data-sudo-required>, e.g. for authentication, with a sudo dialog
… gives you superpowers on the elemeent
… libraries like turbo used this to mark regions for later updates
… mutation observers are clunky. we used a 10000 char long selectors which had bugs
… e.g define a class that extends an Attribute, and it would get connectedCallback/disconnectedCallback/changeCallback
… use cases are well defined. we're not sure about constraints, probably similar to custom elements, e.g. naming constraints

lea: mutation observers are not trivial, because of shadow roots, you can't select across shadow root or observe across roots

keithamus: a list of use cases. see possibilities. linked in IRC

keithamus: https://workflowy.com/s/use-cases-for-custom/wpPt2tuPRhvpk3fW

<keithamus> w3c/tpac2025-breakouts#46

JakeA: disconnectedCallback. do you still know which element this is?

JakeA: might be too have the old element in the callback

keithamus: I was imagining that disconnectedCallback would be called when the attribute node is disconnected

keithamus: it would fire whenever it is connected to an element

WICG/webcomponents#1029

zcorpan: you want to know when you set/remove the attributes but also when the element is connected/disconnected

plinss: I would expect it would work the same as connecting nested element trees

keithamus: I suppose it could have added/removed callbacks that would surface this

lea: connectedCallback has an established minutes, but for attributes you can see it both ways. the q of what connectedCallback does for the attributeNode is still open in that way

keithamus: what I would like to do is match the same semantics. connectedCallback is as similar as possible as connectedCallback in elements. it's cheap to implement new callbacks

rniwa: do you call the constructor when the attribute is added?

plinss: persume it's called when the attribute is set

rniwa: e.g. you add attribute foo, and then set to a different value

JakeA: probably the same as the DOM

keithamus: one constructor call for the lifetime of the attribute. following attribute calls would change it in place

keithamus: emilio was concerned about Attr. sometimes engines don't construct this. potential cost.

smaug: was going to ask about this

smaug: implementations optimize attributes... they are not Attribute objects in the implementation

<JakeA> https://dom.spec.whatwg.org/#dom-element-setattribute - updates the existing attribute. This works in terms of instances too.

zcorpan: might be better to have disconnectedFromAttr

keithamus: emilio suggested that we have a controlling class that manages the entire document's list of these attributes. not like custom elements, but for all instances of an attribute. worried about ergonomics

zcorpan: I wonder if it makes sense to put the lifetime on the element

rniwa: that's not how attr works

zcorpan: thinking on this in terms of how this is spec'ed

lea: I tested what happens today. if you set attribute and then it change its value its preserved. if you remove it and re-set it you get a new attribute node

<lea> https://usercontent.irccloud-cdn.com/file/A8Q6VeVY/image.png

rniwa: set is change is in place

<TabAtkins> noamr: the way i'm used to working with this in libraries

<TabAtkins> noamr: is to think of it like a Mixin, rather than a pair of attributes

<TabAtkins> noamr: several xample of shared state, like commandfor

<JakeA> lea: ahh yeah, I was thinking of another thing

<TabAtkins> noamr: it relates to an element, but thinking of it like a Mixin feels better to me as an author

<TabAtkins> noamr: was wondering if you'd thought of it like that

<TabAtkins> keithamus: using this system i'd probably use event dispatch on Attr nodes to handle cooperation

<TabAtkins> keithamus: but I could see it getting clunky

<TabAtkins> keithamus: looking at use-cases on GitHub codebase, I coudln't see many that relied heavily on cooperation

<TabAtkins> keithamus: so I wonder if there is appetite for more of these cooperative attributes vs standalone ones

<JakeA> https://usercontent.irccloud-cdn.com/file/9piDB1yF/Screenshot%202025-11-12%20at%2016.37.05.png

keithamus: I could foresee using event dispatch on the attribute node for collaboration, perhaps it's clunky. at least on github we didn't rely on heavily on cooperation. I wonder if there was appetite for this cooperative usage of attribute

<TabAtkins> keithamus: from my exp it seems like standalone is more predominant

<JakeA> lea: ^

rniwa: there might be behavior that needs to change, regardless of an attribute

<JakeA> :D

rniwa: it's places where we need more mixins

westbrook: there was an idea about a single container class, but sounds like it's across shadow boundaries

lea: about mixins, there are many cases where multiple attribute collaborate
… there is a discussion about class composition which is pertinent to this

<westbrook> noamr: reminder about the complexity around leveraging these on built-ins...

keithamus: one of the interesting thing is that customized built-ins is that you can use this attributes for customizing builtins in a more palatable way

keithamus: there is a lack of ability to using these things on mixins

lea: some proposals can apply to existing classes

JakeA: patching built-ins is interesting. e.g. form that behaves like a form with enhancements

<lea> Or just exposing `observedAttributes` and `attributeChangedCallback` on `HTMLElement`?

JakeA: is it possible to transport an Attr node between elements

rniwa: one design constraint for mutation observer is that they can chain
… I wonder if we need to consider this in regards to custom elements affecting each other in unexpected ways

keithamus: even if we establish a contract, nothing is stopping authors from doing this
… good feedback

plinss: re mixins, I am concerned re "I'm used to doing this"
… there is value in doing it this way
… it's common in custom elements to reflect between properties and attributes

keithamus: we proposed having static definition of reflection

lea: it might solve it sooner if it doesn't solve this problem

plinss: it's not a hard requirement

plinss: it's nice if it fits into whatever lands

keithamus: lots of issues about cleaning up that stuff

plinss: would be good to solve this in the grander scheme

lea: it's tedious and error prone to do this manually

keithamus: there will be some broilerplate on the custom element to do the attribute/property reflection

rniwa: about registration lifecycle

zcorpan: you can have a filtered list of tag names for each attribute name

zcorpan: I don't think we want to set random properties on existing elements

keithamus: some only make sense only for an element

lea: or a class of elements

keithamus: not sure if that should be in the engine vs. userland

JakeA: this is separate from attributes

JakeA: the right way to do this is that the property is always there

rniwa: this should modify the prototype of these elements

keithamus: is that concerning because of the way IDL properties are named given the custom attributes

keithamus: what kind of namespace we give custom attributes?

lea: either we create an IDL attribute, or you require this to be explicit

<zcorpan> <el foo-bar=""> -> element.custom.fooBar

westbrook: we did this as custom element attribute that ended up being used by the platform, e.g. popover

lea: it's still easy to create conflicts

keithamus: hoping it's a 2nd order problem

lea: you could check if an IDL attribute exists

keithamus: need to exclude e.g. data-*, aria-*, some existing things from MathML

alex: is there a namepsace for reserved names?

alex: is that too long?

TabAtkins: yes generally

zcorpan: data-* is author namespace

JakeA: double dash
… ?

lea: can we not?

keithamus: pressing concerns?

sorvell9: my concern is related to the design overlap between this and custom elements, and it's not a stopper, it feels like you have a lot of the custom-element issues, plus new problems that come with mixin behaviors. this applies to however we do this

sorvell9: if this is very similar to custom elements, could it just replace it? what is the distinction?
… why wouldn't people use this as a drop-in replacement instead of custom elements
… why not start with having this a replacement for custom-elements
… if you save this, why not replace custom elements? Maybe this is better?

lea: re mixins, it exists in many languages, there are philosophical/practical issues. traits vs. identity, not always a "component"
… when all you can do is a component, everything looks like a component
… web components are different from framework components. e.g. in React you can wrap your elements numerous times. also Vue etc
… in web components you can't have elements that add to a table without breaking the table due to parsing rules

sorvell9: I hear it as "this is just a better feature"

lea: I don't think you would make a DIV into an INPUT by adding a mixin to it
… I think you need both

<kizu> Custom elements could have their own sets of attributes associated with them, while with custom attributes it will be much harder to express it

keithamus: I think you need both. it's a semantic choice. my interpretation of this design. it makes it easier to make this semantic distinction
… there are certain things that attributes don't give you, like customStateSet

sorvell9: what I am roughly proposing is that we make this have all of the same powers that custom elements have. except for it not being exclusive

keithamus: makes it difficult to manage customStateSet and other things

sorvell9: you're introducing it anyway

lea: I agree. we will eventually need to figure out how it works with rendering content. We don't have a good answer for inheritance. I see many cases for customStateSet

sorvell9: you're not really restrict me with this

rniwa: I don't think we should let those attribute access closed shadow roots

JakeA: you're either saying "I want video elements to support this attribute", and then the getters would be there from the very start
… or, I'm using this attribute to change this form to say "this is my form, override this form"

<ydaniv> noamr: isn't that a sort of a mixin?

<ydaniv> JakeA: yeah

lea: this seems like a workaround for customized built ins

<JakeA> noamr: Could we just use data-

<JakeA> noamr: there's already dataset

<JakeA> noamr: we just need observability

<JakeA> lea: there's a set of mutation observers you could use to make this work. but you want connectedness & ability to cross shadow roots

<JakeA> noamr: we need more APIs added, but data- could be the start

keithamus: I like in this design that it takes from custom elements

rniwa: next steps?

keithamus: temperature of the room?
… interested in the dataset thing. mild concerns.
… need to figure out a concrete API
… haven't heard significant concerns/objections

Minutes manually created (not a transcript), formatted by scribe.perl version 248 (Mon Oct 27 20:04:16 2025 UTC).

Diagnostics

Succeeded: s/noam:/noamr:/

Maybe present: alex, keithamus, rniwa, smaug, sorvell9, TabAtkins, westbrook, zcorpan

All speakers: alex, JakeA, keithamus, lea, plinss, rniwa, smaug, sorvell9, TabAtkins, westbrook, zcorpan

Active on IRC: alisonmaher, breakout-bot, christianliebel, frehner, JakeA, JRJurman, jugglinmike, keithamus, kizu, lea, LeoLee, noamr, plinss, smaug, sorvell9, TabAtkins, westbrook, ydaniv, zcorpan