@title
Structural Directives
@intro
Angular has a powerful template engine that lets us easily manipulate the DOM structure of our elements.
@description
This guide looks at how Angular manipulates the DOM with **structural directives** and
how you can write your own structural directives to do the same thing.
### Table of contents
- [What are structural directives?](#definition)
- [*NgIf* case study](#ngIf)
- [Group sibling elements with <ng-container>](#ng-container)
- [The asterisk (\*) prefix](#asterisk)
- [Inside *NgFor*](#ngfor)
- [microsyntax](#microsyntax)
- [template input variables](#template-input-variable)
- [one structural directive per element](#one-per-element)
- [Inside the *NgSwitch* directives](#ngSwitch)
- [Prefer the (\*) prefix](#prefer-asterisk)
- [The <template> element](#template)
- [Write a structural directive](#unless)
Try the .
{@a definition}
## What are structural directives?
Structural directives are responsible for HTML layout.
They shape or reshape the DOM's _structure_, typically by adding, removing, or manipulating
elements.
As with other directives, you apply a structural directive to a _host element_.
The directive then does whatever it's supposed to do with that host element and its descendents.
Structural directives are easy to recognize.
An asterisk (\*) precedes the directive attribute name as in this example.
{@example 'structural-directives/ts/src/app/app.component.html' region='ngif'}
No brackets. No parentheses. Just `*ngIf` set to a string.
You'll learn in this guide that the [asterisk (\*) is a convenience notation](#asterisk)
and the string is a [_microsyntax_](#microsyntax) rather than the usual [template expression](template-syntax.html#template-expressions).
Angular "de-sugars" this notation into a marked-up `` that surrounds the
host element and its descendents.
Each structural directive does something different with that template.
Three of the common, built-in structural directives—[NgIf](template-syntax.html#ngIf),
[NgFor](template-syntax.html#ngFor), and [NgSwitch...](template-syntax.html#ngSwitch)—are
described in the [_Template Syntax_](template-syntax.html) guide and seen in samples throughout the Angular documentation.
Here's an example of them in a template:
{@example 'structural-directives/ts/src/app/app.component.html' region='built-in'}
This guide won't repeat how to _use_ them. But it does explain _how they work_
and how to [write your own](#unless) structural directive.
~~~ {.callout.is-helpful}
Directive spelling
Throughout this guide, you'll see a directive spelled in both _UpperCamelCase_ and _lowerCamelCase_.
Already you've seen `NgIf` and `ngIf`.
There's a reason. `NgIf` refers to the directive _class_;
`ngIf` refers to the directive's _attribute name_.
A directive _class_ is spelled in _UpperCamelCase_ (`NgIf`).
A directive's _attribute name_ is spelled in _lowerCamelCase_ (`ngIf`).
The guide refers to the directive _class_ when talking about its properties and what the directive does.
The guide refers to the _attribute name_ when describing how
you apply the directive to an element in the HTML template.
~~~
There are two other kinds of Angular directives, described extensively elsewhere: (1) components and (2) attribute directives.
A *component* manages a region of HTML in the manner of a native HTML element.
Technically it's a directive with a template.
An [*attribute* directive](attribute-directives.html) changes the appearance or behavior
of an element, component, or another directive.
For example, the built-in [`NgStyle`](template-syntax.html#ngStyle) directive
changes several element styles at the same time.
You can apply many _attribute_ directives to one host element.
You can [only apply one](#one-per-element) _structural_ directive to a host element.
{@a ngIf}
## NgIf Case Study
`NgIf` is the simplest structural directive and the easiest to understand.
It takes a boolean value and makes an entire chunk of the DOM appear or disappear.
{@example 'structural-directives/ts/src/app/app.component.html' region='ngif-true'}
The `ngIf` directive doesn't hide elements with CSS. It adds and removes them physically from the DOM.
Confirm that fact using browser developer tools to inspect the DOM.
The top paragraph is in the DOM. The bottom, disused paragraph is not;
in its place is a comment about "template bindings" (more about that [later](#asterisk)).
When the condition is false, `NgIf` removes its host element from the DOM,
detaches it from DOM events (the attachments that it made),
detaches the component from Angular change detection, and destroys it.
The component and DOM nodes can be garbage-collected and free up memory.
### Why *remove* rather than *hide*?
A directive could hide the unwanted paragraph instead by setting its `display` style to `none`.
{@example 'structural-directives/ts/src/app/app.component.html' region='display-none'}
While invisible, the element remains in the DOM.
The difference between hiding and removing doesn't matter for a simple paragraph.
It does matter when the host element is attached to a resource intensive component.
Such a component's behavior continues even when hidden.
The component stays attached to its DOM element. It keeps listening to events.
Angular keeps checking for changes that could affect data bindings.
Whatever the component was doing, it keeps doing.
Although invisible, the component—and all of its descendant components—tie up resources.
The performance and memory burden can be substantial, responsiveness can degrade, and the user sees nothing.
On the positive side, showing the element again is quick.
The component's previous state is preserved and ready to display.
The component doesn't re-initialize—an operation that could be expensive.
So hiding and showing is sometimes the right thing to do.
But in the absence of a compelling reason to keep them around,
your preference should be to remove DOM elements that the user can't see
and recover the unused resources with a structural directive like `NgIf` .
**These same considerations apply to every structural directive, whether built-in or custom.**
Before applying a structural directive, you might want to pause for a moment
to consider the consequences of adding and removing elements and of creating and destroying components.
{@a ngcontainer}
{@a ng-container}
## Group sibling elements with <ng-container>
There's often a _root_ element that can and should host the structural directive.
The list element (`
`) is a typical host element of an `NgFor` repeater.
{@example 'structural-directives/ts/src/app/app.component.html' region='ngfor-li'}
When there isn't a host element, you can usually wrap the content in a native HTML container element,
such as a `
`, and attach the directive to that wrapper.
{@example 'structural-directives/ts/src/app/app.component.html' region='ngif'}
Introducing another container element—typically a `` or `
`—to
group the elements under a single _root_ is usually harmless.
_Usually_ ... but not _always_.
The grouping element may break the template appearance because CSS styles
neither expect nor accommodate the new layout.
For example, suppose you have the following paragraph layout.
{@example 'structural-directives/ts/src/app/app.component.html' region='ngif-span'}
You also have a CSS style rule that happens to apply to a `` within a `
`aragraph.
{@example 'structural-directives/ts/src/app/app.component.css' region='p-span'}
The constructed paragraph renders strangely.
The `p span` style, intended for use elsewhere, was inadvertently applied here.
Another problem: some HTML elements require all immediate children to be of a specific type.
For example, the `