Search⌘ K
AI Features

The ngClass Directive

Explore how to use Angular's ngClass directive to dynamically apply CSS classes based on component properties. Learn to highlight active buttons and disable navigation controls conditionally, improving your app's interactivity. Understand applying objects or functions to ngClass for cleaner templates and effective styling control.

We have a set of buttons for navigating through the images. They look great, but let’s make them more interactive. The buttons should change color if the corresponding image is in view. This will indicate which image a user is viewing.

Bootstrap comes with classes for changing the color of the buttons. They’re the active and disabled classes.

The active class

The active class will highlight the button in blue. If we want to apply this class, we’ll need to figure out which button to apply it to. We’ll keep track of which button to add the class to by creating a property in the app.component.ts file.

export class AppComponent {
  activeImg = 0;
  // Other code....
}

The value of the activeImg property will be the index of the button. We can update the loop in the app.component.html file to use this property.

HTML
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="#">Previous</a>
</li>
<li class="page-item" *ngFor="let img of images; let i = index;"
[ngClass]="{ active: i === activeImg }">
<a class="page-link" href="#">{{ i + 1 }}</a>
</li>
<li class="page-item">
<a class="page-link" href="#">Next</a>
</li>
</ul>

On the <li> element with the ngFor directive applied to it, we’re using a new directive called ngClass. This directive will allow us to bind a dynamic class to the element. The value for this can be an object of classes to apply to the element. We must surround the name of the directive with square brackets if we want to bind it.

The property will represent the class name, and the value will be the condition to check if the class should be applied to the element. If the condition evaluates to true, then the class will be added. Otherwise, it won’t be added or, if the class is already on the element, it will get removed.

One thing you’ll notice is that we’re using the class attribute and ngClass directive at the same time. Angular will take care of merging them.

Here’s the condition we’re using for the active class: i === activeImg

In this example, we’re comparing the index and activeItem property in the component. This should add the active class to the first button in the loop since the property’s default value is 0.

The ngClass directive is an attribute directive. It’s a category of directives that will change the appearance or behavior of an element. They’re different from structural directives because they’ll change the DOM layout by adding/removing elements.

The disable class

Another class we’ll be applying to the buttons is the disable class. This will change the styles of a button to make it look like we can’t interact with it. We’ll want to apply it to the next and previous buttons. The previous button should be disabled if the user is on the first image. The next button should be disabled if the user is on the last image.

HTML
<ul class="pagination">
<li class="page-item" [ngClass]="{ disabled: activeImg === 0 }">
<a class="page-link" href="#">Previous</a>
</li>
<li class="page-item" *ngFor="let img of images; let i = index;"
[ngClass]="{ active: i === activeImg }">
<a class="page-link" href="#">{{ i + 1 }}</a>
</li>
<li class="page-item" [ngClass]="{ disabled: activeImg === images.length - 1 }">
<a class="page-link" href="#">Next</a>
</li>
</ul>

In this example, we’re conditionally adding the disabled class to the next and previous examples.

<li [ngClass]="{ disabled: activeImg === 0 }">

For the previous button, we’re checking if the activeImg property is equal to 0. This will mean that the user is on the first image.

<li [ngClass]="{ disabled: activeImg === images.length - 1 }">

For the next button, we’re checking if the activeImg property is equal to the length of the images array minus 1. This will mean they’re viewing the last image.

Alternative values

We don’t have to set the ngClass directive to an object. We can set it to a function that returns an object of classes. You may want to do this if you have multiple classes to conditionally add to an element. This will make your template more comprehensible.

Here’s an example of how we can set the ngClass directive to a function:

<div [ngClass]="someFunction()"></div>

Then, in the component class, we can define the function.

export class AppComponent {
  someFunction() {
    return {
      someClass: true
    }
  }
}

Testing the buttons

Here are the changes we made to the project:

<ul class="pagination">
  <li class="page-item" [ngClass]="{ disabled: activeImg === 0 }">
    <a class="page-link" href="#">Previous</a>
  </li>
  <li class="page-item" *ngFor="let img of images; let i = index;"
    [ngClass]="{ active: i === activeImg }">
    <a class="page-link" href="#">{{ i + 1 }}</a>
  </li>
  <li class="page-item" [ngClass]="{ disabled: activeImg === images.length - 1 }">
    <a class="page-link" href="#">Next</a>
  </li>
</ul>

If you run the example, the previous button will be disabled. Currently, we don’t have a way to change the currently active item. Therefore, try changing the activeItem property to 5 to check if the next button is disabled. You can also freely change the number between 0 and 5 to check if the correct button is active.