This commit edits the copy of the attribute binding documentation, moves the colspan section that is primarily about property binding to the property binding document, and adds a docregion to the attribute-binding example to help clarify a point in the document. Part of the copy edit reformats the style precedence list in tabular format so that it is easier to read and understand. PR Close #38860
		
			
				
	
	
		
			134 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # 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 priorty:
 | |
| 
 | |
| 1. Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
 | |
|   <table width="100%">
 | |
|     <col width="40%"></col>
 | |
|     <col width="60%"></col>
 | |
|     <thead>
 | |
|       <tr>
 | |
|         <th>Binding type</th>
 | |
|         <th>Example</th>
 | |
|       </tr>
 | |
|     </thead>
 | |
|     <tbody>
 | |
|       <tr>
 | |
|         <td>Property binding</td>
 | |
|         <td><code><div [class.foo]="hasFoo"></code><br><code><div [style.color]="color"></code></td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>Map binding</td>
 | |
|         <td><code><div [class]="classExpression"></code><br><code><div [style]="styleExpression"></code></td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>Static value</td>
 | |
|         <td><code><div class="foo"></code><br><code><div style="color: blue"></code></td>
 | |
|       </tr>
 | |
|     </tbody>
 | |
|   </table>
 | |
| 1. Directive host bindings are less specific because you can use directives in multiple locations, so they have a lower precedence than template bindings.
 | |
|   <table width="100%">
 | |
|     <col width="40%"></col>
 | |
|     <col width="60%"></col>
 | |
|     <thead>
 | |
|       <tr>
 | |
|         <th>Binding type</th>
 | |
|         <th>Example</th>
 | |
|       </tr>
 | |
|     </thead>
 | |
|     <tbody>
 | |
|       <tr>
 | |
|         <td>Property binding</td>
 | |
|         <td><code>host: {'[class.foo]': 'hasFoo'}</code><br><code>host: {'[style.color]': 'color'}</code></td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>Map binding</td>
 | |
|         <td><code>host: {'[class]': 'classExpr'}</code><br><code>host: {'[style]': 'styleExpr'}</code></td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>Static value</td>
 | |
|         <td><code>host: {'class': 'foo'}</code><br><code>host: {'style': 'color: blue'}</code></td>
 | |
|       </tr>
 | |
|     </tbody>
 | |
|   </table>
 | |
| 1. Component host bindings have the lowest precedence.
 | |
|     <table width="100%">
 | |
|     <col width="40%"></col>
 | |
|     <col width="60%"></col>
 | |
|     <thead>
 | |
|       <tr>
 | |
|         <th>Binding type</th>
 | |
|         <th>Example</th>
 | |
|       </tr>
 | |
|     </thead>
 | |
|     <tbody>
 | |
|       <tr>
 | |
|         <td>Property binding</td>
 | |
|         <td><code>host: {'[class.foo]': 'hasFoo'}</code><br><code>host: {'[style.color]': 'color'}</code></td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>Map binding</td>
 | |
|         <td><code>host: {'[class]': 'classExpression'}</code><br><code>host: {'[style]': 'styleExpression'}</code></td>
 | |
|       </tr>
 | |
|       <tr>
 | |
|         <td>Static value</td>
 | |
|         <td><code>host: {'class': 'foo'}</code><br><code>host: {'style': 'color: blue'}</code></td>
 | |
|       </tr>
 | |
|     </tbody>
 | |
|   </table>
 | |
| 
 | |
| ## 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.
 | |
| 
 | |
| <code-example path="attribute-binding/src/app/app.component.html" region="basic-specificity" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| ## 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.
 | |
| 
 | |
| <code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| ## 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.
 | |
| 
 | |
| <code-example path="attribute-binding/src/app/app.component.html" region="dynamic-priority" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| {@a styling-delegation}
 | |
| 
 | |
| ## Delegating to styles with lower precedence
 | |
| 
 | |
| Higher precedence styles can defer to lower precedence styles using `undefined` values.
 | |
| For example, consider the following template:
 | |
| 
 | |
| <code-example path="attribute-binding/src/app/app.component.html" region="style-delegation" header="src/app/app.component.html"></code-example>
 | |
| 
 | |
| Imagine that the `dirWithHostBinding` directive and the `comp-with-host-binding` component both have a `[style.width]` host binding.
 | |
| 
 | |
| <code-example path="attribute-binding/src/app/comp-with-host-binding.component.ts" region="hostbinding" header="src/app/comp-with-host-binding.component.ts and dirWithHostBinding.directive.ts"></code-example>
 | |
| 
 | |
| If `dirWithHostBinding` sets its binding to `undefined`, the `width` property falls back to the value of the `comp-with-host-binding` host binding.
 | |
| 
 | |
| <code-example header="dirWithHostBinding directive">
 | |
| @HostBinding('style.width')
 | |
| width = ''; // undefined
 | |
| </code-example>
 | |
| 
 | |
| <div class="alert is-helpful">
 | |
| 
 | |
|   If `dirWithHostBinding` sets its binding to `null`, Angular removes the `width` property entirely.
 | |
| 
 | |
|   <code-example header="dirWithHostBinding">
 | |
|   @HostBinding('style.width')
 | |
|   width = null;
 | |
|   </code-example>
 | |
| 
 | |
| </div>
 |