Skip to main content Skip to navigation Skip to search

A tree is a hierarchical component that gives users access to a hierarchical set of objects displayed in a the parent-child relationship.


Use a tree view to visually display hierarchical information. The user can expand, collapse, and select a tree node within a tree view.


Basic Tree

A basic tree provides a tree structure with named nodes and an arrow to expand and collapse child nodes.

Basic Tree

Basic Tree With Icons

A tree can include icons to represent the type of nodes within that group. Icons appear between the collapse/expand arrow and the parent node title.

Basic Tree

Checkbox Tree

A checkbox tree features checkboxes between the collapse/expand arrow and the name to indicate whether a node is selected. A parent node with children that are both selected and not selected is shown with an “indeterminate” state.

Checkbox trees should not be used together with icons for the nodes. As with icon trees, make sure to put checkboxes on all nodes of a checkbox tree. Do not alternate between types of trees in a checkbox tree.

Basic Tree


The styling of each piece of a tree node is consistent across the different types of trees.

Touch Targets

The dimensions of the expand/collapse arrow and the node title allow for a comfortable touch target allowing use with a mouse or a touch screen.
Tree view touch targets
Touch Targets are relevant even outside of a mobile form factor. Many new desktop environments, especially those running Windows, allow for the use of a touch screen and should be considered when designing your applications.


Common terminology that explains tree behavior.


Click on a node in the tree to either “highlight” it or navigate to its relative content.


Choose items to apply an action. For example, selecting a checkbox in the tree.

Expand / Collapse

Use the arrow to the left of a node to expand or collapse a node in the tree.

Interacting With Nodes

Expanding / Collapsing Nodes

To expand or collapse a parent node, the user clicks on the expand/collapse arrow. Clicking on the node item itself does not expand or collapse a node. It serves as a highlighting mechanism.

In read-only trees where highlighting is not an option, this pattern remains true for consistency.

Expand and collapse tree node

Highlighting Tree Nodes

To navigate to a content area based on a tree node or to highlight a tree node in order to take a subsequent action based on the selection, a user clicks on the node title itself.

Expand and collapse tree node

Interacting With Checkbox Trees

With a checkbox tree, a user is able to perform one or a combination of three actions by clicking on one of three distinct targets:

  1. Expanding and Collapsing: a user is able to perform this action by clicking on the expand / collapse arrow.
  2. Checking a Checkbox: this would require clicking on the checkbox itself to check or uncheck a treenode. This will also affect the status of the parent node’s checkbox.
  3. Highlighting Tree Node: a user can highlight a tree node by clicking on the name (label) of the tree node. This allows for the possibility of loading content based on selection to provide more information on a tree node.
Interacting with checkboxes

Loading Data

The way to load data within the tree is based on the scenario in which the tree is being used.

Load Parent Nodes First

With a dynamic tree, make sure to load the parent nodes first and then lazy load child nodes when requested.

A general goal to keep in mind is that you want to minimize the time a user needs to spend before their first interaction with the tree as well as every subsequent interaction afterwards.

Loading data

Code & Examples

Basic tree

A basic tree can be created by simply nesting clr-tree-node components at will. To pre-expand a node, you can use the [clrExpanded] input.

Please note that every tree requires to have root node to work properly, this is done by having clr-tree as root wrapper, please check the example below.
Basic Tree

Tracking expanded nodes

Use two-way binding [(clrExpanded)]="expanded" on the clrExpanded property to track when a node is expanded or collapsed.

Routing with a tree

Routing Tree

Use the .clr-treenode-link class to style content inside of a Tree Node as clickable. Indicate an active Tree Node with the .active class combined with the .clr-treenode-link class.

Generating a tree dynamically

When the tree structure is large and complex you can use iteration to generate nodes and child nodes based on the structure given to the ClrTree.

Dynamically Generated Tree

Tree element

Tree typeScript

Checkbox tree

Use checkbox when nodes of the tree need to be selected or unselected by users. There are three parts that are needed to implement a ClrTree with checkbox controls.

  1. Data structured in a tree hierarchy
  2. The correct declaration on the ClrTreeNode's that need to be selectable
  3. A ClrSelectedState for each node that is selectable
Checkbox Tree

Checkbox JSON

Checkbox element

Checkbox typeScript

Binding selection to a boolean

If you know a specific node can never become indeterminate, you probably want to use a boolean property on your node. As mentioned previously, [(clrSelected)] always outputs ClrSelectedState enum values, making two-way binding with a boolean problematic. The most straightforward solution is to use the de-sugarized syntax of the two-way binding , transforming the output to a boolean directly.

Checkbox Tree

Checkbox JSON

Binding element

Binding TypeScript

Recursive tree

If the data you are displaying is recursive or has an unknown depth, you can use our *clrRecursiveFor structural directive to recursively iterate over your data. It has the same syntax as *ngFor, and accepts an additional getChildren parameter that receives a node and should return its children. Please note that it needs to be used inside of a <clr-tree> to function properly.

Recursive Tree

Recursive element

Recursive TypeScript

Lazy loading child nodes

If your tree is too large to be fully build on initialization or getting the children of a node is an expensive operation like an HTTP request, you might want to lazy-load tree nodes, only loading the ones that are currently displayed. To lazy-load children for a simple tree component, you need to combine several features as follows:

  • Use our <clr-tree> root component, giving it a [clrLazy]="true" input
  • leverage our *clrIfExpanded structural directive, it only instantiates children when they are displayed
  • listen to the (clrIfExpandedChange) output to fetch the children's data
  • add a [clrLoading] boolean input to the node if fetching children is asynchronous, to display a spinner while waiting for the data to be loaded

Lazy tree element

Lazy tree TypeScript

Lazy-loading recursive trees

Lazy-loading data for recursive trees is actually the simplest case: as soon as you set [clrLazy]="true" on the parent <clr-tree>, the getChildren function will only be lazily called when a node becomes expanded, and supports both Promise and Observable return types if you need to fetch children asynchronously.

By default, recursive trees will pre-load on level ahead to know if the currently displayed nodes are expandable of not. If you do not want this behavior and have a way of knowing if a node is expandable without fetching its children, you can prevent the extra loading by using the [clrExpandable] boolean input on nodes based on your own condition.

Lazy-loading recursive tree element

Lazy-loading recursive tree TypeScript