When you first start working with Angular, directives can feel confusing. Why do some directives add or remove elements from the DOM while others just change styles or behavior?
The reason is simple: Angular divides directives into two major categories — Structural and Attribute directives.
This article explains the difference with real examples, practical use-cases, do/don’t guidelines, and comparison charts.
1. What Are Directives in Angular?
A directive is a class that can modify the DOM or the behavior of a DOM element/component.
Angular has three types of directives:
Components (a template + logic)
Structural Directives (*ngIf, *ngFor, *ngSwitch)
Attribute Directives (ngClass, ngStyle, ngModel, custom attributes)
This article focuses on Structural vs Attribute directives.
2. Structural Directives — They Change the DOM Structure
Structural directives add, remove, or manipulate DOM elements.
They always start with an asterisk * because Angular transforms the syntax internally.
Examples
*ngIf
*ngFor
*ngSwitchCase
*ngSwitchDefault
How Structural Directives Work
They shape your DOM by creating or destroying elements.
Example using *ngIf:
<div *ngIf="isLoggedIn">
Welcome back!
</div>
If isLoggedIn = false, Angular removes the entire <div> from the DOM.
Case Study Example
Imagine a dashboard that only shows “Admin Panel” to admin users:
<div *ngIf="user.role === 'admin'">
<app-admin-panel></app-admin-panel>
</div>
This directive determines whether the element exists or not.
When to Use Structural Directives
3. Attribute Directives — They Modify Existing Elements
Attribute directives do not add or remove elements.
Instead, they simply change the appearance or behavior of an existing element.
Examples
How Attribute Directives Work
<div [ngClass]="{ 'active': isActive }">
Menu Item
</div>
The <div> element remains in the DOM — only its styling changes.
Case Study Example
Highlight an input when the value is invalid:
<input [ngStyle]="{ borderColor: isInvalid ? 'red' : 'grey' }" />
When to Use Attribute Directives
Changing CSS classes
Applying dynamic styles
Handling user interactions
Adding custom behaviors (e.g., auto-focus, hover effects)
4. Visual Comparison (Easy To Remember)
| Feature | Structural Directives | Attribute Directives |
|---|
| Changes DOM structure | Yes | No |
| Adds/removes elements | Yes | No |
| Asterisk required | Yes | No |
| Affects layout | Yes | Sometimes |
| Purpose | Control existence of elements | Control appearance or behavior |
| Examples | *ngIf, *ngFor | ngClass, ngStyle |
5. Real-World Example: Using Both Together
Scenario
You want to show a list of active users.
If no users are active, show a message.
<div *ngIf="users.length > 0; else noUsers">
<div *ngFor="let user of users" [ngClass]="{ 'online': user.isActive }">
{{ user.name }}
</div>
</div>
<ng-template #noUsers>
<p>No active users found.</p>
</ng-template>
Structural (*ngIf, *ngFor) controls rendering.
Attribute (ngClass) controls styling.
6. Creating Your Own Structural Directive (Simplified)
Example: Show content only if today is Monday
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[showIfMonday]'
})
export class ShowIfMondayDirective {
constructor(
private template: TemplateRef<any>,
private view: ViewContainerRef
) {
const isMonday = new Date().getDay() === 1;
if (isMonday) {
this.view.createEmbeddedView(this.template);
}
}
}
Usage:
<div *showIfMonday>
Happy Monday!
</div>
This literally creates a structural directive that adds or removes the element.
7. Creating Your Own Attribute Directive
Example: Auto highlight on hover
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[hoverHighlight]'
})
export class HoverHighlightDirective {
constructor(private el: ElementRef) {}
@HostListener('mouseenter')
onMouseEnter() {
this.el.nativeElement.style.background = 'yellow';
}
@HostListener('mouseleave')
onMouseLeave() {
this.el.nativeElement.style.background = null;
}
}
Usage:
<p hoverHighlight>Hover me</p>
This changes behavior, not structure.
8. Best Practices
Structural Directives
Avoid using more than one structural directive on the same element
Example:
Incorrect:
<div *ngIf="isReady" *ngFor="let item of items">...</div>
Use <ng-container> instead.
Prefer ng-container to avoid unnecessary HTML elements
Attribute Directives
Use attribute directives for reusable styling logic
Do not use DOM manipulation directly unless absolutely needed
Prefer Renderer2 for safe DOM modifications
9. Summary
Structural directives modify the structure of the DOM (add/remove elements).
Attribute directives modify the appearance or behavior of existing elements.
Both are essential in building dynamic, maintainable, and scalable Angular applications.