Cookies concent notice

This site uses cookies from Google to deliver its services and to analyze traffic.
Learn more
Skip to main content
Say hello to Angular's future home!Check out Angular.devHome
/

Style Precedence

When there are multiple bindings to the same class name or style attribute, Angular uses a set of precedence rules to determine which classes or styles to apply to the element. These rules specify an order for which style and class related bindings have priority. This styling precedence is as follows, from the most specific with the highest priority to least specific with the lowest priority:

  1. Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.

    Binding type Examples
    Property binding
          
          <div [class.foo]="hasFoo">
        
          
          <div [style.color]="color">
        
    Map binding
          
          <div [class]="classExpression">
        
          
          <div [style]="styleExpression">
        
    Static value
          
          <div class="foo">
        
          
          <div style="color: blue">
        
  2. Directive host bindings are less specific because you can use directives in multiple locations, so they have a lower precedence than template bindings.

    Binding type Examples
    Property binding
          
          host: {'[class.foo]': 'hasFoo'}
        
          
          host: {'[style.color]': 'color'}
        
    Map binding
          
          host: {'[class]': 'classExpr'}
        
          
          host: {'[style]': 'styleExpr'}
        
    Static value
          
          host: {'class': 'foo'}
        
          
          host: {'style': 'color: blue'}
        
  3. Component host bindings have the lowest precedence.

    Binding type Examples
    Property binding
          
          host: {'[class.foo]': 'hasFoo'}
        
          
          host: {'[style.color]': 'color'}
        
    Map binding
          
          host: {'[class]': 'classExpression'}
        
          
          host: {'[style]': 'styleExpression'}
        
    Static value
          
          host: {'class': 'foo'}
        
          
          host: {'style': 'color: blue'}
        

Precedence and specificity

In the following example, binding to a specific class, as in [class.special], takes precedence over a generic [class] binding. Similarly, binding to a specific style, as in [style.color], takes precedence over a generic [style] binding.

src/app/app.component.html
      
      <h3>Basic specificity</h3>

<!-- The `class.special` binding overrides any value for the `special` class in `classExpression`.  -->
<div [class.special]="isSpecial" [class]="classExpression">Some text.</div>

<!-- The `style.border` binding overrides any value for the `border` property in `styleExpression`.  -->
<div [style.border]="border" [style]="styleExpression">Some text.</div>
    

Precedence and bindings from different sources

Specificity rules also apply to bindings even when they originate from different sources. An element can have bindings that originate from its own template, from host bindings on matched directives, and from host bindings on matched components.

src/app/app.component.html
      
      <h3>Source specificity</h3>

<!-- The `class.special` template binding overrides any host binding to the `special` class set by `dirWithClassBinding` or `comp-with-host-binding`.-->

<comp-with-host-binding [class.special]="isSpecial" dirWithClassBinding></comp-with-host-binding>


<!-- The `style.color` template binding overrides any host binding to the `color` property set by `dirWithStyleBinding` or `comp-with-host-binding`. -->
<div>
  <comp-with-host-binding [style.color]="color" dirWithStyleBinding></comp-with-host-binding>
</div>

<h3>Dynamic vs static</h3>

<!-- If `[class.special]` equals false, this value overrides the `class="special"` below -->
<div class="special" [class.special]="false">Some text.</div>

<!-- If `styleExpression` has a value for the `border` property, this value overrides the `style="border: dotted darkblue 3px"` below -->
<div style="border: dotted darkblue 3px" [style]="styleExpression">Some text.</div>


<div class="readability">
  <comp-with-host-binding dirWithHostBinding></comp-with-host-binding>
</div>

<app-my-input-with-attribute-decorator type="number"></app-my-input-with-attribute-decorator>
    

Precedence of bindings and static attributes

Bindings take precedence over static attributes because they are dynamic. In the following case, class and [class] have similar specificity, but the [class] binding takes precedence.

src/app/app.component.html
      
      <h3>Dynamic vs static</h3>

<!-- If `[class.special]` equals false, this value overrides the `class="special"` below -->
<div class="special" [class.special]="false">Some text.</div>

<!-- If `styleExpression` has a value for the `border` property, this value overrides the `style="border: dotted darkblue 3px"` below -->
<div style="border: dotted darkblue 3px" [style]="styleExpression">Some text.</div>
    

Delegating to styles with lower precedence

Higher precedence styles can defer to lower precedence styles using undefined values. For example, consider the following template:

src/app/app.component.html
      
      <comp-with-host-binding dirWithHostBinding></comp-with-host-binding>
    

Imagine that the dirWithHostBinding directive and the comp-with-host-binding component both have a [style.width] host binding.

src/app/comp-with-host-binding.component.ts and dirWithHostBinding.directive.ts
      
      @HostBinding('style.width')
width = '200px';
    

If dirWithHostBinding sets its binding to undefined, the width property falls back to the value of the comp-with-host-binding host binding.

dirWithHostBinding directive
      
      @HostBinding('style.width')
width = ''; // undefined
    

If dirWithHostBinding sets its binding to null, Angular removes the width property entirely.

dirWithHostBinding
      
      @HostBinding('style.width')
width = null;
    
Last reviewed on Mon Feb 28 2022