HTML Attributes vs. DOM Properties

When to Use Properties vs. Attributes

  • Properties allow non-string values (objects, streams, callbacks) without manual serialization; attributes are always strings.
  • Useful cases mentioned: passing objects into web components, attaching event listeners or custom data, using video.srcObject for media streams.
  • Properties are preferred when data doesn’t need to appear in HTML or be serialized.
  • Some developers argue complex data shouldn’t live on DOM nodes at all and avoid such patterns.

Reflection and the Attribute–Property Mapping

  • Many attributes have corresponding properties that “reflect” them (e.g., id, some booleans, value/defaultValue on inputs).
  • An attribute like x with no spec-defined property remains only an attribute; element.x is undefined.
  • For inputs, the value attribute initializes an internal value; the value property reads/writes that internal state, not the original attribute. defaultValue reflects the attribute instead.
  • There is debate and confusion over where values are “stored” and how specs/MDN describe this.

data- Attributes and dataset*

  • data-* attributes bridge HTML and JS: accessible via .dataset with automatic kebab→camel conversion.
  • Conversion around acronyms (e.g., ID, HTML, UI) is seen as inconsistent and annoying.
  • Some prefer getAttribute/setAttribute to avoid case-conversion mental overhead.
  • data-* is also used from CSS via attribute selectors and limited attr() usage.

Web Components and Frameworks

  • Custom elements commonly rely on properties to accept rich JS values, mirroring “props” in frameworks.
  • This increases exposure to attribute/property mismatch and leads to boilerplate (attributeChangedCallback, proxies, serialization).
  • JSX-like syntaxes don’t actually use HTML attributes; they set properties (e.g., className, htmlFor), which some find confusing or ugly.

Design Critiques and Model Confusion

  • Some argue the split between attributes and properties adds complexity with little benefit, wishing they were unified.
  • Others counter that unification would either forbid non-string values or break method-based APIs.
  • Proposals to allow non-string attribute values raise serialization issues, compared to JSON’s limits (e.g., Date, prototypes).
  • There is a side discussion about DOM being language-agnostic and distinct from JS objects, with disputed claims about object lifetimes and garbage collection. Behavior here is contested in the thread and not fully resolved.