diff --git a/aio/content/examples/attribute-binding/e2e/src/app.e2e-spec.ts b/aio/content/examples/attribute-binding/e2e/src/app.e2e-spec.ts
new file mode 100644
index 0000000000..c02fa87e1b
--- /dev/null
+++ b/aio/content/examples/attribute-binding/e2e/src/app.e2e-spec.ts
@@ -0,0 +1,47 @@
+'use strict'; // necessary for es6 output in node
+
+import { browser, element, by } from 'protractor';
+
+describe('Attribute binding example', function () {
+
+ beforeEach(function () {
+ browser.get('');
+ });
+
+ it('should display Property Binding with Angular', function () {
+ expect(element(by.css('h1')).getText()).toEqual('Attribute, class, and style bindings');
+ });
+
+ it('should display a table', function() {
+ expect(element.all(by.css('table')).isPresent()).toBe(true);
+ });
+
+ it('should display an Aria button', function () {
+ expect(element.all(by.css('button')).get(0).getText()).toBe('Go for it with Aria');
+ });
+
+ it('should display a blue background on div', function () {
+ expect(element.all(by.css('div')).get(1).getCssValue('background-color')).toEqual('rgba(25, 118, 210, 1)');
+ });
+
+ 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)');
+ });
+
+ it('should display a div with replaced classes', function () {
+ expect(element.all(by.css('div')).get(5).getAttribute('class')).toEqual('new-class');
+ });
+
+ 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');
+ });
+
+});
diff --git a/aio/content/examples/attribute-binding/example-config.json b/aio/content/examples/attribute-binding/example-config.json
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/aio/content/examples/attribute-binding/src/app/app.component.css b/aio/content/examples/attribute-binding/src/app/app.component.css
new file mode 100644
index 0000000000..f26e6c8569
--- /dev/null
+++ b/aio/content/examples/attribute-binding/src/app/app.component.css
@@ -0,0 +1,22 @@
+.special {
+ background-color: #1976d2;
+ color: #ffffff;
+}
+
+.item {
+ font-weight: bold;
+}
+.clearance {
+ border: 2px solid #d41e2e;
+
+}
+.item-clearance {
+ font-style: italic;
+
+}
+
+.new-class {
+ background-color: #ed1b2f;
+ font-style: italic;
+ color: #fff;
+}
diff --git a/aio/content/examples/attribute-binding/src/app/app.component.html b/aio/content/examples/attribute-binding/src/app/app.component.html
new file mode 100644
index 0000000000..7a2fb3311f
--- /dev/null
+++ b/aio/content/examples/attribute-binding/src/app/app.component.html
@@ -0,0 +1,65 @@
+
+
Attribute, class, and style bindings
+
Attribute binding
+
+
+
+
One-Two
+
+
+
+
+
Three-Four
+
+
+
Five
Six
+
+
+
+
+
+
+
+
+
+
+
+
+
Class binding
+
+
+
toggle the "special" class on/off with a property:
+
The class binding is special.
+
+
binding to class.special overrides the class attribute:
+
This one is not so special.
+
+
Using the bind- syntax:
+
This class binding is special too.
+
+
+
+
Add a class:
+
Add another class
+
+
+
+
Overwrite all existing classes with a new class:
+
Reset all classes at once
+
+
+
+
+
Style binding
+
+
+
+
+
+
+
+
+
+
diff --git a/aio/content/examples/attribute-binding/src/app/app.component.spec.ts b/aio/content/examples/attribute-binding/src/app/app.component.spec.ts
new file mode 100644
index 0000000000..bcbdf36b3e
--- /dev/null
+++ b/aio/content/examples/attribute-binding/src/app/app.component.spec.ts
@@ -0,0 +1,27 @@
+import { TestBed, async } from '@angular/core/testing';
+import { AppComponent } from './app.component';
+describe('AppComponent', () => {
+ beforeEach(async(() => {
+ TestBed.configureTestingModule({
+ declarations: [
+ AppComponent
+ ],
+ }).compileComponents();
+ }));
+ it('should create the app', async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app).toBeTruthy();
+ }));
+ it(`should have as title 'app'`, async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ const app = fixture.debugElement.componentInstance;
+ expect(app.title).toEqual('app');
+ }));
+ it('should render title in a h1 tag', async(() => {
+ const fixture = TestBed.createComponent(AppComponent);
+ fixture.detectChanges();
+ const compiled = fixture.debugElement.nativeElement;
+ expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
+ }));
+});
diff --git a/aio/content/examples/attribute-binding/src/app/app.component.ts b/aio/content/examples/attribute-binding/src/app/app.component.ts
new file mode 100644
index 0000000000..f79b22c817
--- /dev/null
+++ b/aio/content/examples/attribute-binding/src/app/app.component.ts
@@ -0,0 +1,15 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'app-root',
+ templateUrl: './app.component.html',
+ styleUrls: ['./app.component.css']
+})
+export class AppComponent {
+ actionName = 'Go for it';
+ isSpecial = true;
+ itemClearance = true;
+ resetClasses = 'new-class';
+ canSave = true;
+
+}
diff --git a/aio/content/examples/attribute-binding/src/app/app.module.ts b/aio/content/examples/attribute-binding/src/app/app.module.ts
new file mode 100644
index 0000000000..926975afe8
--- /dev/null
+++ b/aio/content/examples/attribute-binding/src/app/app.module.ts
@@ -0,0 +1,18 @@
+import { BrowserModule } from '@angular/platform-browser';
+import { NgModule } from '@angular/core';
+
+
+import { AppComponent } from './app.component';
+
+
+@NgModule({
+ declarations: [
+ AppComponent
+ ],
+ imports: [
+ BrowserModule
+ ],
+ providers: [],
+ bootstrap: [AppComponent]
+})
+export class AppModule { }
diff --git a/aio/content/examples/attribute-binding/src/index.html b/aio/content/examples/attribute-binding/src/index.html
new file mode 100644
index 0000000000..0cfaba9b75
--- /dev/null
+++ b/aio/content/examples/attribute-binding/src/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+ AttributeBinding
+
+
+
+
+
+
+
+
+
diff --git a/aio/content/examples/attribute-binding/src/main.ts b/aio/content/examples/attribute-binding/src/main.ts
new file mode 100644
index 0000000000..91ec6da5f0
--- /dev/null
+++ b/aio/content/examples/attribute-binding/src/main.ts
@@ -0,0 +1,12 @@
+import { enableProdMode } from '@angular/core';
+import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
+
+import { AppModule } from './app/app.module';
+import { environment } from './environments/environment';
+
+if (environment.production) {
+ enableProdMode();
+}
+
+platformBrowserDynamic().bootstrapModule(AppModule)
+ .catch(err => console.log(err));
diff --git a/aio/content/examples/attribute-binding/stackblitz.json b/aio/content/examples/attribute-binding/stackblitz.json
new file mode 100644
index 0000000000..1a0178b68a
--- /dev/null
+++ b/aio/content/examples/attribute-binding/stackblitz.json
@@ -0,0 +1,10 @@
+{
+ "description": "Attribute Binding",
+ "files": [
+ "!**/*.d.ts",
+ "!**/*.js",
+ "!**/*.[1,2].*"
+ ],
+ "file": "src/app/app.component.ts",
+ "tags": ["Attribute Binding"]
+}
diff --git a/aio/content/guide/template-syntax.md b/aio/content/guide/template-syntax.md
index 8165cf751c..d42d9b1ce8 100644
--- a/aio/content/guide/template-syntax.md
+++ b/aio/content/guide/template-syntax.md
@@ -895,108 +895,103 @@ of the `evilTitle` examples.
## Attribute, class, and style bindings
-The template syntax provides specialized one-way bindings for scenarios less well suited to property binding.
+The template syntax provides specialized one-way bindings for scenarios less well-suited to property binding.
+
+To see attribute, class, and style bindings in a functioning app, see the especially for this section.
+
### Attribute binding
-You can set the value of an attribute directly with an **attribute binding**.
+Set the value of an attribute directly with an **attribute binding**. This is the only exception to the rule that a binding sets a target property and the only binding that creates and sets an attribute.
+
+Usually, setting an element property with a [property binding](guide/template-syntax#property-binding)
+is preferable to setting the attribute with a string. However, sometimes
+there is no element property to bind, so attribute binding is the solution.
+
+Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) and
+[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG). They are purely attributes, don't correspond to element properties, and don't set element properties. In these cases, there are no property targets to bind to.
+
+Attribute binding syntax resembles property binding, but
+instead of an element property between brackets, start with the prefix `attr`,
+followed by a dot (`.`), and the name of the attribute.
+You then set the attribute value, using an expression that resolves to a string,
+or remove the attribute when the expression resolves to `null`.
+
+One of the primary use cases for attribute binding
+is to set ARIA attributes, as in this example:
+
+
+
-This is the only exception to the rule that a binding sets a target property.
-This is the only binding that creates and sets an attribute.
+#### `colspan` and `colSpan`
-
+Notice the difference between the `colspan` attribute and the `colSpan` property.
-This guide stresses repeatedly that setting an element property with a property binding
-is always preferred to setting the attribute with a string. Why does Angular offer attribute binding?
-
-**You must use attribute binding when there is no element property to bind.**
-
-Consider the [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA),
-[SVG](https://developer.mozilla.org/en-US/docs/Web/SVG), and
-table span attributes. They are pure attributes.
-They do not correspond to element properties, and they do not set element properties.
-There are no property targets to bind to.
-
-This fact becomes obvious when you write something like this.
+If you wrote something like this:
<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>
-And you get this error:
+You'd get this error:
Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
-As the message says, the `
` element does not have a `colspan` property.
-It has the "colspan" *attribute*, but
-interpolation and property binding can set only *properties*, not attributes.
+As the message says, the `
` element does not have a `colspan` property. This is true
+because `colspan` is an attribute—`colSpan`, with a capital `S`, is the
+corresponding property. Interpolation and property binding can set only *properties*, not attributes.
-You need attribute bindings to create and bind to such attributes.
+Instead, you'd use property binding and write it like this:
-Attribute binding syntax resembles property binding.
-Instead of an element property between brackets, start with the prefix **`attr`**,
-followed by a dot (`.`) and the name of the attribute.
-You then set the attribute value, using an expression that resolves to a string.
-
-Bind `[attr.colspan]` to a calculated value:
-
-
+
-Here's how the table renders:
-
-
-
One-Two
-
Five
Six
-
-
-One of the primary use cases for attribute binding
-is to set ARIA attributes, as in this example:
-
-
-
+
### Class binding
-You can add and remove CSS class names from an element's `class` attribute with
+Add and remove CSS class names from an element's `class` attribute with
a **class binding**.
-Class binding syntax resembles property binding.
-Instead of an element property between brackets, start with the prefix `class`,
+Here's how to set the attribute without binding in plain HTML:
+
+```html
+
+
Item clearance special
+```
+
+Class binding syntax resembles property binding, but instead of an element property between brackets, start with the prefix `class`,
optionally followed by a dot (`.`) and the name of a CSS class: `[class.class-name]`.
-The following examples show how to add and remove the application's "special" class
-with class bindings. Here's how to set the attribute without binding:
-
-
-
-
You can replace that with a binding to a string of the desired class names; this is an all-or-nothing, replacement binding.
-
+
+
+
+
+You can also add append a class to an element without overwriting the classes already on the element:
+
+
Finally, you can bind to a specific class name.
Angular adds the class when the template expression evaluates to truthy.
It removes the class when the expression is falsy.
-
+
-
-
-While this is a fine way to toggle a single class name,
-the [NgClass directive](guide/template-syntax#ngClass) is usually preferred when managing multiple class names at the same time.
-
-
+While this technique is suitable for toggling a single class name,
+consider the [`NgClass`](guide/template-syntax#ngClass) directive when
+managing multiple class names at the same time.
@@ -1009,21 +1004,17 @@ Style binding syntax resembles property binding.
Instead of an element property between brackets, start with the prefix `style`,
followed by a dot (`.`) and the name of a CSS style property: `[style.style-property]`.
-
+
Some style binding styles have a unit extension.
The following example conditionally sets the font size in “em” and “%” units .
-
+
-
-
-While this is a fine way to set a single style,
-the [NgStyle directive](guide/template-syntax#ngStyle) is generally preferred when setting several inline styles at the same time.
-
-
+**This technique is suitable for setting a single style, but consider
+the [`NgStyle`](guide/template-syntax#ngStyle) directive when setting several inline styles at the same time.**