In this post you’ll learn how to use the NgClass directive in Angular to dynamically assign class names to elements or components.
The NgClass directive syntax is concise and supports more complex logic, to allow us to have finer control over our class names.
First, let’s explore the HTML and JavaScript way and then look at how to add or remove classes with Angular’s many built-in approaches.
Classnames without Angular
In HTML, we can write declare a class via the class
attribute:
<div
class="list">
</div>
If we wanted to add a class to it, we could use the className
property that exists on Element objects to set or get a class:
const el = document.querySelector('.list');
el.className += ' active';
console.log(el.className); // 'list active'
Property Binding with className
First, let’s investigate the className
property binding with Angular. This approach allows us to set a class via the native className
property that we demonstrated above.
To bind to the className
property using Angular, we’ll need to using the []
binding syntax to directly bind to a property:
<div
[className]="'active'">
</div>
Angular binds to the className
property and passes our string value 'active'
as data.
We can now compose more complex [className]
logic using Angular expressions with the ternary operator:
<div
[className]="isActive ? 'active' : 'inactive'">
</div>
If isActive
results to true
our 'active'
class is added, otherwise 'inactive'
would remain, giving us some toggling capability. This is just one example, and it’s not common that we would need to supply 'inactive'
in this case.
You could use className
to compose more complex classes, but this defeats the purpose of using NgClass in Angular. However, before we do let’s look at how to use Angular’s binding syntax to toggle a class.
Property binding with “class”
To toggle a class with Angular, we can use the [class.class-name]
syntax to supply a condition to be evaluated:
<div
class="list"
[class.active]="isActive">
</div>
📢 This
[class]
syntax is actually part of Angular’s NgClass directive, through@Input('class')
.
When our isActive
results to true
the active
class will be added (otherwise removed). Also note that we can combine class="list"
with [class.active]
(this does not work with [className]
they cannot be combined).
This [class]
syntax also supports kebab-case (using a hyphen between words such as is-active
):
<div
[class.is-active]="isActive">
</div>
This syntax also supports expressions as well for better control:
<div
[class.is-active]="isActive && isAdmin">
</div>
If any expression results false
the is-active
will be removed.
I’d highly recommend using the [class.class-name]
syntax over [className]
because Angular handles it, the other is pretty much plain DOM bindings and no Angular superpowers.
Angular’s NgClass Directive
So far we’ve looked at adding just single classes, which is something the NgClass directive can also help us with as it supports multiple classes. Using multiple classes is the real reason to use the NgClass directive.
You can think of NgClass as being able to specify multiple [class.class-name]
on the same element. We already learned that [class]
is an @Input('class')
of NgClass - so what other syntax can we use?
@Input('class')
klass: string
@Input()
ngClass: string | string[] | Set<string> | { [klass: string]: any; }
This gives us four options for setting classes in Angular.
The first two, string
and string[]
:
<div
[ngClass]="'active'">
</div>
<div
[ngClass]="['active', 'open']">
</div>
It might be that you’re adding these from a theme or from user settings and wish to dynamically add an array of class names.
Ignoring Set<string>
, because no one uses this, let’s look at the object literal approach { [klass: string]: any; }
:
<div
[ngClass]="{
active: isActive
}">
</div>
This gives us the exact same result as [class.active]="isActive"
but uses the NgClass directive to toggle a class.
Multiple Classes with NgClass
We can also supply multiple classes inside the object:
<div
[ngClass]="{
active: isActive,
admin: isAdmin,
subscriber: !isAdmin
}">
</div>
And there you have it, the power of NgClass for adding css classes to your elements or components in Angular.
One thing I should mention is that for any kebab-case strings (such as is-active
) you’ll need to use quotes around the class name:
<div
[ngClass]="{
'is-active': isActive,
admin: isAdmin
}">
</div>
It will error otherwise because it’s an object key, and object keys cannot contain hyphens unless you put them in quotes.
Summary
So far we’ve covered [className]
, [class]
and [ngClass]
bindings and explored the differences between them.
My recommendation is to use [class.class-name]
where appropriate to keep things simple and clean, and where more complex class manipulation is needed - use the NgClass directive!
Free eBook
Directives, simple right? Wrong! On the outside they look simple, but even skilled Angular devs haven’t grasped every concept in this eBook.
- Observables and Async Pipe
- Identity Checking and Performance
- Web Components <ng-template> syntax
- <ng-container> and Observable Composition
- Advanced Rendering Patterns
- Setters and Getters for Styles and Class Bindings
It might be you and your team prefer to use [class.foo]
style syntax for the majority of use cases, and simply adopt NgClass
when introducing more complex scenarios. Or, you may favour just using NgClass
- but my rule is pick one, be consistent and maintainable.
If you are serious about your Angular skills, your next step is to take a look at my Angular courses where you’ll learn Angular, TypeScript, RxJS and state management principles from beginning to expert level.
Happy coding!