Attribute & Structural Directives

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.

4 min read Level 2/5 #angular#directives
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.

Dynamic Components →