Créez un design system Angular Material maintenable : palettes, tokens, thèmes clair/sombre et personnalisation scalable.
Installation Angular Material
Angular Material est la librairie UI officielle d'Angular. Depuis Angular 17, elle supporte nativement le Material Design 3 (M3) avec un système de tokens CSS.
ng add @angular/material
Le CLI te demande :
- Un thème préconçu (Indigo/Pink, Azure/Blue…) ou un thème personnalisé.
- Si tu souhaites activer la typographie globale Material.
- Si tu actives les animations (
BrowserAnimationsModule).
Le fichier généré src/styles.scss inclut automatiquement l'import Material et l'application du thème.
Tokens et palettes personnalisées
Avec M3, Angular Material utilise des tokens CSS (variables) pour toutes les couleurs, typographies et espacements. Tu définis une palette via define-theme().
// styles.scss
@use '@angular/material' as mat;
// Définir la palette couleur
$mon-theme: mat.define-theme((
color: (
theme-type: light,
primary: mat.$azure-palette,
tertiary: mat.$blue-palette
),
typography: (
brand-family: 'Manrope, sans-serif',
bold-weight: 700
),
density: (
scale: 0
)
));
html {
@include mat.all-component-themes($mon-theme);
}
Palettes disponibles
- Palettes M3 prédéfinies :
$red-palette,$green-palette,$azure-palette,$violet-palette… - Pour une palette totalement custom, utilise
mat.define-palette()avec tes propres valeurs HEX.
Thèmes clair et sombre
M3 rend le mode sombre trivial : il suffit de définir deux variantes du thème et de basculer sur prefers-color-scheme ou un attribut HTML.
// styles.scss
@use '@angular/material' as mat;
$theme-clair: mat.define-theme((
color: (theme-type: light, primary: mat.$azure-palette)
));
$theme-sombre: mat.define-theme((
color: (theme-type: dark, primary: mat.$azure-palette)
));
// Appliquer le thème clair par défaut
html {
@include mat.all-component-themes($theme-clair);
}
// Basculer en sombre via attribut data-theme="dark" ou media query
html[data-theme="dark"] {
@include mat.all-component-color-themes($theme-sombre);
}
@media (prefers-color-scheme: dark) {
html:not([data-theme="light"]) {
@include mat.all-component-color-themes($theme-sombre);
}
}
Pour basculer dynamiquement depuis Angular :
@Injectable({ providedIn: 'root' })
export class ThemeService {
private readonly darkMode = signal(false);
toggleTheme(): void {
this.darkMode.update(v => !v);
document.documentElement.setAttribute(
'data-theme',
this.darkMode() ? 'dark' : 'light'
);
}
}
Composants wrapper métier
Plutôt que d'utiliser directement mat-button partout, crée des composants wrapper qui encapsulent tes conventions (variante, taille, icone) et exposent une API simplifiée.
// af-button.component.ts
import { Component, Input } from '@angular/core';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
@Component({
selector: 'af-button',
standalone: true,
imports: [MatButtonModule, MatIconModule],
template: `
<button
mat-flat-button
[color]="color"
[disabled]="disabled"
[attr.aria-label]="label"
>
@if (icon) { <mat-icon>{{ icon }}</mat-icon> }
{{ label }}
</button>
`
})
export class AfButtonComponent {
@Input() label = '';
@Input() icon = '';
@Input() color: 'primary' | 'accent' | 'warn' = 'primary';
@Input() disabled = false;
}
Typographie et spacing
Angular Material expose des classes utilitaires pour la typographie M3. Applique-les directement sur tes éléments HTML sans créer de styles custom.
<!-- Niveaux typographiques M3 -->
<h1 class="mat-display-large">Titre principal</h1>
<h2 class="mat-headline-medium">Sous-titre</h2>
<p class="mat-body-large">Corps de texte standard</p>
<span class="mat-label-small">Libellé discret</span>
Pour le spacing, utilise la fonction SCSS mat.private-token() ou définit tes propres variables en cohérence avec la density scale :
// Density scale : 0 (défaut), -1, -2, -3
// -1 réduit légèrement les composants (boutons, inputs)
// Utile pour les tableaux denses ou dashboards
$theme-dense: mat.define-theme((
color: (theme-type: light, primary: mat.$azure-palette),
density: (scale: -2)
));
Accessibilité et contrastes
Angular Material respecte les critères WCAG 2.1 AA par défaut sur ses composants. Cependant, si tu personnalises les couleurs, tu dois valider les contrastes toi-même.
- Vérifier le ratio de contraste texte/fond avec l'outil WebAIM Contrast Checker — minimum 4.5:1 pour le texte normal.
- Tester la navigation au clavier sur chaque composant interactif (bouton, input, dialog, menu).
- Ne pas supprimer le focus ring de Material — il est essentiel pour les utilisateurs clavier.
- Ajouter
aria-labelsur les icônes sans texte visible (<mat-icon aria-label="Fermer">). - Utiliser
mat-erroretmat-hintdans les formulaires — ils sont lus automatiquement par les lecteurs d'écran. - Tester avec un mode de contraste élevé (Windows High Contrast Mode) — Material 3 le supporte nativement.