docs(ivy): add docs for styling priority order (#35066)
PR Close #35066
This commit is contained in:
parent
4e9d62ff81
commit
7526ef77b7
|
@ -5,7 +5,8 @@
|
||||||
"packageManager": "yarn",
|
"packageManager": "yarn",
|
||||||
"warnings": {
|
"warnings": {
|
||||||
"typescriptMismatch": false
|
"typescriptMismatch": false
|
||||||
}
|
},
|
||||||
|
"analytics": false
|
||||||
},
|
},
|
||||||
"newProjectRoot": "projects",
|
"newProjectRoot": "projects",
|
||||||
"projects": {
|
"projects": {
|
||||||
|
|
|
@ -25,23 +25,12 @@ describe('Attribute binding example', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a blue div with a red border', function () {
|
it('should display a blue div with a red border', function () {
|
||||||
expect(element.all(by.css('div')).get(4).getCssValue('border')).toEqual('2px solid rgb(212, 30, 46)');
|
expect(element.all(by.css('div')).get(1).getCssValue('border')).toEqual('2px solid rgb(212, 30, 46)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should display a div with replaced classes', function () {
|
it('should display a div with many classes', function () {
|
||||||
expect(element.all(by.css('div')).get(5).getAttribute('class')).toEqual('new-class');
|
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('special');
|
||||||
});
|
expect(element.all(by.css('div')).get(1).getAttribute('class')).toContain('clearance');
|
||||||
|
|
||||||
it('should display four buttons', function() {
|
|
||||||
let redButton = element.all(by.css('button')).get(1);
|
|
||||||
let saveButton = element.all(by.css('button')).get(2);
|
|
||||||
let bigButton = element.all(by.css('button')).get(3);
|
|
||||||
let smallButton = element.all(by.css('button')).get(4);
|
|
||||||
|
|
||||||
expect(redButton.getCssValue('color')).toEqual('rgba(255, 0, 0, 1)');
|
|
||||||
expect(saveButton.getCssValue('background-color')).toEqual('rgba(0, 255, 255, 1)');
|
|
||||||
expect(bigButton.getText()).toBe('Big');
|
|
||||||
expect(smallButton.getText()).toBe('Small');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,43 +27,41 @@
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
|
|
||||||
<h2>Class binding</h2>
|
<h2>Styling precedence</h2>
|
||||||
|
|
||||||
<!-- #docregion add-class -->
|
<!-- #docregion basic-specificity -->
|
||||||
<h3>Bind to a specific class</h3>
|
<h3>Basic specificity</h3>
|
||||||
|
|
||||||
<div class="item clearance" [class.special]="isSpecial">This class binding is special.</div>
|
<!-- The `class.special` binding will override any value for the `special` class in `classExpr`. -->
|
||||||
<!-- #enddocregion add-class -->
|
<div [class.special]="isSpecial" [class]="classExpr">Some text.</div>
|
||||||
|
|
||||||
<!-- #docregion bind-syntax -->
|
<!-- The `style.color` binding will override any value for the `color` property in `styleExpr`. -->
|
||||||
|
<div [style.color]="color" [style]="styleExpr">Some text.</div>
|
||||||
|
<!-- #enddocregion basic-specificity -->
|
||||||
|
|
||||||
<h3>Using the bind- syntax:</h3>
|
<!-- #docregion source-specificity -->
|
||||||
|
<h3>Source specificity</h3>
|
||||||
|
|
||||||
<div bind-class.special="isSpecial">This class binding is special too.</div>
|
<!-- The `class.special` template binding will override any host binding to the `special` class set by `dirWithClassBinding` or `comp-with-host-binding`.-->
|
||||||
<!-- #enddocregion bind-syntax -->
|
<comp-with-host-binding [class.special]="isSpecial" dirWithClassBinding>Some text.</comp-with-host-binding>
|
||||||
|
|
||||||
<!-- #docregion direct-class-binding -->
|
<!-- The `style.color` template binding will override any host binding to the `color` property set by `dirWithStyleBinding` or `comp-with-host-binding`. -->
|
||||||
<h3>Bind to multiple classes</h3>
|
<comp-with-host-binding [style.color]="color" dirWithStyleBinding>Some text.</comp-with-host-binding>
|
||||||
|
<!-- #enddocregion source-specificity -->
|
||||||
|
|
||||||
<div [class]="someClasses">Add multiple classes</div>
|
<!-- #docregion dynamic-priority -->
|
||||||
<!-- #enddocregion direct-class-binding -->
|
<h3>Dynamic vs static</h3>
|
||||||
|
|
||||||
<hr />
|
<!-- If `classExpr` has a value for the `special` class, this value will override the `class="special"` below -->
|
||||||
|
<div class="special" [class]="classExpr">Some text.</div>
|
||||||
|
|
||||||
<h2>Style binding</h2>
|
<!-- If `styleExpr` has a value for the `color` property, this value will override the `style="color: blue"` below -->
|
||||||
|
<div style="color: blue" [style]="styleExpr">Some text.</div>
|
||||||
|
|
||||||
<!-- #docregion style-binding-->
|
<!-- #enddocregion dynamic-priority -->
|
||||||
<button [style.color]="isSpecial ? 'red': 'green'">Red</button>
|
|
||||||
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
|
|
||||||
<!-- #enddocregion style-binding -->
|
|
||||||
|
|
||||||
<!-- #docregion style-binding-condition-->
|
<!-- #docregion style-delegation -->
|
||||||
<button [style.font-size.em]="isSpecial ? 3 : 1" >Big</button>
|
<comp-with-host-binding dirWithHostBinding></comp-with-host-binding>
|
||||||
<button [style.font-size.%]="!isSpecial ? 150 : 50" >Small</button>
|
<!-- #enddocregion style-delegation -->
|
||||||
<!-- #enddocregion style-binding-condition-->
|
|
||||||
|
|
||||||
<!-- #docregion direct-style-binding -->
|
|
||||||
<h3>Bind to multiple styles</h3>
|
|
||||||
|
|
||||||
<div style="color: blue" [style]="styleExpr">Add multiple styles</div>
|
|
||||||
<!-- #enddocregion direct-style-binding -->
|
|
||||||
|
|
|
@ -9,8 +9,7 @@ export class AppComponent {
|
||||||
actionName = 'Go for it';
|
actionName = 'Go for it';
|
||||||
isSpecial = true;
|
isSpecial = true;
|
||||||
canSave = true;
|
canSave = true;
|
||||||
someClasses = 'foo bar';
|
classExpr = 'special clearance';
|
||||||
classExpr = 'special foo';
|
|
||||||
styleExpr = 'color: red';
|
styleExpr = 'color: red';
|
||||||
color = 'blue';
|
color = 'blue';
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
import { CompWithHostBindingComponent } from './comp-with-host-binding.component';
|
||||||
|
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent
|
AppComponent,
|
||||||
|
CompWithHostBindingComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule
|
BrowserModule
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { Component } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'comp-with-host-binding',
|
||||||
|
template: 'I am a component!',
|
||||||
|
host: {
|
||||||
|
'[class.special]': 'isSpecial',
|
||||||
|
'[style.color]': 'color',
|
||||||
|
'[style.width]': 'width'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
export class CompWithHostBindingComponent {
|
||||||
|
isSpecial = false;
|
||||||
|
color = 'green';
|
||||||
|
width = '200px';
|
||||||
|
}
|
|
@ -892,68 +892,97 @@ Instead, you'd use property binding and write it like this:
|
||||||
|
|
||||||
### Class binding
|
### Class binding
|
||||||
|
|
||||||
Add and remove CSS class names from an element's `class` attribute with
|
Here's how to set the `class` attribute without a binding in plain HTML:
|
||||||
a **class binding**.
|
|
||||||
|
|
||||||
Here's how to set the attribute without a binding in plain HTML:
|
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- standard class attribute setting -->
|
<!-- standard class attribute setting -->
|
||||||
<div class="item clearance special">Item clearance special</div>
|
<div class="foo bar">Some text</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
Class binding syntax resembles property binding, but instead of an element property between brackets, start with the prefix `class`,
|
You can also add and remove CSS class names from an element's `class` attribute with a **class binding**.
|
||||||
optionally followed by a dot (`.`) and the name of a CSS class: `[class.class-name]`.
|
|
||||||
Angular adds the class when the template expression evaluates to truthy.
|
|
||||||
It removes the class when the expression is falsy.
|
|
||||||
|
|
||||||
Binding to a specific class is additive, so it won't overwrite other class bindings or static classes unless the class names are duplicated.
|
To create a single class binding, start with the prefix `class` followed by a dot (`.`) and the name of the CSS class (for example, `[class.foo]="hasFoo"`).
|
||||||
|
Angular adds the class when the bound expression is truthy, and it removes the class when the expression is falsy (with the exception of `undefined`, see [styling delegation](#styling-delegation)).
|
||||||
|
|
||||||
In the example below, the final class list for the `<div>` will be `"item clearance special"` if `isSpecial` is truthy, and only `"item clearance"` if it is falsy.
|
To create a binding to multiple classes, use a generic `[class]` binding without the dot (for example, `[class]="classExpr"`).
|
||||||
|
The expression can be a space-delimited string of class names, or you can format it as an object with class names as the keys and truthy/falsy expressions as the values.
|
||||||
|
With object format, Angular will add a class only if its associated value is truthy.
|
||||||
|
|
||||||
<code-example path="attribute-binding/src/app/app.component.html" region="add-class" header="src/app/app.component.html"></code-example>
|
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
|
||||||
|
|
||||||
You can also use the alternative class binding syntax that replaces square brackets with the `bind-` keyword:
|
|
||||||
|
|
||||||
<code-example path="attribute-binding/src/app/app.component.html" region="bind-syntax" header="src/app/app.component.html"></code-example>
|
|
||||||
|
|
||||||
If there are multiple classes you'd like to toggle, you can bind to the `[class]` property directly.
|
|
||||||
Binding to `[class]` is additive, so it shouldn't overwrite other class bindings or static classes unless the class names are duplicated*.
|
|
||||||
|
|
||||||
<code-example path="attribute-binding/src/app/app.component.html" region="direct-class-binding" header="src/app/app.component.html"></code-example>
|
|
||||||
|
|
||||||
The expression attached to the `[class]` binding is most often a string list of class names like `"clearance special"`.
|
|
||||||
|
|
||||||
You can also format the expression as an object with class names as the keys and truthy/falsy expressions as the values, like `{clearance: true, special: false}`.
|
|
||||||
In this case, Angular will add a class only if its associated value is truthy.
|
|
||||||
It's important to note that with object format, the identity of the object must change for the class list to be updated.
|
|
||||||
Updating the property without changing object identity will have no effect.
|
Updating the property without changing object identity will have no effect.
|
||||||
|
|
||||||
*This is true for Angular version 9 and later. For Angular version 8, see <a href="http://v8.angular.io/guide/template-syntax#class-binding">v8.angular.io</a>
|
If there are multiple bindings to the same class name, conflicts are resolved using [styling precedence](#styling-precedence).
|
||||||
|
|
||||||
|
<style>
|
||||||
|
td, th {vertical-align: top}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<table width="100%">
|
||||||
|
<col width="15%">
|
||||||
|
</col>
|
||||||
|
<col width="20%">
|
||||||
|
</col>
|
||||||
|
<col width="35%">
|
||||||
|
</col>
|
||||||
|
<col width="30%">
|
||||||
|
</col>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Binding Type
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Syntax
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Input Type
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Example Input Values
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Single class binding</td>
|
||||||
|
<td><code>[class.foo]="hasFoo"</code></td>
|
||||||
|
<td><code>boolean | undefined | null</code></td>
|
||||||
|
<td><code>true</code>, <code>false</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td rowspan=3>Multi-class binding</td>
|
||||||
|
<td rowspan=3><code>[class]="classExpr"</code></td>
|
||||||
|
<td><code>string</code></td>
|
||||||
|
<td><code>"my-class-1 my-class-2 my-class-3"</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>{[key: string]: boolean | undefined | null}</code></td>
|
||||||
|
<td><code>{foo: true, bar: false}</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>Array</code><<code>string</code>></td>
|
||||||
|
<td><code>['foo', 'bar']</code></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
The [NgClass](#ngclass) directive can be used as an alternative to direct `[class]` bindings.
|
||||||
|
However, using the above class binding syntax without `NgClass` is preferred because due to improvements in class binding in Angular, `NgClass` no longer provides significant value, and might eventually be removed in the future.
|
||||||
|
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
### Style binding
|
### Style binding
|
||||||
|
|
||||||
Here's how to set the style attribute without a binding in plain HTML:
|
Here's how to set the `style` attribute without a binding in plain HTML:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<!-- standard style attribute setting -->
|
<!-- standard style attribute setting -->
|
||||||
<div style="color: blue">Item clearance special</div>
|
<div style="color: blue">Some text</div>
|
||||||
```
|
```
|
||||||
|
|
||||||
You can set styles dynamically with a **style binding**.
|
You can also set styles dynamically with a **style binding**.
|
||||||
|
|
||||||
Style binding syntax resembles property binding.
|
To create a single style binding, start with the prefix `style` followed by a dot (`.`) and the name of the CSS style property (for example, `[style.width]="width"`).
|
||||||
Instead of an element property between brackets, start with the prefix `style`,
|
The property will be set to the value of the bound expression, which is normally a string.
|
||||||
followed by a dot (`.`) and the name of a CSS style property: `[style.style-property]`.
|
Optionally, you can add a unit extension like `em` or `%`, which requires a number type.
|
||||||
|
|
||||||
<code-example path="attribute-binding/src/app/app.component.html" region="style-binding" header="src/app/app.component.html"></code-example>
|
|
||||||
|
|
||||||
Some style binding styles have a unit extension.
|
|
||||||
The following example conditionally sets the font size in “em” and “%” units.
|
|
||||||
|
|
||||||
<code-example path="attribute-binding/src/app/app.component.html" region="style-binding-condition" header="src/app/app.component.html"></code-example>
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
|
@ -963,22 +992,140 @@ Note that a _style property_ name can be written in either
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly.
|
If there are multiple styles you'd like to toggle, you can bind to the `[style]` property directly without the dot (for example, `[style]="styleExpr"`).
|
||||||
Binding to `[style]` is additive, so it shouldn't overwrite other style bindings or static styles unless the same style property is duplicated.
|
|
||||||
|
|
||||||
<code-example path="attribute-binding/src/app/app.component.html" region="direct-style-binding" header="src/app/app.component.html"></code-example>
|
|
||||||
|
|
||||||
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
|
The expression attached to the `[style]` binding is most often a string list of styles like `"width: 100px; height: 100px;"`.
|
||||||
|
|
||||||
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
|
You can also format the expression as an object with style names as the keys and style values as the values, like `{width: '100px', height: '100px'}`.
|
||||||
It's important to note that with object format, the identity of the object must change for the styles to be updated.
|
It's important to note that with any object-like expression (`object`, `Array`, `Map`, `Set`, etc), the identity of the object must change for the class list to be updated.
|
||||||
Updating the property without changing object identity will have no effect.
|
Updating the property without changing object identity will have no effect.
|
||||||
|
|
||||||
*This is true for Angular version 9 and later. For Angular version 8, see <a href="http://v8.angular.io/guide/template-syntax#style-binding">v8.angular.io</a>
|
If there are multiple bindings to the same style property, conflicts are resolved using [styling precedence rules](#styling-precedence).
|
||||||
|
|
||||||
|
<style>
|
||||||
|
td, th {vertical-align: top}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<table width="100%">
|
||||||
|
<col width="15%">
|
||||||
|
</col>
|
||||||
|
<col width="20%">
|
||||||
|
</col>
|
||||||
|
<col width="35%">
|
||||||
|
</col>
|
||||||
|
<col width="30%">
|
||||||
|
</col>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
Binding Type
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Syntax
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Input Type
|
||||||
|
</th>
|
||||||
|
<th>
|
||||||
|
Example Input Values
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Single style binding</td>
|
||||||
|
<td><code>[style.width]="width"</code></td>
|
||||||
|
<td><code>string | undefined | null</code></td>
|
||||||
|
<td><code>"100px"</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<tr>
|
||||||
|
<td>Single style binding with units</td>
|
||||||
|
<td><code>[style.width.px]="width"</code></td>
|
||||||
|
<td><code>number | undefined | null</code></td>
|
||||||
|
<td><code>100</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td rowspan=3>Multi-style binding</td>
|
||||||
|
<td rowspan=3><code>[style]="styleExpr"</code></td>
|
||||||
|
<td><code>string</code></td>
|
||||||
|
<td><code>"width: 100px; height: 100px"</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>{[key: string]: string | undefined | null}</code></td>
|
||||||
|
<td><code>{width: '100px', height: '100px'}</code></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><code>Array</code><<code>string</code>></td>
|
||||||
|
<td><code>['width', '100px']</code></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
The [NgStyle](#ngstyle) directive can be used as an alternative to direct `[style]` bindings.
|
||||||
|
However, using the above style binding syntax without `NgStyle` is preferred because due to improvements in style binding in Angular, `NgStyle` no longer provides significant value, and might eventually be removed in the future.
|
||||||
|
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|
||||||
|
{@a styling-precedence}
|
||||||
|
### Styling Precedence
|
||||||
|
|
||||||
|
A single HTML element can have its CSS class list and style values bound to a multiple sources (for example, host bindings from multiple directives).
|
||||||
|
|
||||||
|
When there are multiple bindings to the same class name or style property, Angular uses a set of precedence rules to resolve conflicts and determine which classes or styles are ultimately applied to the element.
|
||||||
|
|
||||||
|
<div class="alert is-helpful">
|
||||||
|
<h4>Styling precedence (highest to lowest)</h4>
|
||||||
|
|
||||||
|
1. Template bindings
|
||||||
|
1. Property binding (for example, `<div [class.foo]="hasFoo">` or `<div [style.color]="color">`)
|
||||||
|
1. Map binding (for example, `<div [class]="classExpr">` or `<div [style]="styleExpr">`)
|
||||||
|
1. Static value (for example, `<div class="foo">` or `<div style="color: blue">`)
|
||||||
|
1. Directive host bindings
|
||||||
|
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
|
||||||
|
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
|
||||||
|
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
|
||||||
|
1. Component host bindings
|
||||||
|
1. Property binding (for example, `host: {'[class.foo]': 'hasFoo'}` or `host: {'[style.color]': 'color'}`)
|
||||||
|
1. Map binding (for example, `host: {'[class]': 'classExpr'}` or `host: {'[style]': 'styleExpr'}`)
|
||||||
|
1. Static value (for example, `host: {'class': 'foo'}` or `host: {'style': 'color: blue'}`)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
The more specific a class or style binding is, the higher its precedence.
|
||||||
|
|
||||||
|
A binding to a specific class (for example, `[class.foo]`) will take precedence over a generic `[class]` binding, and a binding to a specific style (for example, `[style.bar]`) will take 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>
|
||||||
|
|
||||||
|
Specificity rules also apply when it comes to bindings that originate from different sources.
|
||||||
|
It's possible for an element to have bindings in the template where it's declared, from host bindings on matched directives, and from host bindings on matched components.
|
||||||
|
|
||||||
|
Template bindings are the most specific because they apply to the element directly and exclusively, so they have the highest precedence.
|
||||||
|
|
||||||
|
Directive host bindings are considered less specific because directives can be used in multiple locations, so they have a lower precedence than template bindings.
|
||||||
|
|
||||||
|
Directives often augment component behavior, so host bindings from components have the lowest precedence.
|
||||||
|
|
||||||
|
<code-example path="attribute-binding/src/app/app.component.html" region="source-specificity" header="src/app/app.component.html"></code-example>
|
||||||
|
|
||||||
|
In addition, bindings take precedence over static attributes.
|
||||||
|
|
||||||
|
In the following case, `class` and `[class]` have similar specificity, but the `[class]` binding will take precedence because it is dynamic.
|
||||||
|
|
||||||
|
<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
|
||||||
|
|
||||||
|
It is possible for higher precedence styles to "delegate" to lower precedence styles using `undefined` values.
|
||||||
|
Whereas setting a style property to `null` ensures the style is removed, setting it to `undefined` will cause Angular to fall back to the next-highest precedence binding to that style.
|
||||||
|
|
||||||
|
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.
|
||||||
|
In that case, if `dirWithHostBinding` sets its binding to `undefined`, the `width` property will fall back to the value of the `comp-with-host-binding` host binding.
|
||||||
|
However, if `dirWithHostBinding` sets its binding to `null`, the `width` property will be removed entirely.
|
||||||
|
|
||||||
|
|
||||||
{@a event-binding}
|
{@a event-binding}
|
||||||
|
|
||||||
## Event binding `(event)`
|
## Event binding `(event)`
|
||||||
|
|
Loading…
Reference in New Issue