Angular Class Binding
Introduction
Angular class binding is a powerful feature that allows you to dynamically apply CSS classes to HTML elements based on component logic. Rather than using traditional JavaScript to manipulate DOM element classes, Angular provides a declarative way to control the appearance of elements based on your application's state. Class binding bridges your component's TypeScript code and your template's HTML, enabling responsive, data-driven styling.
In this guide, you'll learn how to use Angular's class binding syntax to create dynamic, responsive UIs that reflect your application's state.
Basic Class Binding Syntax
Angular offers several ways to bind classes to HTML elements. Let's explore each approach:
1. Single Class Binding
The simplest form of class binding uses square brackets to add or remove a single CSS class:
<div [class.active]="isActive">This div can be active</div>
In your component:
export class MyComponent {
isActive = true; // This will apply the 'active' class
}
When isActive
is true
, the resulting HTML will be:
<div class="active">This div can be active</div>
When isActive
is false
, the class won't be applied:
<div>This div can be active</div>
2. Multiple Class Binding
To bind multiple classes, you can use the [ngClass]
directive:
<div [ngClass]="classObject">Multiple classes can be applied</div>
In your component, you can use an object where keys are class names and values are boolean expressions:
export class MyComponent {
classObject = {
'active': true,
'text-danger': false,
'bold': true
};
}
This will result in:
<div class="active bold">Multiple classes can be applied</div>
3. Class Binding with Expressions
You can also use expressions to determine which classes to apply:
<div [ngClass]="isSpecial ? 'special' : 'not-special'">
Conditionally styled div
</div>
4. Class Binding with Arrays
Arrays can be used with [ngClass]
as well:
<div [ngClass]="['bold', 'italic']">Bold and italic text</div>
Dynamic Class Binding
Class binding becomes particularly powerful when you update the bound properties in response to user interactions or other events.
Let's create a simple toggle button example:
export class ToggleComponent {
isHighlighted = false;
toggleHighlight() {
this.isHighlighted = !this.isHighlighted;
}
}
In the template:
<div [class.highlighted]="isHighlighted">
This text can be highlighted
</div>
<button (click)="toggleHighlight()">
{{ isHighlighted ? 'Remove highlighting' : 'Add highlighting' }}
</button>
Whenever the button is clicked, the isHighlighted
property toggles, which in turn adds or removes the highlighted
class from the div.
Class Binding with Methods
You can also use component methods to determine classes:
<div [ngClass]="getClasses(item)">
Classes determined by an item's properties
</div>
In your component:
export class MyComponent {
getClasses(item) {
return {
'active': item.isActive,
'disabled': !item.isEnabled,
'highlighted': item.isSelected
};
}
}
This pattern is useful when class logic depends on complex conditions or when the same logic needs to be reused for multiple elements.
Combining Static and Dynamic Classes
You can combine static class attributes with class binding:
<div class="card" [class.selected]="isSelected">
This is a card that might be selected
</div>
In this example, the element always has the card
class, but the selected
class is added only when isSelected
is true
.
Practical Examples
Example 1: Navigation Menu
Here's how you might implement an active state for navigation links:
export class NavComponent {
currentPage = 'home';
isActive(page: string): boolean {
return this.currentPage === page;
}
navigate(page: string): void {
this.currentPage = page;
}
}
Template:
<nav>
<ul>
<li [class.active]="isActive('home')" (click)="navigate('home')">Home</li>
<li [class.active]="isActive('about')" (click)="navigate('about')">About</li>
<li [class.active]="isActive('contact')" (click)="navigate('contact')">Contact</li>
</ul>
</nav>
Example 2: Form Validation
Class binding works well with form validation:
import { FormControl, FormGroup, Validators } from '@angular/forms';
export class SignupFormComponent {
signupForm = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email]),
password: new FormControl('', [Validators.required])
});
get email() { return this.signupForm.get('email'); }
get password() { return this.signupForm.get('password'); }
}
Template:
<form [formGroup]="signupForm">
<div class="form-group">
<label for="email">Email</label>
<input
id="email"
formControlName="email"
[ngClass]="{
'is-invalid': email.invalid && (email.dirty || email.touched),
'is-valid': email.valid && (email.dirty || email.touched)
}">
<div
*ngIf="email.invalid && (email.dirty || email.touched)"
class="error-message">
Please enter a valid email address.
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input
id="password"
type="password"
formControlName="password"
[ngClass]="{
'is-invalid': password.invalid && (password.dirty || password.touched),
'is-valid': password.valid && (password.dirty || password.touched)
}">
</div>
</form>
Example 3: Data List with Filtering
Here's an example showing how to apply different classes based on data properties:
export class ProductListComponent {
products = [
{ id: 1, name: 'Laptop', price: 1200, inStock: true },
{ id: 2, name: 'Phone', price: 800, inStock: true },
{ id: 3, name: 'Tablet', price: 500, inStock: false }
];
getProductClasses(product) {
return {
'out-of-stock': !product.inStock,
'premium-product': product.price > 1000,
'standard-product': product.price <= 1000
};
}
}
Template:
<div class="product-list">
<div
*ngFor="let product of products"
class="product-item"
[ngClass]="getProductClasses(product)">
<h3>{{ product.name }}</h3>
<p>Price: {{ product.price | currency }}</p>
<p [class.text-danger]="!product.inStock">
{{ product.inStock ? 'In Stock' : 'Out of Stock' }}
</p>
</div>
</div>
Class Binding Performance Considerations
While class binding is powerful, keep these performance tips in mind:
- For simple cases with one or two classes, use
[class.name]="condition"
syntax. - For multiple classes that depend on the same conditions, group them with
[ngClass]
. - Avoid complex expressions in your templates; move logic to your component.
- For frequently updating lists, consider using
trackBy
with*ngFor
to improve performance.
Summary
Angular's class binding provides a declarative way to dynamically style elements based on your application's state:
- Use
[class.name]="condition"
for binding a single class - Use
[ngClass]
for multiple classes with objects, arrays, or expressions - Combine static classes with dynamic binding for more complex styling
- Leverage class binding for practical scenarios like navigation, form validation, and data presentation
By mastering class binding, you can create more responsive and user-friendly interfaces that adapt to changes in your application's state without manual DOM manipulation.
Additional Resources
Exercises
- Create a simple to-do list where completed tasks get a "completed" class that strikes through the text.
- Build a photo gallery with thumbnails that show an "active" class when selected.
- Implement a theme switcher that changes multiple classes across your application (light/dark mode).
- Create a form with validation feedback that uses class binding to show error states.
Happy coding with Angular class binding!
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)