Angular Classes with NgClass

Angular Tagged in Angular Jan 18, 2018 3 mins read by Todd Motto

With Angular, we have many approaches to adding, removing, toggling classes. We can choose single classes and bind a property, or we can use the awesome NgClass directive from Angular.

In this post, we’ll explore class bindings, and also Angular’s NgClass directive, the syntaxes and also some best practice ideas.

It’s a frequent requirement to add some kind of “state” to the DOM, typically via classes. Let’s explore some quick and easy options we have with Angular.

Property Binding with className

Before we jump into NgClass, let’s explore some sugar syntax that’s simple yet effective. When working with single classes, I much prefer and advocate this approach over diving into NgClass, it’s faster to work with and I find it’s more descriptive when analysing existing code.

So, what does it look like?

In JavaScript DOM, we have a className property available on DOM elements:

const div = document.querySelector('div');
div.className = 'hello';
console.log(div.className); // 'hello'

Nice and easy. But, in Angular we’re working with templates and bindings - not DOM APIs such as querySelector.

In Angular, we bind to properties, not attribute. Which means we can turn this knowledge into:

<div [className]="'active'"></div>

Angular will then lookup the JavaScript property of className and bind our expression to it.

As a side note, take interpolation for example:

<h1>{{ text }}</h1>

Really, this is sugar syntax for:

<h1 [innerText]="text"></h1>

Anyway, back to classes. It might be that we wish to provide a conditional to our className:

<div [className]="condition ? 'active' : 'inactive'"></div>

Bear in mind, we cannot do this:

<!--  if the condition is false, we will end up with class="false" -->
<div [className]="condition && 'active'"></div>

We want to avoid this, and supply a class at all times, unless we don’t want that behaviour. So what about just one class?

Property binding with “class”

Angular has a shorthand syntax for supplying a class that I absolutely love:

<div [class.active]="condition"></div>

When condition evaluates to true, the class of active will be added. When false, active is then removed. This is really nice, clean and concise.

What about more complex classes, perhaps using the BEM (Block-Element-Modifier) syntax?

<div [class.is-active]="condition"></div>

That’s all we need. Thankfully we don’t need to supply the is-active inside a string, which you might expect when using a dash.

It’s time for some NgClass, a more flexible approach - and one I’d use when we need multiple classes.

Angular’s NgClass Directive

We should use NgClass when we’re expecting multiple classes to be potentially added.

The basic syntax of NgClass:

string | string[] | Set<string> | { [klass: string]: any }

This means we can supply single strings, arrays of strings, Sets, and object literals. Really, we just care about the object literal approach, strings and string arrays allow us to set classes, but not remove them - because there’s no conditional data powering their existence:

<div [ngClass]="'active'"></div>
<div [ngClass]="['active', 'open']"></div>

So, let’s investigate object literals with NgClass:

<div [ngClass]="{
  active: condition
}">
</div>

Just like our previous example with [class.active] - this essentially does the same thing.

Note, however, we cannot do this:

<!-- errors -->
<div [ngClass]="{
  is-active: condition
}">
</div>

Why? Because this is an object literal, keys cannot be set using dashes without using a string syntax:

<!-- works -->
<div [ngClass]="{
  'is-active': condition
}">
</div>

If you need a more complex CSS class, use a string. If you like, keep your keys consistent and always use a string even if it’s not needed. This may be a sensible styling choice within your team.

Multiple Classes with NgClass

So far we’ve covered adding and removing single classes with NgClass, so let’s look at a more ideal solution with multiple classes.

It’s also worth noting that the condition we supply as the value of the object literal key, will be evaluated. This means we can use ternary statements, or negate expressions:

<div [ngClass]="{
  'is-active': condition,
  'is-inactive': !condition,
  'is-focused': condition && anotherCondition,
}">
</div>

And there you have the majority of use cases you’ll ever need when it comes to NgClass. For readability purposes, I would encourage you to bump conditions onto new lines as demonstrated above. It’s easy to scan, read, and evaluate what’s happening in your codebase.

Mixing class and NgClass

When it comes to keeping your codebase consistent, which is a must, choose one approach and stick with it.

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 the rule is pick one, be consistent and maintainable.

Angular Online Courses Angular shields
Ultimate Angular

Everything you need to master Angular

Online courses that give you the knowledge to master Angular and build real world applications. Join 45,000 others today.

Start now Navigation arrow