# Attributes
Typed attributes on a template constructor, reactive expression blocks, and
the two-way bindings Elements installs on form controls.
Attributes go in `()` on the opening tag. Each attribute is `public` (the
default) or `private`. Optional attributes use `?`. Attributes can have
initializers that reference other attributes, and declaration order does not
matter. `private` attributes cannot be provided by callers, but they can be
mutated inside the template scope.
```ehtml
{greeting}
```
Attributes are fully typed and integrated with the codebase's tooling: rename,
find-references, go-to-definition, and type checking work across templates and
TypeScript alike.
## Layout
One or two attributes sit on the tag line.
```ehtml
```
Three or more go one per line. The `(` stays on the tag line, each attribute
gets a line and a trailing comma, and `)>` closes at the tag's indent.
```ehtml
```
The trailing comma is optional and worth writing: adding an attribute then
touches one line instead of two.
Regular attributes stay on the tag line ahead of the `(`, and a long one goes
after the `)`.
```ehtml
,
view: View,
private draft: Draft = { title: "" },
) oninit={() => window.addEventListener("popstate", () => onPopState(view))}>
```
Do not hang the list off the tag name's indent:
```ehtml
```
Every line there starts at a different column, so the constructor does not read
as a list and `class` does not read as separate from it. The rule is the one
TypeScript uses for a parameter list: open on the declaration line, one item per
line, close at the declaration's indent.
Attributes are reactive automatically, including across template boundaries:
```ehtml
done: {tasks.filter(t => t.done).length}
```
Toggling the checkbox in `` updates the count in `` immediately.
**Attributes live on the root tag only.** An attribute list on a non-root element
(e.g. `
`) is invalid.
**A union inside an object default needs a cast.** The declared type does not
currently reach into an object literal used as a default, so a union field in
one is inferred as its widened type and rejected:
```ehtml
```
Grouping template state into one object is the usual way to keep it mutable: a
handler can mutate an object's fields and the change is live, while reassigning
a plain attribute inside a handler is not (see Reactivity). The object is
therefore often the right shape, and the cast is the price until this is fixed.
## Expressions
`{ ... }` is a TypeScript expression. Allowed as element children and attribute
values.
```ehtml