Overview for stepper

Angular Material's stepper provides a wizard-like workflow by dividing content into logical steps.

Material stepper builds on the foundation of the CDK stepper that is responsible for the logic that drives a stepped workflow. Material stepper extends the CDK stepper and has Material Design styling.

There are two stepper variants: horizontal and vertical. You can switch between the two using the orientation attribute.

Stepper overview
This example contains tests. Open in Stackblitz to run the tests.
Stepper vertical
This example contains tests. Open in Stackblitz to run the tests.

If a step's label is only text, then the label attribute can be used.

 Loading document... 

For more complex labels, add a template with the matStepLabel directive inside the mat-step.

 Loading document... 

For a horizontal mat-stepper it's possible to define the position of the label. end is the default value, while bottom will place it under the step icon instead of at its side. This behaviour is controlled by labelPosition property.

 Loading document... 

If you're using a horizontal stepper, you can control where the stepper's content is positioned using the headerPosition input. By default it's on top of the content, but it can also be placed under it.

Stepper header position
This example contains tests. Open in Stackblitz to run the tests.

There are two button directives to support navigation between different steps: matStepperPrevious and matStepperNext.

 Loading document... 

The linear attribute can be set on mat-stepper to create a linear stepper that requires the user to complete previous steps before proceeding to following steps. For each mat-step, the stepControl attribute can be set to the top level AbstractControl that is used to check the validity of the step.

There are two possible approaches. One is using a single form for stepper, and the other is using a different form for each step.

Alternatively, if you don't want to use the Angular forms, you can pass in the completed property to each of the steps which won't allow the user to continue until it becomes true. Note that if both completed and stepControl are set, the stepControl will take precedence.

When using a single form for the stepper, matStepperPrevious and matStepperNext have to be set to type="button" in order to prevent submission of the form before all steps are completed.

<form [formGroup]="formGroup">
  <mat-stepper formArrayName="formArray" linear>
    <mat-step formGroupName="0" [stepControl]="formArray.get([0])">
      ...
      <div>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
    <mat-step formGroupName="1" [stepControl]="formArray.get([1])">
      ...
      <div>
        <button mat-button matStepperPrevious type="button">Back</button>
        <button mat-button matStepperNext type="button">Next</button>
      </div>
    </mat-step>
    ...
  </mat-stepper>
</form>
<mat-stepper orientation="vertical" linear>
  <mat-step [stepControl]="formGroup1">
    <form [formGroup]="formGroup1">
      ...
    </form>
  </mat-step>
  <mat-step [stepControl]="formGroup2">
    <form [formGroup]="formGroup2">
      ...
    </form>
  </mat-step>
</mat-stepper>

If completion of a step in linear stepper is not required, then the optional attribute can be set on mat-step.

 Loading document... 

By default, steps are editable, which means users can return to previously completed steps and edit their responses. editable="false" can be set on mat-step to change the default.

 Loading document... 

By default, the completed attribute of a step returns true if the step is valid (in case of linear stepper) and the user has interacted with the step. The user, however, can also override this default completed behavior by setting the completed attribute as needed.

By default, the step headers will use the create and done icons from the Material design icon set via <mat-icon> elements. If you want to provide a different set of icons, you can do so by placing a matStepperIcon for each of the icons that you want to override. The index, active, and optional values of the individual steps are available through template variables:

 Loading document... 

Note that you aren't limited to using the mat-icon component when providing custom icons.

You can control the duration of the stepper's animation using the animationDuration input. If you want to disable the animation completely, you can do so by setting the properties to 0ms.

Stepper animations
This example contains tests. Open in Stackblitz to run the tests.

You can set the state of a step to whatever you want. The given state by default maps to an icon. However, it can be overridden the same way as mentioned above.

 Loading document... 

In order to use the custom step states, you must add the displayDefaultIndicatorType option to the global default stepper options which can be specified by providing a value for STEPPER_GLOBAL_OPTIONS in your application's root module.

@NgModule({
  providers: [
    {
      provide: STEPPER_GLOBAL_OPTIONS,
      useValue: { displayDefaultIndicatorType: false }
    }
  ]
})
Stepper with customized states
This example contains tests. Open in Stackblitz to run the tests.

If you want to show an error when the user moved past a step that hasn't been filled out correctly, you can set the error message through the errorMessage input and configure the stepper to show errors via the showError option in the STEPPER_GLOBAL_OPTIONS injection token. Note that since linear steppers prevent a user from advancing past an invalid step to begin with, this setting will not affect steppers marked as linear.

@NgModule({
  providers: [
    {
      provide: STEPPER_GLOBAL_OPTIONS,
      useValue: { showError: true }
    }
  ]
})
Stepper that displays errors in the steps
This example contains tests. Open in Stackblitz to run the tests.

By default, the stepper will render all of it's content when it's initialized. If you have some content that you want to defer until the particular step is opened, you can put it inside an ng-template with the matStepContent attribute.

Stepper lazy content rendering
This example contains tests. Open in Stackblitz to run the tests.

If your app supports a wide variety of screens and a stepper's layout doesn't fit a particular screen size, you can control its orientation dynamically to change the layout based on the viewport.

Stepper responsive
This example contains tests. Open in Stackblitz to run the tests.
Keyboard shortcut Action
Left Arrow Focus the previous step header.
Right Arrow Focus the next step header.
Enter Select the focused step.
Space Select the focused step.

Labels used by the stepper are provided through MatStepperIntl. Localization of these messages can be done by providing a subclass with translated values in your application root module.

@NgModule({
  imports: [MatStepperModule],
  providers: [
    {provide: MatStepperIntl, useClass: MyIntl},
  ],
})
export class MyApp {}
Stepper that uses the MatStepperIntl service
This example contains tests. Open in Stackblitz to run the tests.

The stepper is treated as a tabbed view for accessibility purposes, so it is given role="tablist" by default. The header of step that can be clicked to select the step is given role="tab", and the content that can be expanded upon selection is given role="tabpanel". aria-selected attribute of step header is automatically set based on step selection change.

The stepper and each step should be given a meaningful label via aria-label or aria-labelledby.

Prefer vertical steppers when building for small screen sizes, as horizontal steppers typically take up significantly more horizontal space thus introduce horizontal scrolling. Applications with multiple scrolling dimensions make content harder to consume for some users. See the Responsive Stepper section above for an example on building a stepper that adjusts its layout based on viewport size.

Steppers often contain forms and form controls. If validation errors inside of a stepper's form prevents moving to another step, make sure that your form controls communicate error messages to assistive technology. This helps the user know why they can't advance to another step. You can accomplish this by using <mat-error> with <mat-form-field>, or by using an ARIA live region.

When a step contains a forms validation error, MatStepper will display the error in the step's header if specified. See the Error State section for an example of a stepper with an error message. For non-linear steppers, you should use an ARIA live region to announce error messages when users navigate away from a step with an error message.

Azure & Blue theme selected.