Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Understand Binding  ›  Lesson

Property and Attribute Binding

Property Binding 12 minSquare brackets bind an expression to a DOM property of an element or an input of a component, and the attr. prefix binds to plain HTML attributes that have no matching property.

Property and Attribute Binding

The plant card needs a photo whose address comes from data, a button that turns grey while watering is in progress, and a red border when the plant is thirsty. Each of these sets something on an element. That is the job of square brackets.

The rule

Brackets mean "evaluate this"; no brackets means "this exact text".

Property binding puts the result of an expression into a DOM property, or into a component input:

<img [src]="plant().photo" [alt]="plant().name" />
<button [disabled]="watering()">Water</button>
<app-plant-card [plant]="p" />

Without brackets, src="plant().photo" is plain HTML: the browser gets the literal characters plant().photo as the address.

Two handy shapes for styling:

<article [class.thirsty]="isThirsty()">...</article>
<div class="gauge" [style.width.%]="waterLevel()"></div>

[class.thirsty] adds the class while the expression is true and removes it when false. [style.width.%] sets one style, with the unit written after the dot.

Attribute binding exists because not every HTML attribute has a DOM property. ARIA attributes, data-* attributes and many SVG attributes are like this. Prefix the name with attr.:

<button [attr.aria-label]="'Water ' + plant().name">💧</button>
<li [attr.data-plant-id]="plant().id">...</li>

If the bound value is null, Angular removes the attribute completely, which is how you make one optional.

Why the difference? An HTML attribute is the starting text in the markup; a DOM property is the live value on the element object. disabled has a property, so [disabled] works. data-plant-id has no property at all, so [data-plant-id] fails with "not a known property", and [attr.data-plant-id] fixes it. (Recent Angular versions also accept ARIA names without the prefix, but [attr.aria-label] works in every version and says plainly that you are setting an attribute.)

The shortcut

Ask two quick questions. Is the value computed? Then use brackets. Is it ARIA, data-* or SVG? Then add attr.. Everything else is a plain [property].

Binding the thirsty badgeStep 1 of 4
  1. Computed?

    The badge text colour depends on isThirsty(), so it needs brackets.

Drills

Answer fast — trust the rule.

quick drill

What does the browser receive for <img src="plant().photo" />?

quick drill

Which binding disables the button while watering() is true?

quick drill

How do you set a data-plant-id attribute from plant().id?

quick drill

What happens with [attr.data-note]="note()" when note() returns null?

Remember

  • [prop]="expr" evaluates and sets a DOM property or component input; no brackets means literal text.
  • [class.x] toggles a class, [style.width.px] sets one style, [attr.x] sets a real attribute.
  • Trap: data-* (and, for older versions, ARIA) attributes need attr.; binding null removes the attribute.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainBrackets, prefixes and strings

Write bindings for Greenhouse's plant card that: set an image src from plant().photo, disable the Water button while watering() is true, add a thirsty class when isThirsty() is true, and set aria-label to the plant's name. Then explain what goes wrong if you write src="plant().photo" without brackets.