Write Angular like a pro. Angular Icon

Follow the ultimate Angular roadmap.

Using ngStyle in Angular for dynamic styling

In this tutorial you’ll learn how to dynamically apply CSS styles in Angular via ngStyle, but we’ll also cover the style property binding for full completeness.

In traditional JavaScript, we may create a click event and add or remove a style based on the condition of a property. Styles applied with the style attribute also take precedence over any styles bound to an element using class, so it’s useful to use inline styles to dynamically override default styles.

Using ngStyle allows us to apply inline styles to any element, or component, easily. There are lots of recipes available on how to use ngStyle, so we’ll cover all the latest practices and talk about when and why to use each method.

Unlike other libraries or frameworks, such as React, there is no special syntax involved when declaring the actual CSS property and value, which certainly makes composing dynamic inline styles with Angular far easier.

💎 Important: An attribute is the name of the HTML key you wish to create, for example <div style="...">. A property is the JavaScript equivalent created behind-the-scenes when the browser bootstraps our application. So when we use element.style we are talking to a property, not an attribute.

So let’s dive into our first example using an inline style attribute, and then we’ll move on to ngStyle.

Style Attribute Binding

In Angular you can easily apply inline styles via a static style attribute, as you would in normal HTML:

<div style="background: #f4f4f4; border: 1px solid #dcdcdc;">
  ...
</div>

This is fine for one-off use cases, though you’d be likely better off using a class to apply a style, but the values remain static. When dealing with Angular, it’s likely you’ll need to apply a dynamic inline style that changes based on the state of your data structure.

That’s where property binding to the style attribute comes in.

Style Property Binding

Inline styles can be applied using square brackets and referencing the style attribute. By using [style] we reference the attribute, but because we are applying a binding using square brackets - it becomes a property binding.

Important: Because we are binding to a property we need to also pass the type of data, which means a string when dealing with inline styles, so a single quote '...' is needed at the beginning and end of the style string, otherwise we’ll see an error.

With this in mind, let’s create an inline style in Angular using a style property binding and pass in a string of styles, either a single value or multiple values:

<div [style]=" 'background: #f4f4f4; border: 1px solid #dcdcdc;' ">
  ...
</div>

To create these style strings dynamically and conditionally, we would then introduce perhaps the ternary operator to check against a property and change the style based on the value:

<div [style]="item.promo ? 'background: #f4f4f4; border: 1px solid #dcdcdc;' : ''">
  ...
</div>

The above checks the existence of a item.promo property in the template, and if true will render the inline styles for us, otherwise will not.

Style bindings in Angular also offer a shorthand syntax that allow us to streamline how we set specific values, which is useful for smaller tasks. Here’s how we could rewrite the above example using the style binding that allows a CSS property to be set at the same time - making it easier to set a value:

<div 
  [style.background]="item.promo ? '#f4f4f4' : '#fff'"
  [style.border]="item.promo ? '1px solid #dcdcdc' : '1px solid #fff'">
  ...
</div>

As you can see from the above, this practice of setting a style and CSS property at the same time means we need to supply a fallback value for when the condition evaluates false - which is potentially not ideal and can involve writing a lot of unnecessary code.

Managing inline styles in the template is acceptable for smaller use-cases, but can easily get out of hand and overly complex. To mitigate this, I’d recommend using a method to return any composed styles for all your components:

@Component({
  template: `
    <div [style]="getPromoStyles()">
      ...
    </div>
  `
})
export class MenuItemComponent {
  @Input() item: Item;

  constructor() {}

  getPromoStyles() {
    if (this.item.promo) {
      return 'background: #f4f4f4; border: 1px solid #dcdcdc';
    }
  }
}

This is a lot cleaner and your component can be very easily unit-tested to ensure it returns the correct style string based on the item.promo property. What’s really nice is you don’t need to supply an empty string fallback as well, the style binding is clever enough to just ignore any values not returned to it.

It’s advisable to use a method to return inline styles to a component’s template instead of using a get due to the impacts on Change Detection.

Moving onto deeper syntax, we can also use an optional property for any units such as px, em and friends:

<p 
  [style.font-size.px]="promo ? 20 : 18"
  [style.font-size.em]="promo ? 5 : 3"
  [style.font-size.rem]="promo ? 5 : 3"
  [style.font-size.%]="promo ? 120 : 100">
  ...
</p>

This technique would be useful for referencing strict number values, perhaps returned from an API request so you don’t need to parse it from a string to number - the style binding is cleverly designed to handle lots of use cases and syntax.

So that’s how to set dynamic styles using the style property binding, to pass individual styles or multiple styles and optional units.

One final thing with the style binding is the ability to pass an object configuration. Let’s change our previous example to using an object instead of a string:

@Component({
  template: `
    <div [style]="getPromoStyles()">
      ...
    </div>
  `
})
export class MenuItemComponent {
  @Input() item: Item;

  constructor() {}

  getPromoStyles() {
    if (this.item.promo) {
      return {
        background: '#f4f4f4',
        border: '1px solid #dcdcdc'
      };
    }
  }
}

Of course, that means you can also use an object in the template and not use a component method if you’d prefer.

You have two options, pass an entire object and toggle the values (not recommended) or pass an object dynamically using a ternary or conditional:

<!-- ❌ Not recommended -->
<div 
  [style]="{
    background: item.promo ? '#f4f4f4' : '#fff',
    border:  item.promo ? '1px solid #dcdcdc': '1px solid #fff'
  }">
  ...
</div>

I wouldn’t opt for the above technique, as again it involves creating duplicate code and fallbacks - this is the best option for you by passing an object only if needed, and passing null to render nothing if the condition results false:

<!-- ✅ Recommended -->
<div 
  [style]="item.promo ? {
    background: '#f4f4f4',
    border: '1px solid #dcdcdc'
  }: null">
  ...
</div>

You can also use the shorthand syntax for setting units with this syntax as well, but using single quotes '...' is required around the object property name:

<div 
  [style]="item.promo ? {
    background: '#f4f4f4',
    border: '1px solid #dcdcdc',
    'font-size.px': 20
  }: null">
  ...
</div>

So what about ngStyle? What’s interesting is you do not need it nowadays…

Yes, you read that correctly - you don’t need it anymore.

Anything ngStyle can do, the style binding can do better.

Nevertheless, let’s cover it for completeness.

NgStyle Directive

Taking the examples we’ve already explored, we can demonstrate how to use ngStyle in a template.

First, if you’re using standalone components you’ll need to import the NgStyle directive and add it to your imports: [] array on the @Component decorator:

@Component({
  standalone: true,
  imports: [NgStyle],
  template: `
    <div [ngStyle]="getPromoStyles()">
      ...
    </div>
  `
})
export class MenuItemComponent {
  @Input() item: Item;

  constructor() {}

  getPromoStyles() {
    if (this.item.promo) {
      return {
        background: '#f4f4f4',
        border: '1px solid #dcdcdc'
      };
    }
  }
}

Of course, this means you can use ngStyle in the template in the same way:

<div 
  [ngStyle]="item.promo ? {
    background: '#f4f4f4',
    border: '1px solid #dcdcdc',
    'font-size.px': 20
  }: null">
  ...
</div>

That is all that the ngStyle directive has to offer, object literal syntax to pass a dynamic style. It cannot support strings or single values, making it less powerful than the style binding.

With this in mind, we’ve covered how to add dynamic styles to an Angular template, what’s more is you can also add these styles to components and they are not limited to just DOM elements such as <div>.

🚀 Learn more techniques, best practices and real-world expert knowledge, I’d highly recommend checking out my Angular courses - they will guide you through your journey to mastering Angular to the fullest!

Writing lots of inline styles can be hard to manage, but by moving them into a component method (instead of the template) and dynamically assigning them, we can create slick components with minimal effort. Most of the time you’ll only want to use an inline style to override an existing property, or provide dynamic CSS that cannot be applied via a class property binding.

Happy styling!

Learn Angular the right way.

The most complete guide to learning Angular ever built.
Trusted by 82,951 students.

Todd Motto

with Todd Motto

Google Developer Expert icon Google Developer Expert

Related blogs 🚀

Free eBooks:

Angular Directives In-Depth eBook Cover

JavaScript Array Methods eBook Cover

NestJS Build a RESTful CRUD API eBook Cover