Angular 2+ Classes with NgClass and NgStyle

Ogundipe Samuel Ayo

In this blog post, we'll be learning about NgClass and NgStyle in Angular v2.x. Throughout this blog post, Angular means Angular version greater than 2.x unless stated otherwise.

For AngularJS v1.x styling, see our other article: The Many Ways To Use ngClass.

Extra Reading: The Next Version of Angular is Angular v4

Creating dynamic styles in web applications can be a real pain. Luckily with Angular, we have multiple ways to create dynamic stylings to our application.

What We'll Build

However, let us take a quick view of some of what we aim to achieve with ngStyle and ngClass.

Styling Without Angular

First of all, let us look at how we change the class and style of an element in pure JavaScript.

And for that, we would need to create a small div like the one below:

<div id="my_id">This is a div written in black.</div>

To change the style of the above div and class in pure javascript, we would need to do this:

var divToChange = document.getElemetById('my_id');

//to change the class we would do.
divToChange.className = "newclass";

//if we want to add multiple classes, we could just do
divToChange.className = "newclass secondclass thirldclass";

//if we want to add a class name without removing the class present before, we do:
divToChange.className = divToChange.className.concat(" addedwit");

//to change the background color of such an element, we would also have to do.
divToChange.style.background-color = "red";

//to change the color of such an element would need
divToChange.style.color = "white";

//Which we would agree is a bit more stressful than what angular ships with us.

If we look at the above code, we can notice that we had to first get element by id, then assessing its class name, before we start changing the values, them using compact, e.t.c.

We would also notice that in some cases, we would need to reach property of property e.g divToChange.style.background-color before assigning a value to it.

We would both agree that this can be a very tedious method of dealing with just styles and class names.

Angular makes many parts of development easier including styling. Now, let's see how these are taken care of in Angular.

First of all, this tutorial believes that you know:

1.) What Angular is? 2.) How to use the angular-cli

Getting Started With The Angular CLI

In case you do not have the angular cli installed, you can run the following command.

sudo npm install -g angular-cli

Extra Reading on Angular Cli Use the Angular CLI For Faster Angular 2 Projects

Once the angular cli has been installed, let us create a new project. so we run:

ng new angular-class-style

The above command creates a new project called angular-class-style.

Once done, we change directory into our angular project and run ng serve.

# change directory into our app directory
cd angular-class-style

# serve the application
ng serve

We should see this:

Getting Started With Angular Style Directives

Now let's get started with Style:

In Angular, there are two methods of passing styles into elements.

Using the [style.property] Binding.

In the first instance, we can bind something like [style.color]='red'.

This kind of styling would make the color of the element red. Similarly, we can also alter any style element that way by passing a string as the value. However, to be more dynamic, we can pass a dynamic style using a variable that exists in the component.

Let's take this for example. Open up your src/app/app.component.ts file, we would replace it with the following content.

//import the angular component from angular core
import { Component } from '@angular/core';
@Component({
    // define the selector for your app
    selector: 'app-root',
    //pass in the template url
    templateUrl: './app.component.html',
    //pass in the css of the component
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'app works!';

    //set a property that holds a random color for our style.
    randomcolor = this.getRandomColor();

    //function to get random colors
    public getRandomColor() {
        var letters = '0123456789ABCDEF'.split('');
        var color = '#';
        for (var i = 0; i < 6; i++){
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }

    //function to set a new random color
    setColor() {
        this.randomcolor = this.getRandomColor();
    }
}

What we have done is very simple. We have set a property called randomcolor as a variable that holds the background color, and we have immediately set it to the value of our random generator function.

Next, we defined a random generator function, that randomly generates colours by splitting letters and making sure it returns a color format like #ffffff

Then we defined a setcolor function that sets the variable to another randomly generated color.

After Doing this, we should update our src/app/app.component.html to the following structure:

<h1>
{{title}}
</h1>
<!---style binding for colors -->
<h2>Style Binding using 'style.color' directive</h2>
<!--call the random color property to set the color of this div -->
<div [style.color]="randomcolor"> I would be styled with different colors dynamically </div>
<!--attach a click function to this button to set the color dynamically -->
<button (click)="setColor()"> Set my color </button>

Here, we have defined our HTML structure for the component.

We have four main elements on the piece of code.

The first one which prints out the value of value, The second, which is a header element, defining what we are doing.

The third is the actual div in which we have attached a style binding to, While the fourth element, is the button, which has a click function that calls the setColor function from our component.

If we close the page and compile, we should see something like this:

Using the [ngStyle] Binding

Another Method using style is to use the [ngStyle] property directly, which allows us to pass objects into it. for example [ngStyle]="{'color':'white', 'font-size':'17px'}" which also allows us to set those styles dynamically.

Let's take a look at the following example, Update your src/app/app.component.ts to this:

//import the angular component from angular core
import { Component } from '@angular/core';
@Component({
    // define the selector for your app
    selector: 'app-root',
    //pass in the template url
    templateUrl: './app.component.html',
    //pass in the css of the component
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'app works!';
    //set a property that holds a random color for our style.
    randomcolor=this.getRandomColor();
    //declare the fontsize and background color properties
    public font_size="12px";
    public background_color="grey ";
    //function to get random colors
    public getRandomColor(){
        var letters = '0123456789ABCDEF'.split('');
        var color = '#';
        for (var i = 0; i < 6; i++){
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }
    //function to set a new random color
    setColor(){
        this.randomcolor=this.getRandomColor();
    }
}

Now let's look at what has changed:

We added two properties into our app.component.ts file named font_size and background_color. These two properties are responsible for changing the style dynamically.

Currently, they are just properties holding default values, and nothing special happens with them.

Now lets also update our src/app/app.component.html to this:

<h1>
{{title}}
</h1>
<!---style binding for colors -->
<h2>Style Binding using 'style.color' directive</h2>
<!--call the random color property to set the color of this div -->
<div [style.color]="randomcolor"> I would be styled with different colors dynamically </div>
<!--attach a click function to this button to set the color dynamically -->
<button (click)="setColor()"> Set my color </button>
<!---style bindning for ngStyle -->
<h2>Style Binding using 'ngStyle' directive</h2>
<!--call the style object to style class -->
<div [ngStyle]="{
'color': getRandomColor(),
'font-size': font_size,
'background-color': background_color
}"> I would be styled with different colors dynamically </div>
<!--attach a click function to this button to set the style dynamically -->
<input type="text" [(ngModel)]="background_color" placeholder="background_color">
<input type="text" [(ngModel)]="font_size" placeholder="font_size">

Let us take a brief look at what we added to the Html structure:

We added some extra Html elements to the page. A new header tag, to specify what we are doing, a new div with our ngStyle binding, with an object passed to it.

One thing you might notice is that the object passed to it looks a lot like a CSS class.

In fact, it is almost a CSS class, except that we pass in variables to it and also functions.

Can you notice our getRandomColor function is being called here again to set the color. Not that it is compulsory, but rather than hard code the color, we decided to give it some spice.

We now have two new elements which are input buttons, with ngModel bindings to the variable declared in the style, for reactivity purposes.

After adding this files and compiling, your page should look like this:

Now let's look at what has changed:

Although we set some default parameters, let's move into our app.component.html file to see what's there.

We added a new div which is bonded using ng style, and we then passed an object to it. The object consists of 3 properties which are style properties namely: color, background-color and font-size.

The color attribute is set to a random color from our random color function, while both the background-color and font-size are preset.

Just after then, we find two inputs with ngModel binding to the font-size and color, which makes those fields reactive.

So if i were to type 18px to the font-size box, i get text of about 18px, vis-a-vis if i am to type in orange to the background-color box, i get a background color of orange.

Getting Started With Angular Class Directives

Now let us move into using the class directives.

Using the [className] directive

Let us start by using the [className] directive:

Let us open up a file called src/app/app.component.css and add some css classes into it.

.style1 {
    font-family: verdana;
    font-size: 20px;
}

.style2 {
    color: red;
    text-align: center;
}

What we have done here is to declare two classes, namely: style1 and style2 with different CSS properties. However, let's go on and see what we would use them for later on.

Now let us open up our src/app/app.component.html and replace it with the following content:

<h1>
    {{title}}
</h1>

<!---style binding for colors -->
<h2>Style Binding using 'style.color' directive</h2>

<!--call the random color property to set the color of this div -->
<div [style.color]="randomcolor"> I would be styled with different colors dynamically </div>

<!--attach a click function to this button to set the color dynamically -->
<button (click)="setColor()"> Set my color </button>

<!---style binding for ngStyle -->
<h2>Style Binding using 'ngStyle' directive</h2>

<!--call the style object to style class -->
<div [ngStyle]="{
    'color': getRandomColor(),
    'font-size': font_size,
    'background-color': background_color
}"> I would be styled with different colors dynamically </div>

<!--attach a click function to this button to set the style dynamically -->
<input type="text" [(ngModel)]="background_color" placeholder="background_color">
<input type="text" [(ngModel)]="font_size" placeholder="font_size">

<!---class binding for ClassName -->
<h2>Class Binding using 'className' directive</h2>

<!--call the ngclass object to add a class name to it. -->
<div [className]="'style1'"> I would be classed using class name

If you notice, the font for the last text had changed.

What have we done here?

We have added some classes to our CSS files, and we have used the className directive to specify the class we want in our HTML.

This is how what we have would look at now:

Although this might not make sense as to why you would do this, as it is the same as doing class="style1" directly. But let us take a look at this example to see when using class name can be useful.

Open up your src/app/appcomponent.ts file and replace it with the following code:

//import the angular component from angular core
import { Component } from '@angular/core';
@Component({
    // define the selector for your app
    selector: 'app-root',
    //pass in the template url
    templateUrl: './app.component.html',
    //pass in the css of the component
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'app works!';
    //set a property that holds a random color for our style.   
    randomcolor=this.getRandomColor();

    //declare the fontsize and background color properties
    public font_size="12px";
    public background_color="grey ";

    //declare a variable to hold class name:
    public my_Class = 'style1';

    //function to get random colors
    public getRandomColor(){
        var letters = '0123456789ABCDEF'.split('');
        var color = '#';
        for (var i = 0; i < 6; i++){
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }

    //function to set a new random color
    setColor(){
        this.randomcolor=this.getRandomColor();
    }

    //function to change the class from style1 to style 2 when clicked
    toggle_class(){
        if(this.my_Class=="style1"){
            this.my_Class='style2';
        }else{
            this.my_Class='style1';
        }
    }
}

If you look at the above code, we have only added one extra property, which is public my_Class='style1' which is just a holder for the class we are calling, and one extra method, for changing the class value of the my_class property, which basically just toggles the classes.

Now let's add the following Html code:

<h1>
{{title}}
</h1>

<!---style binding for colors -->
<h2>Style Binding using 'style.color' directive</h2>

<!--call the random color property to set the color of this div -->
<div [style.color]="randomcolor"> I would be styled with different colors dynamically </div>

<!--attach a click function to this button to set the color dynamically -->
<button (click)="setColor()"> Set my color </button>

<!---style binding for ngStyle -->
<h2>Style Binding using 'ngStyle' directive</h2>

<!--call the style object to style class -->
<div [ngStyle]="{
    'color': getRandomColor(),
    'font-size': font_size,
    'background-color': background_color
}"> I would be styled with different colors dynamically </div>

<!--attach a click function to this button to set the style dynamically -->
<input type="text" [(ngModel)]="background_color" placeholder="background_color">
<input type="text" [(ngModel)]="font_size" placeholder="font_size">

<!---class binding for ClassName -->
<h2>Class Binding using 'className' directive</h2>

<!--call the ngclass object to add a class name to it. -->
<div [className]="'style1'"> I would be classed using classname

<!---class binding for ClassName -->
<h2>Class Binding using 'className' directive and variable</h2>

<!--call the ngclass object to add a class name to it. -->
<div [className]="my_Class"> I would be classed using classname</div>

<!--button to change the class -->
<button (click)="toggle_class()">Toggle_class</button>

If we click the button, we notice the classes are being swapped.

So what have we done here?

We have used the class name attribute to specify our class, which is being toggled using the button provided.

Using the ngClass Binding

Another class binding we can do is using the ngClass binding.

We can use the ngclass to load classes dynamically too.

just like the class name, we can load the classes either by string, by an array or even by objects.

The usage of object is the bigger advantage ngClass has over className

e.g:

<div [ngClass]="['style1', 'style2']">array of classes <div [ngClass]="'style1 style2'">string of classes <div [ngClass]="{'style1': true, 'style2': true}">object of classes</div>

It should be noted that both the three methods in the example above, would give the same result.

But lets take a look at the third option that uses an object.

We are allowed to pass an object to the ngClass directive. The object contains a key of all the styles we want to load and a boolean value of either true or false.

Let's Take a look at the example below:

Open up your src/app/appcomponent.ts and replace it with this content:

//import the angular component from angular core
import { Component } from '@angular/core';
@Component({
    // define the selector for your app
    selector: 'app-root',
    //pass in the template url
    templateUrl: './app.component.html',
    //pass in the css of the component
    styleUrls: ['./app.component.css']
})
export class AppComponent {
    title = 'app works!';
    //set a property that holds a random color for our style.
    randomcolor=this.getRandomColor();
    //declare the fontsize and background color properties
    public font_size="12px";
    public background_color="grey ";
    //declare a variable to hold class name:
    public my_Class = 'style1';
    //variable to hold boolean value to style1
    isClass1Visible: false;
    //variable to hold boolean value to style2
    isClass2Visible: false;
    //function to get random colors
    public getRandomColor(){
        var letters = '0123456789ABCDEF'.split('');
        var color = '#';
        for (var i = 0; i < 6; i++){
            color += letters[Math.floor(Math.random() * 16)];
        }
        return color;
    }
    //function to set a new random color
    setColor(){
        this.randomcolor=this.getRandomColor()
    }
    //function to change the class from style1 to style 2 when clicked
    toggle_class(){
        if(this.my_Class=="style1"){
            this.my_Class='style2';
        }else{
            this.my_Class='style1';
        }
    }
}

In the above code, we would notice the addition of two properties and two variables which are: isClass1Visible and isClass2Visible.

The two properties hold the default boolean value for both style1 and style2.

Now let's update our HTML structure to this:

<h1>
{{title}}
</h1>
<!---style binding for colors -->
<h2>Style Binding using 'style.color' directive</h2>

<!--call the random color property to set the color of this div -->
<div [style.color]="randomcolor"> I would be styled with different colors dynamically </div>

<!--attach a click function to this button to set the color dynamically -->
<button (click)="setColor()"> Set my color </button>

<!---style binding for ngStyle -->
<h2>Style Binding using 'ngStyle' directive</h2>

<!--call the style object to style class -->
<div [ngStyle]="{
    'color': getRandomColor(),
    'font-size': font_size,
    'background-color': background_color
}"> I would be styled with different colors dynamically </div>

<!--attach a click function to this button to set the style dynamically -->
<input type="text" [(ngModel)]="background_color" placeholder="background_color">
<input type="text" [(ngModel)]="font_size" placeholder="font_size">

<!---class binding for ClassName -->
<h2>Class Binding using 'className' directive</h2>

<!--call the ngclass object to add a class name to it. -->
<div [className]="'style1'"> I would be classed using classname</div>

<!---class binding for ClassName -->
<h2>Class Binding using 'className' directive and variable</h2>

<!--call the ngclass object to add a class name to it. -->
<div [className]="my_Class"> I would be classed using classname</div>
<button (click)="toggle_class()">Toggle_class</button>

<!-- class binding using ngclass -->
<h2> Class Binding using 'ngClass' directive with objects and variables</h2>

<!--call the classes in the objects and their value -->
<div [ngClass]="{'style1': isClass1Visible, 'style2': isClass2Visible}">object of classes</div>

<!--button to togggle style1 -->
<button (click)="isClass1Visible = !isClass1Visible;">Toggle style 1</button>

<!-- button to toggle style2 -->
<button (click)="isClass2Visible = !isClass2Visible;">Toggle style 2</button>

What have we added? we have added a div with the ngclass binding, and we have added our object of classes to them with a boolean value of false.

We also have two values that change the boolean value from false to true.

So as we click, the classes change themselves.

Now this is what our page should look like:

I hope you now understand how easy it is to play around with ngStyle and ngClass to make your application more reactive.

With this approach, you wouldn't need jQuery to do things like toggle and tabs. And it is a much cleaner approach.

Ogundipe Samuel Ayo

7 posts

Software Enginner / Technical Writer. Conversant with Php (Codeigniter and Laravel), Python (Flask and Django), C# (WPF), Javacript (Vue, Angular, React-native, Node.js (Adonis.js, Express) ). Can Use the Mean Stack, But never used it For anything Serious