How to Style Components Using Angular ngClass
Sep 11, 2020 • 5 Minute Read
Introduction
In this guide, we will learn about Angular's ngClass directive. You will get a brief idea of the semantics and syntax of ngClass, and we'll also have a look at the Angular source code and observe how ngClass works under the hood.
Overview
You can use the ngClass directive to conditionally apply one-to-many classes or styles to an element, giving you an effective way to operate with multiple classes or styles at once.
You may find other alternatives with some drawbacks.
For example, with Angular's class binding, a only single class can be conditionally applied at a time. Native style and class attributes statically apply one-to-many classes or styles. Whenever you employ NgClass and NgStyle over Angular's class and style bindings or the native attributes, consider the following points:
- Are you applying one or many classes or styles?
- Are you applying classes orstyles in a static manner or dynamically?
<!-- Native Class/Style attributes -->
<input class="is-warning my-button" style="border: none; color: blue">
<!-- Angular class and style Bindings -->
<input [class.is-warning]="booleanProp" [style.border]="borderProp">
<!-- ngClass -->
<input [ngClass]="{'is-warning': booleanProp, 'myButton': true}">
<input [ngClass]="isWarningBtn">
<!-- ngStyle -->
<input [ngStyle]="{'border': borderProp, 'color': colorProp}">
<input [ngStyle]="hasColorBorder">
<!--
booleanProp, borderProp, etc...
would be properties from our
Typescript class
-->
You can combine conditional styling with Angular's property and event binding by using NgStyle and NgClass directives using the Angular template syntax.
NgClass
NgClass can obtain input via inline declarations, or a property or method from TypeScript class. You may think that the syntax is more complex than it really is. Ultimately, NgClass can take the following as input:
• Space delimited string
[ngClass]="is-info-element is-item has-no-border"
• Array of Strings
[ngClass]="['is-info-element', 'is-item', 'has-no-border'"]
• Object
[ngClass]="{'is-info-element': true, 'is-item': true}
All previous examples are inline and you can replace these with a Typescript property or method as long as the expression returns valid input.
export class MyComponentClass {
myStringProperty = "is-info is-item has-border";
myArrayProperty = ['is-info', 'is-item', 'has-border'];
myObjectProperty = {'is-info': true, 'is-item': true};
}
• [ngClass]="myStringProperty"
• [ngClass]="myArrayProperty"
• [ngClass]="myObjectProperty"
Ternary statements are valid input as long as they return a valid string, object, or array.
For example:
[ngClass]="name === 'erxk' ? 'is-author' : 'is-reader'
Under the Hood
Below is an example of how to use NgClass.
<button type="button" class="big-font" [ngClass]="klassStyler">Submit</button>
<div>
<label for="one">Terms of Service</label>
<input #one id="one" type="checkbox" (change)="updateTos(one.checked)">
<label for="two">Send Usage Information</label>
<input #two id="two" type="checkbox" (change)="updateUsage(two.checked)">
</div>
Below is the component javascript:
export class StatusButtonComponent implements OnInit {
tosSign = false;
sndUsage = false;
// [ngClass]="klassStyler"
klassStyler = {
warning: false,
info: false,
error: !this.tosSign,
success: this.tosSign,
}
// ...
updateStyle() {
this.klassStyler.error = !this.tosSign;
this.klassStyler.success = this.tosSign && this.sndUsage;
this.klassStyler.warning = this.tosSign && !this.sndUsage;
}
}
Below is the CSS:
.warning {
background: hsl(48, 100%, 67%);
border: 5px solid hsl(58, 100%, 67%);
color: black;
}
.error {
background: hsl(348, 100%, 61%);
border: 5px solid hsl(248, 100%, 61%);
color: white;
}
.success {
Below are some of the major takeaways from the sample code:
• Your button element has the NgClass directive applied to it .
• Your NgClass input is klassStyler from your Typescript class. klassStyler examines a valid object expression.
• The properties on klassStyler match the names of the CSS classes in your code.
• NgClass will append classes, not overwrite. Your button will still have class=" big-font" applied to it.
• You're updating the CSS classes on HTML Element in your Typescript class.
Conclusion
We have looked at using the ngClass Angular directive to fulfill conditional styling with multiple classes. We used Angular's property and event binding for this use case.