Property binding lets you set a DOM element property, or a child component's input, directly from a TypeScript expression. This lesson explains the syntax and where it differs from plain HTML attributes.
What Is Property Binding?
Property binding uses square brackets, [property]="expression", to set a DOM property (not just an HTML attribute) to the result of a TypeScript expression evaluated on the component class.
This distinction matters because many DOM properties don't have a simple string equivalent, disabled is a boolean, src needs a real URL string, and a component's custom @Input() might expect an entire object.
[property] targets a DOM element property directly (like .value, .disabled, .src).
[attr.name] targets an HTML attribute explicitly, useful for attributes with no matching DOM property (like aria-* or colspan).
[class.name] toggles a single CSS class based on a boolean expression.
[style.property] sets a single inline CSS property directly.
Angular Property Binding Cheatsheet
Common property, attribute, class, and style bindings you'll write often.
Binding
Example
Notes
DOM property
[value]="name"
Binds the live property, not the attribute
Boolean property
[disabled]="isSaving"
Sets a real boolean, not the string "false"
Attribute binding
[attr.aria-label]="label"
For attributes with no DOM property
Single class
[class.active]="isActive"
Toggles one class conditionally
Class object
[class]="classMap"
Sets multiple classes from an object/string
Single style
[style.color]="textColor"
Sets one inline style property
Component input
[title]="pageTitle"
Passes data into a child's @Input()/input()
Property Binding vs Attribute Binding
Most HTML attributes have a matching DOM property with the same name and Angular's [property] syntax targets that property by default. Some attributes, however, have no DOM property equivalent (like colspan or custom data-*/aria-* attributes), for those, use the explicit [attr.name] form.
Without attr., Angular would look for a colspan or ariaExpanded DOM property, which doesn't exist for colspan and is named differently for ARIA.
Binding to Component Inputs
The same [property] syntax used for native DOM properties is also how you pass data into a child component's @Input() (or input() signal input). Angular resolves whether the target is a DOM property or a component input based on the element/component being bound to.
Interpolation ({{ }}) is really just a readable shorthand for property binding when the target is a string, text content or a string attribute value. Anything non-string (booleans, numbers used as numbers, objects) requires square-bracket property binding.
<!-- equivalent for string values -->
<img src="{{ imageUrl }}" />
<img [src]="imageUrl" />
<!-- only property binding works correctly here -->
<button [disabled]="isSaving">Save</button>
Common Mistakes
Using interpolation to set boolean properties like disabled="{{ isSaving }}", which always evaluates truthy as a string.
Forgetting the attr. prefix for attributes without a matching DOM property, like colspan or custom data-* attributes.
Binding a whole object to [class] when only a single conditional class is needed ([class.active] is simpler).
Assuming [value] on native form controls behaves like two-way binding; it is one-way unless combined with an event binding or ngModel.
Key Takeaways
Property binding ([property]) sets a real DOM property, not just a string attribute.
Use [attr.name] for attributes without a corresponding DOM property.
[class.name] and [style.property] are convenient shorthands for single conditional classes or styles.
The exact same [property] syntax is used to pass data into a child component's inputs.
Pro Tip
When in doubt about interpolation vs property binding, default to property binding ([ ]) for anything other than plain text content, it avoids subtle bugs with booleans and numbers rendered as strings.
You now understand Angular property binding in depth. Next, learn about Angular Directives to add reusable behavior to your templates.