webcomponents-cg icon indicating copy to clipboard operation
webcomponents-cg copied to clipboard

Isolating Props from Attributes in Custom Elements

Open jmiguelrivas opened this issue 5 months ago • 0 comments

When building Web Components, we often map HTML attributes directly to internal component properties. But as HTML evolves and introduces more native attributes (like size, color, variant, etc.), collisions are increasingly likely.

Consider this example:

<nn-pilar size="50% - 1rem"></nn-pilar>

Here, size is not currently a global attribute in HTML, but it could become one in the future. If it does, your component’s size prop might conflict with a native behavior, or lead to unexpected rendering quirks.

To avoid this, I’m exploring ways to clearly separate component props from native attributes.

Proposal: Use a namespaced attribute prefix for props

Instead of merging concepts like this:

<nn-pilar p-size="50% - 1rem"></nn-pilar>

Which still flattens the concept of "props" into a string key, I propose something more explicitly nested:

<nn-pilar p.size="50% - 1rem"></nn-pilar>

This form visually and semantically distinguishes component props from native attributes, and mirrors JavaScript object notation:

props: {
  size: '50% - 1rem'
}

In JavaScript, you could then access these props with a method like:

this.getProp('size') // "50% - 1rem"

This approach:

  • Prevents future naming collisions with HTML.
  • Encourages clear mental models, where attributes like p.size are clearly part of a namespaced prop system.
  • Keeps DOM clean, without overloading generic or ambiguous attributes.

Notes:

  • While p-size is valid HTML, dashes don’t convey nesting or ownership—they flatten the structure. Using . in attributes better reflects scoped data (e.g., p.size, i18n.key, config.theme, etc.).
  • This mirrors the way many frameworks (Vue, React props, etc.) handle structured state or namespacing.

jmiguelrivas avatar May 26 '25 08:05 jmiguelrivas