Reusable Behavior Without a Template
Attribute & Structural Directives
Directives attach behaviour to existing elements. Attribute directives change appearance or behaviour; structural directives change DOM layout.
What you'll learn
- Write an attribute directive with @Directive
- Use built-in structural directives
- Apply host config from a directive
A directive is a class with a selector that gets attached to elements — like a component without a template.
Attribute Directive
import { Directive, ElementRef, inject, input } from '@angular/core';
@Directive({
selector: '[appHighlight]',
standalone: true,
host: {
'(mouseenter)': 'on()',
'(mouseleave)': 'off()',
},
})
export class HighlightDirective {
color = input('yellow', { alias: 'appHighlight' });
private el = inject(ElementRef<HTMLElement>);
on() { this.el.nativeElement.style.background = this.color(); }
off() { this.el.nativeElement.style.background = ''; }
} Use it like an HTML attribute:
<p [appHighlight]="'lightblue'">Hover me</p> Structural Directives
Structural directives (the * ones) reshape the DOM by adding or removing elements. *ngIf and *ngFor still exist, but modern Angular has replaced them with the @if and @for control flow blocks built into the template syntax.
@if (user(); as u) {
<p>Hi, {{ u.name }}</p>
} @else {
<p>Loading...</p>
}
@for (item of items(); track item.id) {
<li>{{ item.name }}</li>
} Writing your own custom structural directive is rare these days — the built-in blocks handle the common cases.
Directives vs Components
A component is a directive with a template. Everything you can do on a component’s host config (classes, listeners, attribute bindings) works the same on a directive.