Skip to content

Instantly share code, notes, and snippets.

@Acetoshi
Last active July 29, 2025 15:02
Show Gist options
  • Select an option

  • Save Acetoshi/f2a4ae36e49ac55a25291418a4316515 to your computer and use it in GitHub Desktop.

Select an option

Save Acetoshi/f2a4ae36e49ac55a25291418a4316515 to your computer and use it in GitHub Desktop.
Angular component semantics

πŸ’‘ Angular Component Selectors and HTML Semantics: A Clean Solution

In modern web development, writing semantically correct HTML is important β€” for accessibility, browser consistency, and maintainability. But if you're using Angular, you may have run into a frustrating problem: Angular component selectors don’t always play nicely with HTML hierarchy.


🚧 Part 1: The Problem β€” Angular Component Tags Break HTML Semantics

By default, Angular components are used with custom tags like:

<app-my-component></app-my-component>

But what if you're rendering a list of items?

<ul>
  <app-my-component></app-my-component>
</ul>

Problem: This structure is invalid HTML. According to the HTML spec, a <ul> must only contain <li> elements. Using a custom element like <app-my-component> breaks semantics, accessibility, and can even confuse assistive technologies.


βœ… Part 2: The Solution β€” Use Attribute Selectors on Native Tags

Angular allows you to define components that attach to native HTML elements using an attribute selector.

πŸ”§ Step-by-step

In your component:

@Component({
  selector: 'li[app-my-component]',
  templateUrl: './my-component.component.html',
  styleUrls: ['./my-component.component.scss']
})
export class MyComponent {
  @Input() data: any;
}

And in your parent template:

<ul>
  <li app-my-component  [data]="INPUT_DATA"></li>
</ul>

Now:

  • βœ… Your DOM is fully valid
  • βœ… Your Angular component logic is preserved
  • βœ… The list structure is semantic and accessible

πŸ“š Official Documentation

This technique is based on Angular’s support for attribute selectors in components.

It’s commonly used for cases like <button my-button> or <input custom-input>, but works equally well for list items or any other native HTML tags.


🎯 Conclusion

If you're building components that need to fit into specific HTML structures β€” like <ul>/<li>, <table>/<tr>, etc. β€” don’t force custom component tags where they don’t belong.

Instead, use attribute selectors to get the power of Angular components without breaking HTML semantics.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment