Angular Mastery: NgClass & NgStyle

Erxk
Angular In Depth
Published in
5 min readNov 21, 2019

Mastering the Fundamentals of Angular Template Syntax: Part 2

AngularInDepth is moving away from Medium. More recent articles are hosted on the new platform inDepth.dev. Thanks for being part of indepth movement!

Source Code: StackBlitz 🚀

Article Goal: Learn about Angular’s NgClass & NgStyle Directives.

Article Topics (What We’ll Learn):

  • Discuss the Syntax and Semantics of NgClass & NgStyle
  • Explore the Angular Source Code and see how NgClass & NgStyle work under the hood
  • Use custom examples and cheat sheets to develop a better understanding of how to use NgClass and NgStyle

Overview

NgClass & NgStyle are Angular Directives that allow us to conditionally apply one-to-many classes/styles to an element. This provides a convenient way to work with multiple classes or styles at once and apply them conditionally; compared to their alternatives:

Native style and class attributes apply one-to-many classes/styles statically.

Angular’s class and style bindings only allow a single class or style to be conditionally applied at a time.

When determining when to use NgClass and NgStyle over Angular’s class and style bindings or the native attributes; consider:

  • Am I applying classes/styles conditionally (dynamically) or statically?
  • Am I applying one or many classes/styles?
Examples

Combining NgStyle and NgClass Directives with our knowledge of Angular Template Syntax, we can marry conditional styling with Angular’s Property & Event Binding.

Now that we have an understanding of why and when we would use them, let’s break down the two Angular Directives.

NgClass

Syntax

NgClass can receive input via inline declarations, or a property/method from our TypeScript class. This can make the syntax feel more convoluted than it really is. Ultimately, NgClass can take the following as input:

  • A space-delimited String [ngClass]="is-info is-item has-border"
  • An Array of Strings [ngClass]="['is-info', 'is-item', 'has-border'"]
  • An Object [ngClass]="{'is-info': true, 'is-item': true}

All of the above examples are inline and could be replaced with a Typescript property/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, array, or object.

For example: [ngClass]="name === 'erxk' ? 'is-author' : 'is-reader'

Under the Hood

For context, an example:

Example using NgClass
status-button.component.html
status-button.component.ts
status-button.component.css

Key takeaways from our example code:

  • Our button element has the NgClass Directive applied to it
  • Our NgClass input is classStyler from our Typescript Class. classStyler evaluates to a valid object expression.
  • The properties on classStyler match the names of our CSS Classes.
  • NgClass will append classes, not overwrite. Our button will still have class="big-font” applied to it.
  • Updating the CSS classes on our HTML Element in our Typescript Class.

This way of leveraging TypeScript/JavaScript to update our CSS conditionally; starts to feel like utilizing the element.classList.add and element.classList.remove methods in Vanilla JavaScript:

updateButtonClass() {
const button = document.querySelector('button');
button.classList.add('info');
}

This is similar to what NgClass is doing under the hood. Looking at the source code for NgClass, it does all the heavy lifting and then invokes toggleClass().

Snippet below is context for the next snippet, we don’t have to worry about understanding it all.

From the Angular Source Code (Context for next Snippet)

If we look at the implementation of toggleClass(), we can see that ultimately NgClass is simply using Angular’s Renderer2 to addClass() or removeClass() from our nativeElement (The element with NgClass on it).

From the Angular Source-Code

Note, this underlying implementation is the same whether we use NgClass with Typescript properties/methods or write expressions inline in our HTML.

Key Points

  • We can pass a Typescript property/method or write an expression inline to our NgClass Directive
  • NgClass can take a String, Array of Strings, or Object Expression as input.
  • Under the hood, NgClass is adding/removing classes via Renderer2 addClass() and removeClass()
  • NgClass appends, it does not overwrite.

NgStyle

NgClass and NgStyle share a significant amount of functionality and behavior. The key difference is:

  • NgStyle takes a key-value pair object as input.
  • NgStyle applies styles and not classes.
  • NgStyle will overwrite styles defined by the native style attribute.

Syntax

NgStyle takes a key-value pair object, where the key is a CSS style. An optional suffix can be added to the key, making keys such as this viable:

[ngStyle]="{font-size.px: 16}" Instead of [ngStyle]="{font-size: 16px}"

Similar to NgClass, NgStyle can be passed input inline or use a Typescript property/method. [ngStyle]="myObjectExpressionProperty"

Under the Hood

For context, an example:

Example using NgStyle
picture-editor.component.ts
picture-editor.component.html

Key takeaways from our example code:

  • NgStyle is being applied to our image
  • Our NgStyle input is styler from our Typescript class. styler evaluates to a valid object expression.
  • The properties in styler all evaluate to valid CSS styles
  • The input elements are updating values on our styler property via Angular Event Binding.

If we take a look at the Angular source code, we can see that NgStyle uses a similar paradigm to NgClass. — NgStyle is a more straight-forward Directive; as it only accepts one type of input.

From Angular Source Code

When Angular invokes _setStyle() the AngularRenderer2 is used to invoke setStyle() and removeStyle() based on our input. Notice, we are setting the style, not appending. If we defined a style on our element using the native style attribute, it will be overwritten by NgStyle.

Key Takeaways

  • NgStyle can accept a key-value pair as input, where the key is a valid CSS Style
  • NgStyle can be passed input via inline or a Typescript property or method
  • NgStyle under the hood utilizes Angular’s Renderer2 to invoke setStyle() and removeStyle()
  • NgStyle will overwrite existing styles on the element.

Conclusion

Thanks for reading! We’ve reviewed how to leverage the NgClass and NgStyle Angular Directives to achieve conditional styling with multiple classes/styles while utilizing Angular’s Property and Event Binding. We also looked at how NgClass and NgStyle are working under the hood and some example usages.

Series

Resources

☁️ Flotes — Try the demo, no login required. Or sign up for free. Flotes is how I take notes and learn efficiently, even when I’m busy.

Flotes

--

--