Skip to content

Latest commit

 

History

History
247 lines (181 loc) · 14.9 KB

theming-your-components.md

File metadata and controls

247 lines (181 loc) · 14.9 KB

Theme your own components with Angular Material's theming system

You can use Angular Material's Sass-based theming system for your own custom components.

Note: The information on this page is specific to Material 3, for Material 2 information on how to theme your components see the Material 2 guide.

Reading values from a theme

As described in the theming guide, a theme is a Sass map that contains style values to customize components. Angular Material provides APIs for reading values from this data structure.

Reading tonal palette colors

To read a tonal palette color from the theme, use the get-theme-color function with three arguments:

Argument Description
$theme The M3 theme to read from.
$palette The name of the palette to read from. This can be any of the standard M3 palettes:
  • primary
  • secondary
  • tertiary
  • error
  • neutral
  • neutral-variant
$hue The hue number to read within the palette. This can be any of the standard hues:
  • 0
  • 10
  • 20
  • 30
  • 40
  • 50
  • 60
  • 70
  • 80
  • 90
  • 95
  • 99
  • 100

Reading color roles

To read a color role, use get-theme-color with two arguments:

Argument Description
$theme The M3 theme to read from.
$role The name of the color role. This can be any of the M3 color roles:
  • primary
  • on-primary
  • primary-container
  • on-primary-container
  • primary-fixed
  • primary-fixed-dim
  • on-primary-fixed
  • on-primary-fixed-variant
  • secondary
  • on-secondary
  • secondary-container
  • on-secondary-container
  • secondary-fixed
  • secondary-fixed-dim
  • on-secondary-fixed
  • on-secondary-fixed-variant
  • tertiary
  • on-tertiary
  • tertiary-container
  • on-tertiary-container
  • tertiary-fixed
  • tertiary-fixed-dim
  • on-tertiary-fixed
  • on-tertiary-fixed-variant
  • error
  • on-error
  • error-container
  • on-error-container
  • surface-dim
  • surface
  • surface-bright
  • surface-container-lowest
  • surface-container-low
  • surface-container
  • surface-container-high
  • surface-container-highest
  • on-surface
  • on-surface-variant
  • outline
  • outline-variant
  • inverse-surface
  • inverse-on-surface
  • inverse-primary
  • scrim
  • shadow

Reading the theme type

To read the theme type (light or dark), call get-theme-type with a single argument:

Argument Description
$theme The M3 theme to read from.

Reading typescale properties

To read a typescale property from the theme, call get-theme-typography with three arguments:

Argument Description
$theme The M3 theme to read from.
$level The typescale level. This can be any of the M3 typescale levels:
  • display-large
  • display-medium
  • display-small
  • headline-large
  • headline-medium
  • headline-small
  • title-large
  • title-medium
  • title-small
  • body-large
  • body-medium
  • body-small
  • label-large
  • label-medium
  • label-small
$property The CSS font property to get a value for. This can be one of the following CSS properties:
  • font (The CSS font shorthand, includes all font properties except letter-spacing)
  • font-family
  • font-size
  • font-weight
  • line-height
  • letter-spacing

Reading the density scale

To read the density scale (0, -1, -2, -3, -4, or -5) from the theme, call get-theme-density with a single argument:

Argument Description
$theme The M3 theme to read from.

Checking what dimensions are configured for a theme

Depending on how a theme was created, it may not have configuration data for all theming dimensions (base, color, typography, density). You can check if a theme has a configuration for a particular dimension by calling the theme-has Sass function, passing the theme and the dimension to check.

See the below example of checking the configured dimensions for a theme:

$theme: mat.define-theme(...);

$has-base: mat.theme-has($theme, base);
$has-color: mat.theme-has($theme, color);
$has-typography: mat.theme-has($theme, typography);
$has-density: mat.theme-has($theme, density);

Separating theme styles

Angular Material components each have a Sass file that defines mixins for customizing that component's color and typography. For example, MatButton has mixins for button-color and button-typography. Each mixin emits all color and typography styles for that component, respectively.

You can mirror this structure in your components by defining your own mixins. These mixins should accept an Angular Material theme, from which they can read color and typography values. You can then include these mixins in your application along with Angular Material's own mixins.

Step-by-step example

To illustrate participation in Angular Material's theming system, we can look at an example of a custom carousel component. The carousel starts with a single file, carousel.scss, that contains structural, color, and typography styles. This file is included in the styleUrls of the component.

// carousel.scss

.my-carousel {
  display: flex;
  font-family: serif;
}

.my-carousel-button {
  border-radius: 50%;
  color: blue;
}

Step 1: Extract theme-based styles to a separate file

To change this file to participate in Angular Material's theming system, we split the styles into two files, with the color and typography styles moved into mixins. By convention, the new file name ends with -theme. Additionally, the file starts with an underscore (_), indicating that this is a Sass partial file. See the Sass documentation for more information about partial files.

// carousel.scss

.my-carousel {
  display: flex;
}

.my-carousel-button {
  border-radius: 50%;
}
// _carousel-theme.scss

@mixin color($theme) {
  .my-carousel-button {
    color: blue;
  }
}

@mixin typography($theme) {
  .my-carousel {
    font-family: serif;
  }
}

Step 2: Use values from the theme

Now that theme theme-based styles reside in mixins, we can extract the values we need from the theme passed into the mixins.

// _carousel-theme.scss

@use 'sass:map';
@use '@angular/material' as mat;

@mixin color($theme) {
  .my-carousel-button {
    // Read the 50 hue from the primary color palette.
    color: mat.get-theme-color($theme, primary, 50);
  }
}

@mixin typography($theme) {
  .my-carousel {
    // Get the large headline font from the theme.
    font: mat.get-theme-typography($theme, headline-large, font);
  }
}

Step 3: Add a theme mixin

For convenience, we can add a theme mixin that includes both color and typography. This theme mixin should only emit the styles for each color and typography, respectively, if they have a config specified.

// _carousel-theme.scss

@use 'sass:map';
@use '@angular/material' as mat;

@mixin color($theme) {
  .my-carousel-button {
    // Read the 50 hue from the primary color palette.
    color: mat.get-theme-color($theme, primary, 50);
  }
}

@mixin typography($theme) {
  .my-carousel {
    // Get the large headline font from the theme.
    font: mat.get-theme-typography($theme, headline-large, font);
  }
}

@mixin theme($theme) {
  @if mat.theme-has($theme, color) {
    @include color($theme);
  }

  @if mat.theme-has($theme, typography) {
    @include typography($theme);
  }
}

Step 4: Include the theme mixin in your application

Now that you've defined the carousel component's theme mixin, you can include this mixin along with the other theme mixins in your application.

@use '@angular/material' as mat;
@use './path/to/carousel-theme' as carousel;

$my-theme: mat.define-theme((
  color: (
    theme-type: light,
    primary: mat.$red-palette,
  ),
  typography: (
    brand-family: 'Comic Sans',
    bold-weight: 900,
  ),
));

html {
  @include mat.all-component-themes($my-theme);
  @include carousel.theme($my-theme);
}