Angular Material provides a rich set of UI components that follow Google’s Material Design guidelines, helping developers build modern, accessible, and responsive web applications faster. One of the most commonly used form components is the Material Checkbox, implemented using the mat-checkbox component.
In this tutorial, Angular Material Checkbox Example: mat-checkbox in Angular 21, you’ll learn how to use mat-checkbox with the latest Angular 21 and Angular Material. We’ll cover everything from basic usage to real-world scenarios such as handling checkbox states, binding values with forms, and improving accessibility.
By the end of this guide, you will be able to:
-
Add and configure Angular Material in an Angular 21 project
-
Use
mat-checkboxin templates with proper styling -
Bind checkbox values using template-driven and reactive forms
-
Handle change events and checkbox groups
-
Apply best practices for accessibility and UX
This tutorial is beginner-friendly but also includes practical patterns commonly used in production Angular applications, making it useful whether you’re just starting with Angular Material or upgrading an existing project to Angular 21.
Setting Up an Angular 21 Project and Installing Angular Material
Before using mat-checkbox, we need a fresh Angular 21 project with Angular Material properly installed and configured.
1. Prerequisites
Make sure you have the following installed:
-
Node.js (LTS recommended)
-
npm or pnpm
-
Angular CLI (latest)
Check your Angular CLI version:
ng version
If needed, update it:
npm install -g @angular/cli
2. Create a New Angular 21 Project
Create a new Angular project using the Angular CLI:
ng new angular-material-checkbox
During the setup:
-
Choose Yes for routing (optional but recommended)
-
Select CSS (or SCSS if you prefer)
Navigate into the project directory:
cd angular-material-checkbox
Start the development server to verify everything works:
ng serve
Open your browser at:
http://localhost:4200

3. Install Angular Material
Angular Material provides official UI components that work seamlessly with Angular 21.
Run the following command:
ng add @angular/material
During the installation:
-
Choose a prebuilt theme (e.g., Indigo/Pink)
-
Select Yes for typography styles
-
Select Yes for browser animations
The CLI will automatically:
-
Install Angular Material, CDK, and Animations
-
Update
angular.json -
Import
BrowserAnimationsModule
4. Verify Angular Material Installation
Open src/app/app.html and temporarily add:
<h1>Angular Material Checkbox Demo</h1>
<button mat-raised-button color="primary">Test Button</button>
If the button appears styled, Angular Material is installed correctly.
Basic Usage of mat-checkbox in Angular 21
Now that Angular Material is properly configured with standalone components and provideAnimations(), let’s start using the mat-checkbox component in real examples.
1. A Simple mat-checkbox
The most basic usage of mat-checkbox requires no additional configuration.
app.ts
import { Component, signal } from '@angular/core';
import { MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
imports: [MatCheckboxModule],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
protected readonly title = signal('angular-material-checkbox');
}
app.html
<h2>Basic Checkbox</h2>
<mat-checkbox> Subscribe to newsletter </mat-checkbox>
This renders a Material-styled checkbox with a label.
2. Setting the Initial State
You can control the initial state using the checked property.
<mat-checkbox [checked]="true"> Enable notifications </mat-checkbox>
Or bind it to a component property:
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
imports: [MatCheckboxModule, FormsModule],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
protected readonly title = signal('angular-material-checkbox');
notificationsEnabled = true;
}
<mat-checkbox [(ngModel)]="notificationsEnabled"> Enable notifications </mat-checkbox>
⚠️
ngModelrequiresFormsModule. We’ll cover forms properly in later sections.
3. Disabled Checkboxes
Disable a checkbox using the disabled attribute:
<mat-checkbox disabled>
Feature unavailable
</mat-checkbox>
Or dynamically:
<mat-checkbox [disabled]="isDisabled">
Dynamic disabled checkbox
</mat-checkbox>
4. Handling Change Events
Use the (change) event to react to user interaction.
<mat-checkbox (change)="onChange($event)">
Accept terms and conditions
</mat-checkbox>
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
imports: [MatCheckboxModule, FormsModule],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
protected readonly title = signal('angular-material-checkbox');
notificationsEnabled = true;
onChange(event: MatCheckboxChange) {
console.log('Checked:', event.checked);
}
}
5. Indeterminate State
Material checkboxes support an indeterminate state, useful for “Select All” patterns.
<mat-checkbox [indeterminate]="true">
Select all items
</mat-checkbox>
ℹ️ Indeterminate is a visual state only and does not affect
checked.
6. Accessibility Best Practices
-
Always provide a clear label
-
Use
aria-labelwhen the label is not visible -
Avoid relying solely on color for state indication
<mat-checkbox aria-label="Accept privacy policy"></mat-checkbox>
7. Summary
In this section, you learned how to:
-
Render a basic
mat-checkbox -
Set checked and disabled states
-
Handle change events
-
Use the indeterminate state
-
Follow basic accessibility practices
Binding mat-checkbox with Template-Driven and Reactive Forms
In real-world Angular applications, checkboxes are rarely used alone. They are usually part of a form, either template-driven or reactive. Angular Material’s mat-checkbox integrates seamlessly with both approaches.
In this section, you’ll learn how to bind mat-checkbox using standalone components in Angular 21.
1. Template-Driven Forms with mat-checkbox
Template-driven forms are simple and ideal for basic forms.
Import FormsModule
Since this is a standalone setup, import FormsModule directly into the component.
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
imports: [MatCheckboxModule, FormsModule],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
acceptTerms = false;
}
<h2>Template-Driven Form</h2>
<mat-checkbox [(ngModel)]="acceptTerms"> I accept the terms and conditions </mat-checkbox>
<p>Accepted: {{ acceptTerms }}</p>
Key Points
-
[(ngModel)]enables two-way data binding -
The checkbox state updates automatically
-
Ideal for small or simple forms
2. Reactive Forms with mat-checkbox
Reactive forms are recommended for complex forms, validation, and scalability.
Import ReactiveFormsModule
import { Component } from '@angular/core';
import { ReactiveFormsModule, FormControl, FormGroup } from '@angular/forms';
import { MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule, MatCheckboxModule],
template: `
<h2>Reactive Form</h2>
<form [formGroup]="form">
<mat-checkbox formControlName="subscribe">
Subscribe to newsletter
</mat-checkbox>
</form>
<pre>{{ form.value | json }}</pre>
`
})
export class App {
form = new FormGroup({
subscribe: new FormControl(false)
});
}
Using FormBuilder (Recommended)
import { FormBuilder } from '@angular/forms';
export class App {
form = this.fb.group({
subscribe: false
});
constructor(private fb: FormBuilder) {}
}
3. Checkbox Validation Example
You can require a checkbox to be checked (e.g. accept terms):
import { Componen } from '@angular/core';
import { FormBuilde, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
imports: [MatCheckboxModule, FormsModule, ReactiveFormsModule],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
form: any;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
acceptTerms: [false, Validators.requiredTrue]
});
}
}
<mat-checkbox formControlName="acceptTerms"> Accept terms and conditions </mat-checkbox>
@if (form.controls.acceptTerms.invalid && form.controls.acceptTerms.touched) {
<div>You must accept the terms</div>
}
4. Checkbox Groups (Multiple Options)
For multiple checkboxes, use a FormArray.
import { Component } from '@angular/core';
import { FormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
imports: [MatCheckboxModule, FormsModule, ReactiveFormsModule],
templateUrl: './app.html',
styleUrl: './app.css'
})
export class App {
form: any;
constructor(private fb: FormBuilder) {
this.form = this.fb.group({
features: this.fb.array([
this.fb.control(false),
this.fb.control(false),
this.fb.control(false)
])
});
}
}
<div formArrayName="features">
<mat-checkbox *ngFor="let ctrl of features.controls; let i = index"
[formControlName]="i">
Feature {{ i + 1 }}
</mat-checkbox>
</div>
get features() {
return this.form.get('features') as FormArray;
}
5. Template-Driven vs Reactive Forms
| Feature | Template-Driven | Reactive |
|---|---|---|
| Setup | Simple | More structured |
| Validation | Directive-based | Code-based |
| Scalability | Small forms | Large forms |
| Recommended | Quick demos | Production apps |
6. Summary
In this section, you learned how to:
-
Bind
mat-checkboxusingngModel -
Use
mat-checkboxwith reactive forms -
Validate required checkboxes
-
Build checkbox groups with
FormArray
Handling Checkbox Events and States (Change, Toggle, Indeterminate)
Beyond simple binding, mat-checkbox provides powerful APIs to react to user interaction and manage checkbox states. In this section, we’ll explore how to handle events and work with different checkbox states in Angular 21.
1. Handling the (change) Event
The (change) event fires whenever the checkbox value changes due to user interaction.
<mat-checkbox (change)="onCheckboxChange($event)">
Enable dark mode
</mat-checkbox>
import { Component } from '@angular/core';
import { MatCheckboxChange, MatCheckboxModule } from '@angular/material/checkbox';
@Component({
selector: 'app-root',
standalone: true,
imports: [MatCheckboxModule],
templateUrl: './app.component.html'
})
export class App {
onCheckboxChange(event: MatCheckboxChange) {
console.log('Checked:', event.checked);
}
}
When to Use (change)
-
Trigger side effects (API calls, logging)
-
React to user-initiated changes
-
Access the
checkedboolean safely
2. Programmatically Toggling a Checkbox
You can toggle a checkbox using component state or a template reference.
Toggle Using a Property
<mat-checkbox [(ngModel)]="isEnabled">
Feature enabled
</mat-checkbox>
<button mat-button (click)="isEnabled = !isEnabled">
Toggle Checkbox
</button>
Toggle Using @ViewChild
import { ViewChild } from '@angular/core';
import { MatCheckbox } from '@angular/material/checkbox';
@ViewChild(MatCheckbox) checkbox!: MatCheckbox;
toggle() {
this.checkbox.toggle();
}
<mat-checkbox>Manual toggle</mat-checkbox>
<button mat-button (click)="toggle()">Toggle</button>
⚠️ Use
ViewChildsparingly; state binding is usually preferred.
3. Understanding Checkbox States
mat-checkbox supports three visual states:
| State | Property | Description |
|---|---|---|
| Checked | checked |
The checkbox is selected |
| Unchecked | checked = false |
The checkbox is not selected |
| Indeterminate | indeterminate |
Partial selection |
4. Indeterminate State (Select All Pattern)
The indeterminate state is commonly used for “Select All” checkboxes.
Example: Select All Logic
items = [
{ name: 'Item 1', selected: false },
{ name: 'Item 2', selected: false },
{ name: 'Item 3', selected: false }
];
get allSelected() {
return this.items.every(item => item.selected);
}
get someSelected() {
return this.items.some(item => item.selected) && !this.allSelected;
}
toggleAll(checked: boolean) {
this.items.forEach(item => (item.selected = checked));
}
<mat-checkbox
[checked]="allSelected"
[indeterminate]="someSelected"
(change)="toggleAll($event.checked)">
Select All
</mat-checkbox>
<div *ngFor="let item of items">
<mat-checkbox [(ngModel)]="item.selected">
{{ item.name }}
</mat-checkbox>
</div>
5. Preventing Toggle Based on Conditions
You can prevent state changes dynamically.
<mat-checkbox
[checked]="isChecked"
(change)="canToggle ? isChecked = $event.checked : $event.source.checked = isChecked">
Conditional toggle
</mat-checkbox>
6. Accessibility Considerations
-
Use
(change)instead of(click)for keyboard support -
Avoid manual DOM manipulation
-
Always keep the visual and data state in sync
7. Summary
In this section, you learned how to:
-
Handle checkbox change events
-
Toggle checkboxes programmatically
-
Use and manage the indeterminate state
-
Build a “Select All” checkbox pattern
-
Control checkbox behavior safely
Styling and Theming mat-checkbox in Angular 21
Angular Material follows Material Design and uses a powerful theming system. In this section, you’ll learn how to style and theme mat-checkbox properly in Angular 21—from simple color tweaks to full custom themes.
1. Using Built-in Theme Colors
Angular Material checkboxes support predefined theme colors.
<mat-checkbox color="primary">Primary</mat-checkbox>
<mat-checkbox color="accent">Accent</mat-checkbox>
<mat-checkbox color="warn">Warn</mat-checkbox>
🎨 These colors come from your active Material theme.
2. Applying Custom Styles with CSS
You can style mat-checkbox using global styles or component styles.
Component-Level Styling
.custom-checkbox {
font-weight: 600;
margin-bottom: 12px;
}
<mat-checkbox class="custom-checkbox">
Custom styled checkbox
</mat-checkbox>
Styling the Checkbox Box (Advanced)
Angular Material uses MDC-based components, so styling requires deep selectors.
:host ::ng-deep .mdc-checkbox__background {
border-radius: 6px;
}
⚠️
::ng-deepis deprecated but still commonly used for Material overrides. Use sparingly.
3. Disabling Ripple Effect
You can disable the ripple animation per checkbox:
<mat-checkbox disableRipple>
No ripple effect
</mat-checkbox>
Or globally:
import { MAT_RIPPLE_GLOBAL_OPTIONS } from '@angular/material/core';
providers: [
{
provide: MAT_RIPPLE_GLOBAL_OPTIONS,
useValue: { disabled: true }
}
]
4. Creating a Custom Angular Material Theme
To fully customize colors, create a theme file.
src/styles.scss
@use '@angular/material' as mat;
$primary: mat.define-palette(mat.$indigo-palette);
$accent: mat.define-palette(mat.$pink-palette);
$warn: mat.define-palette(mat.$red-palette);
$theme: mat.define-light-theme((
color: (
primary: $primary,
accent: $accent,
warn: $warn
)
));
@include mat.all-component-themes($theme);
🎯
mat-checkboxwill automatically use these colors.
5. Dark Mode Support
Angular Material makes dark mode easy.
$dark-theme: mat.define-dark-theme((
color: (
primary: $primary,
accent: $accent,
warn: $warn
)
));
.dark-theme {
@include mat.all-component-colors($dark-theme);
}
<div class="dark-theme">
<mat-checkbox>Dark mode checkbox</mat-checkbox>
</div>
6. Density & Spacing
Angular Material supports density customization.
$theme: mat.define-light-theme((
color: (
primary: $primary,
accent: $accent
),
density: -1
));
Lower density = more compact UI.
7. Best Practices for Styling mat-checkbox
-
✅ Prefer theming over CSS overrides
-
❌ Avoid heavy
::ng-deepusage -
🎨 Keep checkbox styles consistent across the app
-
♿ Don’t reduce contrast below accessibility standards
8. Summary
In this section, you learned how to:
-
Apply built-in theme colors
-
Customize checkbox styles
-
Disable ripple effects
-
Create light and dark themes
-
Adjust density and spacing
Common Use Cases and Best Practices for mat-checkbox
The mat-checkbox component is simple on the surface, but it’s widely used in real-world applications for permissions, preferences, filters, and bulk actions. In this section, we’ll explore common use cases and best practices when working with mat-checkbox in Angular 21.
1. Accept Terms & Conditions
One of the most common checkbox use cases is requiring users to accept terms before proceeding.
this.form = this.fb.group({
acceptTerms: [false, Validators.requiredTrue]
});
<mat-checkbox formControlName="acceptTerms">
I accept the terms and conditions
</mat-checkbox>
<button mat-raised-button color="primary" [disabled]="form.invalid">
Continue
</button>
✅ Best Practice
-
Use
Validators.requiredTrue -
Disable submit actions until checked
2. User Preferences & Settings
Checkboxes are ideal for toggling user preferences.
<mat-checkbox [(ngModel)]="settings.emailNotifications">
Email notifications
</mat-checkbox>
<mat-checkbox [(ngModel)]="settings.smsAlerts">
SMS alerts
</mat-checkbox>
settings = {
emailNotifications: true,
smsAlerts: false
};
✅ Best Practice
-
Persist preferences via API or local storage
-
Reflect the saved state on load
3. Filter Lists with Checkboxes
Checkboxes are often used for filtering lists or search results.
<mat-checkbox (change)="toggleFilter('active', $event.checked)">
Active users
</mat-checkbox>
<mat-checkbox (change)="toggleFilter('admin', $event.checked)">
Admin users
</mat-checkbox>
filters = new Set<string>();
toggleFilter(filter: string, enabled: boolean) {
enabled ? this.filters.add(filter) : this.filters.delete(filter);
}
✅ Best Practice
-
Use debouncing for API-based filters
-
Keep filter state centralized
4. Select All / Bulk Actions
Checkboxes are essential for bulk selection in tables and lists.
<mat-checkbox
[checked]="allSelected"
[indeterminate]="someSelected"
(change)="toggleAll($event.checked)">
Select All
</mat-checkbox>
✅ Best Practice
-
Always support
indeterminate -
Clearly indicate partial selections
5. Permissions & Role Management
Checkboxes are commonly used in admin dashboards.
<mat-checkbox [(ngModel)]="permissions.read">Read</mat-checkbox>
<mat-checkbox [(ngModel)]="permissions.write">Write</mat-checkbox>
<mat-checkbox [(ngModel)]="permissions.delete">Delete</mat-checkbox>
permissions = {
read: true,
write: false,
delete: false
};
✅ Best Practice
-
Use reactive forms for complex permission matrices
-
Validate dependencies (e.g. write requires read)
6. Accessibility Best Practices
Always ensure checkboxes are accessible.
-
✔ Use descriptive labels
-
✔ Add
aria-labelwhen label text is hidden -
✔ Ensure sufficient color contrast
-
✔ Use
(change)instead of(click)
<mat-checkbox aria-label="Enable email notifications"></mat-checkbox>
7. Performance Tips
-
Import only
MatCheckboxModule, not all Material modules -
Avoid unnecessary change detection triggers
-
Prefer reactive forms in large forms
-
Use
trackBywhen rendering checkbox lists
8. Common Mistakes to Avoid
❌ Styling checkboxes with heavy ::ng-deep overrides
❌ Mixing ngModel and reactive forms in the same form
❌ Relying on click events instead of change
❌ Ignoring the indeterminate state for bulk actions
9. Summary
In this section, you learned:
-
Real-world use cases for
mat-checkbox -
Best practices for UX, accessibility, and performance
-
Common pitfalls to avoid in production apps
Troubleshooting Common mat-checkbox Issues in Angular 21
Even though mat-checkbox is easy to use, you may encounter issues related to configuration, forms, styling, or standalone setup. This section covers the most common problems and how to fix them in Angular 21.
1. Checkbox Not Rendering or Looks Unstyled
❌ Problem
The checkbox appears as plain HTML or doesn’t render at all.
✅ Solutions
-
Ensure Angular Material is installed:
ng add @angular/material -
Confirm the module is imported in the standalone component:
imports: [MatCheckboxModule] -
Verify a Material theme is included in
styles.scss
2. Ripple or Animation Not Working
❌ Problem
Ripple effects or transitions don’t appear.
✅ Solution
Make sure provideAnimations() is added in main.ts:
bootstrapApplication(AppComponent, {
providers: [provideAnimations()]
});
If animations are intentionally disabled, expect limited visuals.
3. ngModel Not Working with mat-checkbox
❌ Error
NG8002: Can't bind to 'ngModel' since it isn't a known property
✅ Solution
Import FormsModule in the standalone component:
imports: [FormsModule, MatCheckboxModule]
⚠️ Avoid mixing
ngModeland reactive forms in the same form.
4. Reactive Form Checkbox Not Updating
❌ Problem
Checkbox state doesn’t update the form value.
✅ Solutions
-
Ensure
ReactiveFormsModuleis imported -
Use
formControlName, not[checked] -
Initialize the control properly:
new FormControl(false)
5. Indeterminate State Not Resetting
❌ Problem
The checkbox stays indeterminate after user interaction.
✅ Solution
Manually control indeterminate:
toggleAll(checked: boolean) {
this.items.forEach(item => item.selected = checked);
}
Angular Material does not automatically reset the indeterminate state.
6. Styling Changes Not Applied
❌ Problem
CSS styles don’t affect the checkbox.
✅ Solutions
-
Use global styles for deep overrides
-
Prefer Material theming over CSS
-
Use
::ng-deeponly when necessary:
:host ::ng-deep .mdc-checkbox__background {
border-radius: 4px;
}
7. Checkbox Click Doesn’t Trigger Logic
❌ Problem
(click) event fires inconsistently.
✅ Solution
Use (change) instead:
<mat-checkbox (change)="onChange($event)"></mat-checkbox>
This ensures keyboard and screen reader compatibility.
8. Performance Issues with Many Checkboxes
❌ Problem
Large lists of checkboxes feel slow.
✅ Solutions
-
Use
trackBywith*ngFor -
Switch to reactive forms
-
Avoid heavy bindings inside loops
-
Use
OnPushchange detection
9. Console Warnings or Errors
Common Causes
-
Missing animations provider
-
Missing form module
-
Duplicate Material installations
-
Version mismatch
✅ Fix
Run:
ng version
Ensure Angular, Material, and CDK versions match.
10. Summary
In this section, you learned how to:
-
Fix rendering and styling issues
-
Resolve form binding problems
-
Handle indeterminate state correctly
-
Improve performance with many checkboxes
-
Debug common runtime errors
Conclusion and Next Steps
In this tutorial, Angular Material Checkbox Example: mat-checkbox in Angular 21, we explored how to use mat-checkbox effectively in modern Angular applications built with standalone components.
What You’ve Learned
You now know how to:
-
Set up an Angular 21 project with Angular Material
-
Configure animations using
provideAnimations() -
Use
mat-checkboxfor basic and advanced scenarios -
Bind checkboxes with template-driven and reactive forms
-
Handle checkbox events and states, including indeterminate
-
Style and theme checkboxes using Angular Material’s theming system
-
Apply best practices for accessibility, performance, and UX
-
Troubleshoot common
mat-checkboxissues
When to Use mat-checkbox
Use mat-checkbox when:
-
A user can select multiple options
-
You need a boolean or tri-state input
-
Accessibility and keyboard support are important
-
You want a consistent Material Design UI across your app
Avoid checkboxes when:
-
Only one option can be selected (use radio buttons instead)
-
A destructive action needs confirmation (use dialogs)
Final Tip
Always keep Angular and Angular Material versions in sync, import only the components you need, and rely on Material’s theming system instead of heavy CSS overrides.
You can find the full source on our GitHub.
If you don’t want to waste your time designing your front-end or your budget to spend by hiring a web designer, then Angular Templates is the best place to go. So, speed up your front-end web development with premium Angular templates. Choose your template for your front-end project here.
That's just the basics. If you need more deep learning about Angular, you can take the following cheap course:
- Angular - The Complete Guide (2025 Edition)
- Complete Angular Course 2025 - Master Angular in only 6 days
- Angular Deep Dive - Beginner to Advanced (Angular 20)
- Modern Angular 20 with Signals - The missing guide
- The Modern Angular Bootcamp
- Angular (Full App) with Angular Material, Angularfire & NgRx
- Angular Front End Development Beginner to Master 2025
- 30 Days of Angular: Build 30 Projects with Angular
- Angular 20 Full Course - Complete Zero to Hero Angular 20
- Angular Material In Depth (Angular 20)
🚀 Happy coding with Angular 21 and Angular Material!
