diff --git a/docs/src/app/pages/system-variables/index.ts b/docs/src/app/pages/system-variables/index.ts deleted file mode 100644 index cd7ebb8992f0..000000000000 --- a/docs/src/app/pages/system-variables/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -export * from './system-variables'; diff --git a/docs/src/app/pages/system-variables/system-variables.html b/docs/src/app/pages/system-variables/system-variables.html deleted file mode 100644 index 613e900b60d2..000000000000 --- a/docs/src/app/pages/system-variables/system-variables.html +++ /dev/null @@ -1,242 +0,0 @@ -

- Angular Material components depend on system variables defined as CSS variables through the - material.theme - Sass mixin. This page provides guidance and documentation for using these variables to - customize components. -

- -

Colors

- -

- Material Design uses color to create accessible, personal color schemes - that communicate your product's hierarchy, state, and brand. See Material - Design's Color System - page to learn more about its use and purpose. -

-

- The following colors are the most often used in Angular Material components. Use these - colors and follow their uses to add theme colors to your application's custom components. -

- -
-
-
-
Primary
-
--mat-sys-primary
-
-
-

- The most common color used by Angular Material components to - participate in the application theme. -

-

- Examples include the background color - of filled buttons, the icon color of selected radio buttons, and the - outline color of form fields. -

-

- Use the color --mat-sys-on-primary for - icons, text, and other visual elements placed on a primary background. This - color is calculated to be optimal for accessibility and legibility. -

-
-
- -
-
-
Surface
-
--mat-sys-surface
-
-
-

- A low-emphasis background color that provides a clear contrast for - both light and dark themes and their varied theme colors. -

-

- Examples include the background color of the application and most - components such as the dialog, card, table, and more. -

-

- Use the color --mat-sys-on-surface for - icons, text, and other visual elements placed on a surface background. This - color is calculated to be optimal for accessibility and legibility. -

-
-
- -
-
-
Error
-
--mat-sys-error
-
-
-

- High-contrast color meant to alert the user to attract immediate attention. -

-

- Examples include the background color of the badge and the text color of invalid - form fields inputs. -

-

- Use the color --mat-sys-on-error for - icons, text, and other visual elements placed on an error background. This - color is calculated to be optimal for accessibility and legibility. -

-
-
- -
-
-
Outline
-
--mat-sys-outline
-
-
-

- Used for borders and dividers to help provide visual separation between - and around elements. -

-

- Examples include the color of the divider and border color of an outlined - form field. -

-

- Use the color --mat-sys-outline-variant for a less - prominent outline. -

-
-
-
- - - Other available colors - -

- These colors are less commonly used in Angular Material components but - are available for adding color variety and creating additional emphasis - to components. -

-

- Colors may be paired with a --mat-sys-on- variable - that should be used for text and icons placed within a filled container. -

- -

Alternative Theme Colors

- - - -

Surface Colors

- -

- The following colors should be used for backgrounds and large, - low-emphasis areas of the screen. -

- -

- Containers filled with a surface color should apply the - --mat-sys-on-surface color to text - and icons placed within. -

- - - -

Fixed Colors

- -

- These colors are the same for both light and dark themes. They are unused - by any Angular Material components. -

- - - -
- -

Typography

- -

- There are five categories of font types defined by Material Design: body, display, headline, - label, and title. Each category has three sizes: small, medium, and large. -

-

- Learn more about how these categories and their sizes should be used in your application by - visiting Material Design's - Typography documentation. -

- - -@for (category of ['body', 'display', 'headline', 'label', 'title']; track $index) { -
-
{{category}}
- @for (size of ['small', 'medium', 'large']; track $index) { -
-
-
--mat-sys-{{category}}-{{size}}
-
-
Lorem ipsum dolor
-
- } -
-} - -

- Each system variable can be applied to the "font" CSS style. Additionally, the parts of the variable definition - can be accessed individually by appending the keywords "font", "line-height", "size", "tracking", and "weight". -

-

- For example, the values for medium body text may be defined as follows: -

-
---mat-sys-body-medium: 400 0.875rem / 1.25rem Roboto, sans-serif;
---mat-sys-body-medium-font: Roboto, sans-serif;
---mat-sys-body-medium-line-height: 1.25rem;
---mat-sys-body-medium-size: 0.875rem;
---mat-sys-body-medium-tracking: 0.016rem;
---mat-sys-body-medium-weight: 400;
-
- -

Elevation

- -

- Material Design provides six levels of elevation that can be used to provide - a sense of depth and organization to an application's UI. Learn more at Material Design's - Elevation guide. -

- -

- These levels are defined as CSS box-shadow values that can be styled to an element. -

- -@for (level of [0, 1, 2, 3, 4, 5]; track $index) { -
- box-shadow: var(--mat-sys-level{{level}}) -
-} - -

Overrides

- -

- The mat.theme-overrides mixin - can be included to emit different definitions for the system variables and - override the definitions emitted from mat.theme. -

- -
- This example container has several system variables overridden by including the - following Sass code: - -
-  @include mat.theme-overrides((
-    primary: #ebdcff,
-    on-primary: #230f46,
-    body-medium: 500 1.15rem/1.3rem Arial,
-    corner-large: 32px,
-    level3: 0 4px 6px 1px var(--mat-sys-surface-dim),
-  ));
-
diff --git a/docs/src/app/pages/system-variables/system-variables.scss b/docs/src/app/pages/system-variables/system-variables.scss deleted file mode 100644 index 87193de7efe4..000000000000 --- a/docs/src/app/pages/system-variables/system-variables.scss +++ /dev/null @@ -1,196 +0,0 @@ -@use '@angular/material' as mat; - -:host { - display: block; - max-width: 1000px; -} - -h1 { - font: var(--mat-sys-title-large); - font-size: 28px; - padding-top: 32px; -} - -h2 { - font: var(--mat-sys-title-large); -} - -a { - color: var(--mat-sys-primary); -} - -.demo-warn { - background: var(--mat-sys-error-container); - color: var(--mat-sys-on-error-container); - border: 1px solid var(--mat-sys-outline-variant); - border-radius: var(--mat-sys-corner-extra-small); - padding: 8px; -} - -.demo-group { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: 24px; - margin-top: 24px; -} - -@media (max-width: 1000px) { - .demo-group { grid-template-columns: auto;} -} - -.demo-color-container { - border-radius: var(--mat-sys-corner-small); - display: inline-block; - font: var(--mat-sys-body-medium); - vertical-align: top; -} - -.demo-heading { - color: var(--mat-sys-on-primary); - background: var(--mat-sys-primary); - border: 1px solid var(--mat-sys-outline); - border-top-right-radius: var(--mat-sys-corner-small); - border-top-left-radius: var(--mat-sys-corner-small); - border-bottom: none; - padding: 16px; - display: flex; - align-items: center; - justify-content: space-between; -} - -.demo-name { - font: var(--mat-sys-title-medium); -} - -.demo-variable { - font: var(--mat-sys-title-small); - font-family: monospace; - text-align: right; -} - -.demo-description { - border: 1px solid var(--mat-sys-outline); - border-bottom-right-radius: var(--mat-sys-corner-small); - border-bottom-left-radius: var(--mat-sys-corner-small); - padding: 0 16px; -} - -.demo-code { - font-family: monospace; -} - -.demo-surface-variable { - display: inline-block; - font-family: monospace; - background: var(--mat-sys-primary-container); - color: var(--mat-sys-on-primary-container); - padding: 2px 6px; - margin: 0 2px; - border-radius: 4px; -} - -mat-expansion-panel { - margin-top: 24px; - overflow: visible; - @include mat.expansion-overrides(( - 'container-text-font': var(--mat-sys-body-medium-font), - 'container-text-size': var(--mat-sys-body-medium-size), - 'container-text-weight': var(--mat-sys-body-medium-weight), - 'container-text-line-height': var(--mat-sys-body-medium-line-height), - 'container-text-tracking': var(--mat-sys-body-medium-tracking), - )); -} - -.demo-compact-color-container { - border-radius: var(--mat-sys-corner-small); - border: 1px solid var(--mat-sys-outline); - overflow: hidden; // Hide child heading background color - margin-top: 24px; - - .demo-heading { - border: none; - border-radius: 0; - - &:not(:nth-child(1)) { - border-top: 1px solid var(--mat-sys-outline); - } - } - - .demo-variables { - text-align: end; - } -} - -.demo-typography-group { - border: 1px solid var(--mat-sys-outline); - border-radius: var(--mat-sys-corner-small); - margin-top: 40px; - overflow: hidden; -} - -.demo-typography-title { - text-transform: capitalize; - font: var(--mat-sys-title-medium); - padding: 16px; - border-bottom: 1px solid var(--mat-sys-outline); - background: var(--mat-sys-primary-container); - color: var(--mat-sys-on-primary-container); -} - -.demo-typography-variable { - min-width: 240px; -} - -.demo-typography-example { - padding: 16px; - display: flex; - align-items: baseline; - border-top: 1px solid var(--mat-sys-outline-variant); - - &:nth-child(1) { - border: none; - } - .demo-surface-variable { - margin-right: 16px; - } -} - -.demo-typography-text { - display: inline-block; -} - -.demo-elevation { - height: 40px; - width: 300px; - margin: 32px 0; - display: flex; - align-items: center; - justify-content: center; - background: var(--mat-sys-surface-container); - color: var(--mat-sys-on-surface); - border-radius: var(--mat-sys-corner-extra-small); -} - -.demo-code-block { - background: var(--mat-sys-surface-container-low); - padding: 16px; - border-radius: var(--mat-sys-corner-small); - border: 1px solid var(--mat-sys-outline); -} - -.demo-overrides { - background-color: var(--mat-sys-primary); - color: var(--mat-sys-on-primary); - font: var(--mat-sys-body-medium); - border-radius: var(--mat-sys-corner-small); - box-shadow: var(--mat-sys-level3); - padding: 16px; - - @include mat.theme-overrides(( - primary: #ebdcff, - on-primary: #230f46, - body-medium: 500 1.15rem/1.3rem Arial, - corner-large: 32px, - level3: 0 4px 6px 1px var(--mat-sys-surface-dim), - )); -} diff --git a/docs/src/app/pages/system-variables/system-variables.ts b/docs/src/app/pages/system-variables/system-variables.ts deleted file mode 100644 index e5b17ffb9cf9..000000000000 --- a/docs/src/app/pages/system-variables/system-variables.ts +++ /dev/null @@ -1,162 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import {ChangeDetectionStrategy, Component, input} from '@angular/core'; -import {MatExpansionPanel, MatExpansionPanelHeader} from '@angular/material/expansion'; - -interface Color { - name: string; - background: string; - text: string; - hideText?: boolean; -} - -@Component({ - selector: 'theme-demo-colors', - template: ` -
- @for (color of colors(); track $index) { -
-
{{color.name}}
-
-
{{color.background}}
- @if (!color.hideText) { -
{{color.text}}
- } -
-
- } -
- `, - styleUrl: 'system-variables.scss', - changeDetection: ChangeDetectionStrategy.OnPush, -}) -export class ThemeDemoColors { - colors = input(); -} - -@Component({ - selector: 'app-system-variables', - templateUrl: './system-variables.html', - styleUrls: ['./system-variables.scss'], - imports: [MatExpansionPanel, MatExpansionPanelHeader, ThemeDemoColors], -}) -export class SystemVariables { - alternativeThemeColors: Color[] = [ - { - name: 'Primary Container', - background: '--mat-sys-primary-container', - text: '--mat-sys-on-primary-container', - }, - { - name: 'Secondary', - background: '--mat-sys-secondary', - text: '--mat-sys-on-secondary', - }, - { - name: 'Secondary Container', - background: '--mat-sys-secondary-container', - text: '--mat-sys-on-secondary-container', - }, - { - name: 'Tertiary', - background: '--mat-sys-tertiary', - text: '--mat-sys-on-tertiary', - }, - { - name: 'Tertiary Container', - background: '--mat-sys-tertiary-container', - text: '--mat-sys-on-tertiary-container', - }, - { - name: 'Error Container', - background: '--mat-sys-error-container', - text: '--mat-sys-on-error-container', - }, - ]; - - surfaceColors: Color[] = [ - { - name: 'Surface Dim', - background: '--mat-sys-surface-dim', - text: '--mat-sys-on-surface', - hideText: true, - }, - { - name: 'Surface Bright', - background: '--mat-sys-surface-bright', - text: '--mat-sys-on-surface', - hideText: true, - }, - { - name: 'Surface Container Lowest', - background: '--mat-sys-surface-container-lowest', - text: '--mat-sys-on-surface', - hideText: true, - }, - { - name: 'Surface Container Low', - background: '--mat-sys-surface-container-low', - text: '--mat-sys-on-surface', - hideText: true, - }, - { - name: 'Surface Container', - background: '--mat-sys-surface-container', - text: '--mat-sys-on-surface', - hideText: true, - }, - { - name: 'Surface Container High', - background: '--mat-sys-surface-container-high', - text: '--mat-sys-on-surface', - hideText: true, - }, - { - name: 'Surface Container Highest', - background: '--mat-sys-surface-container-highest', - text: '--mat-sys-on-surface', - hideText: true, - }, - ]; - - fixedColors: Color[] = [ - { - name: 'Primary Fixed', - background: '--mat-sys-primary-fixed', - text: '--mat-sys-on-primary-fixed', - }, - { - name: 'Primary Fixed Dim', - background: '--mat-sys-primary-fixed-dim', - text: '--mat-sys-on-primary-fixed', - }, - { - name: 'Secondary Fixed', - background: '--mat-sys-secondary-fixed', - text: '--mat-sys-on-secondary-fixed', - }, - { - name: 'Secondary Fixed Dim', - background: '--mat-sys-secondary-fixed-dim', - text: '--mat-sys-on-secondary-fixed', - }, - { - name: 'Tertiary Fixed', - background: '--mat-sys-tertiary-fixed', - text: '--mat-sys-on-tertiary-fixed', - }, - { - name: 'Tertiary Fixed Dim', - background: '--mat-sys-tertiary-fixed-dim', - text: '--mat-sys-on-tertiary-fixed', - }, - ]; -} diff --git a/docs/src/app/routes.ts b/docs/src/app/routes.ts index af7844550f20..fb28a39e315d 100644 --- a/docs/src/app/routes.ts +++ b/docs/src/app/routes.ts @@ -57,10 +57,10 @@ export const MATERIAL_DOCS_ROUTES: Routes = [ path: 'cdk/drag-drop/:tab', redirectTo: externalRedirect('https://angular.dev/guide/drag-drop'), }, + {path: 'guide/system-variables', redirectTo: '/guide/theming-your-components'}, // In v19, the theming system became based on system variables and the mat.theme mixin. // The following guides were consolidated into the main theming guide, which redirects // users to v18 docs if they are looking for this content. - {path: 'guide/theming-your-components', redirectTo: '/guide/theming'}, {path: 'guide/typography', redirectTo: '/guide/theming'}, {path: 'guide/customizing-component-styles', redirectTo: '/guide/theming'}, {path: 'guide/elevation', redirectTo: '/guide/theming'}, diff --git a/docs/src/app/shared/guide-items/guide-items.ts b/docs/src/app/shared/guide-items/guide-items.ts index feb5aac17361..0ef4cd047d5b 100644 --- a/docs/src/app/shared/guide-items/guide-items.ts +++ b/docs/src/app/shared/guide-items/guide-items.ts @@ -7,7 +7,6 @@ */ import {Injectable} from '@angular/core'; -import {SystemVariables} from '../../pages/system-variables'; import {ComponentType} from '@angular/cdk/portal'; export interface GuideItem { @@ -24,12 +23,6 @@ const GUIDES: GuideItem[] = [ document: '/docs-content/guides/getting-started.md.html', overview: 'Add Angular Material to your project!', }, - { - id: 'schematics', - name: 'Schematics', - document: '/docs-content/guides/schematics.md.html', - overview: 'Use schematics to quickly generate views with Material Design components.', - }, { id: 'theming', name: 'Theming Angular Material', @@ -37,10 +30,16 @@ const GUIDES: GuideItem[] = [ overview: "Customize your application with Angular Material's theming system.", }, { - id: 'system-variables', - name: 'System Variables', - document: SystemVariables, - overview: 'Understand the system variables available to use in your application.', + id: 'theming-your-components', + name: 'Theming your components', + document: '/docs-content/guides/theming-your-components.md.html', + overview: 'Applying Angular Material theming to your own components', + }, + { + id: 'schematics', + name: 'Schematics', + document: '/docs-content/guides/schematics.md.html', + overview: 'Use schematics to quickly generate views with Material Design components.', }, { id: 'creating-a-custom-form-field-control', diff --git a/docs/src/styles.scss b/docs/src/styles.scss index aa13d737aeee..eb3ebfd8d76c 100644 --- a/docs/src/styles.scss +++ b/docs/src/styles.scss @@ -9,16 +9,19 @@ html { background-color: var(--mat-sys-surface); color: var(--mat-sys-on-surface); - @include mat.theme(( - color: ( - theme-type: light, - primary: mat.$azure-palette, - tertiary: mat.$blue-palette, - ), - typography: Roboto, - density: 0, - )); + @include mat.theme( + ( + color: ( + theme-type: light, + primary: mat.$azure-palette, + tertiary: mat.$blue-palette, + ), + typography: Roboto, + density: 0, + ) + ); + @include mat.system-classes(); @include cdk.a11y-visually-hidden(); } diff --git a/docs/src/styles/_tables.scss b/docs/src/styles/_tables.scss index c9084474be8b..cf41ac2373ce 100644 --- a/docs/src/styles/_tables.scss +++ b/docs/src/styles/_tables.scss @@ -10,7 +10,6 @@ width: 100%; } - // Styles specific only to the table inside markdown. .docs-markdown > table { font-size: 14px; @@ -18,10 +17,10 @@ // Code tends to wrap inside tables which doesn't look great with the background color. code { background: transparent; + padding: 0; } } - .docs-api th, .docs-markdown > table th { max-width: 100px; diff --git a/guides/theming-your-components.md b/guides/theming-your-components.md new file mode 100644 index 000000000000..93a8b925673f --- /dev/null +++ b/guides/theming-your-components.md @@ -0,0 +1,787 @@ + + +# Theming your components + +Angular Material provides two approaches to styling custom components to match the application's +theme: + +- **CSS variables** included by `mat.theme()`. These are prefixed with `--mat-sys` and can be used + in your component stylesheets to match the theme and design for your application. +- **Utility classes** included by `mat.system-classes()`. These utility classes wrap the CSS variables + and allow you to apply theme styles directly from your component templates. + +Both approaches are valid ways to ensure your application is consistently designed alongside Angular +Material's components. Also, by using the system tokens for applying color to your application, +you will automatically support both light and dark mode versions that can be set using the +`color-scheme` CSS property. + +This guide will focus on showing the implementation for the utility classes as a means to show +both the available classes and the underlying system token CSS variables used. + +If your application is based on the older Material Design 2 APIs with theme configs, you can still +use these CSS variables and classes. See +the [Material Design 2 Support](#material-design-2-support) section below to learn how to enable +them. + +## Colors + +Material Design uses color to create accessible, personal color schemes that communicate your +product's hierarchy, state, and brand. See Material +Design's [Color Roles](https://m3.material.io/styles/color/roles) page to learn more +about its use and purpose. + +Using the system tokens makes it easy to match the same color scheme of your application's theme. It +also makes it easy to ensure your application can correctly handle both light and dark mode +automatically. + +### Background + +

Primary

+ +A primary background is useful for key components across the UI, such as buttons that have greater +importance on the page. In Angular Material, this is used for the selected date in a datepicker, the +handle of a slider, and the background of a checkbox. + +Text and icons should use the `on-primary` system color token ensure good contrast and +accessibility (see [Text](#text) below). + +
+.mat-bg-primary {
+  background-color: var(--mat-sys-primary);
+}
+
+ +A primary container color background is useful for filling components that should stand out on a +surface. In Angular Material, this is used for the container of a floating action button. + +
+.mat-bg-primary-container {
+  background-color: var(--mat-sys-primary-container);
+}
+
+ +

Secondary

+ +A secondary background is useful for less prominent components in the UI that have a different color +scheme than the primary. + +Text and icons should use the `on-secondary` system color token ensure good contrast and +accessibility (see [Text](#text) below). + +
+.mat-bg-secondary {
+  background-color: var(--mat-sys-secondary);
+}
+
+ +A secondary container color background is useful for components that need less emphasis than +secondary, such as filter chips. In Angular Material, this is used for selected items in a list and +the container of a tonal button. + +
+.mat-bg-secondary-container {
+  background-color: var(--mat-sys-secondary-container);
+}
+
+ +

Error

+ +An error background is useful for indicating an error state, such as an invalid text field, or for +the background of an important notification. In Angular Material, this is used for the background of +a badge. + +Text and icons should use the `on-error` system color token ensure good contrast and accessibility ( +see [Text](#text) below). + +
+.mat-bg-error {
+  background-color: var(--mat-sys-error);
+}
+
+ +An error container color background is useful for components that need less emphasis than error, +such as a container for error text. + +
+.mat-bg-error-container {
+  background-color: var(--mat-sys-error-container);
+}
+
+ +

Surfaces

+ +When using surface backgrounds, text and icons should use the `on-surface` or `on-surface-variant` +system color tokens ensure good contrast and accessibility (see [Text](#text) below). + +A surface background is useful for general surfaces of components. In Angular Material, this is used +for the background of many components, like tables, dialogs, menus, and toolbars. + +
+.mat-bg-surface {
+  background-color: var(--mat-sys-surface);
+}
+
+ +A surface variant background is useful for surfaces that need to stand out from the main surface +color. In Angular Material, this is used for the background of a filled form field and the track of +a progress bar. + +
+.mat-bg-surface-variant {
+  background-color: var(--mat-sys-surface-variant);
+}
+
+ +The "highest" surface container background is useful for surfaces that need the most emphasis +against the main surface color. In Angular Material, this is used for the background of a filled +card. + +
+.mat-bg-surface-container-highest {
+  background-color: var(--mat-sys-surface-container-highest);
+}
+
+ +A "high" surface container background is useful for surfaces that need more emphasis against the +main surface color. In Angular Material, this is used for the background of a datepicker. + +
+.mat-bg-surface-container-high {
+  background-color: var(--mat-sys-surface-container-high);
+}
+
+ +A surface container background is useful for surfaces that need to stand out from the main surface +color. In Angular Material, this is used for the background of a menu. + +
+.mat-bg-surface-container {
+  background-color: var(--mat-sys-surface-container);
+}
+
+ +A "low" surface container background is useful for surfaces that need less emphasis against the main +surface color. In Angular Material, this is used for the background of a bottom sheet. + +
+.mat-bg-surface-container-low {
+  background-color: var(--mat-sys-surface-container-low);
+}
+
+ +The "lowest" surface container background is useful for surfaces that need the least emphasis +against the main surface color. + +
+.mat-bg-surface-container-lowest {
+  background-color: var(--mat-sys-surface-container-lowest);
+}
+
+ +An inverse surface color background is useful for making elements stand out against the default +color scheme. It is good for temporary notifications that appear above your content. In Angular +Material, this is used for the background of a snackbar and a tooltip. + +When using the inverse surface background, text and icons should use the `inverse-on-surface` system +color token ensure good contrast and accessibility (see [Text](#text) below). + +
+.mat-bg-inverse-surface {
+  background-color: var(--mat-sys-inverse-surface);
+}
+
+ +

Disabled

+ +A disabled color background is useful for disabled components. In Angular Material, this is used for +components generally filled with the primary color but are currently disabled. + +In Angular Material, text and icons often use a 38% color mix of the surface color to strongly +convey +the disabled state. This is described with the `mat-text-disabled` class in [Text](#text)). + +
+.mat-bg-disabled {
+  background-color: color-mix(in srgb, var(--mat-sys-on-surface) 12%, transparent);
+}
+
+ +### Text + +

Primary

+ +Use the primary color for text that needs to stand out. In Angular Material, this is used for the +text of a text button and the selected tab label. + +
+.mat-text-primary {
+  color: var(--mat-sys-primary);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Secondary

+ +Use the secondary color for text that needs to stand out apart from the main theme color. + +
+.mat-text-secondary {
+  color: var(--mat-sys-secondary);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Error

+ +Use the error color for text that indicates an issue or warning, such as validation messages. In +Angular Material, this is used for the error text in a form field. + +
+.mat-text-error {
+  color: var(--mat-sys-error);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Disabled

+ +Use the disabled text color for elements that are disabled on either the disabled or surface +background. + +
+.mat-text-disabled {
+  color: color-mix(in srgb, var(--mat-sys-on-surface) 38%, transparent);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Surface Variant

+ +Use the on-surface-variant color for text that should have a lower emphasis than the surrounding +text. This can include subheading, captions, and hint text. + +
+.mat-text-on-surface-variant {
+  color: var(--mat-sys-on-surface-variant);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Primary

+ +Use the on-primary color for text and icons appearing on primary backgrounds to ensure good contrast +and accessibility. + +
+.mat-text-on-primary {
+  color: var(--mat-sys-on-primary);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Primary Container

+ +Use the on-primary-container color for text and icons appearing on primary-container backgrounds to +ensure good contrast and accessibility. + +
+.mat-text-on-primary-container {
+  color: var(--mat-sys-on-primary-container);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Secondary

+ +Use the on-secondary color for text and icons appearing on secondary backgrounds to ensure good +contrast and accessibility. + +
+.mat-text-on-secondary {
+  color: var(--mat-sys-on-secondary);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Secondary Container

+ +Use the on-secondary-container color for text that contrasts well against a secondary-container +background. + +
+.mat-text-on-secondary-container {
+  color: var(--mat-sys-on-secondary-container);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Error

+ +Use the on-error color for text that contrasts well against an error background. + +
+.mat-text-on-error {
+  color: var(--mat-sys-on-error);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Error Container

+ +Use the on-error-container color for text that contrasts well against an error-container background. + +
+.mat-text-on-error-container {
+  color: var(--mat-sys-on-error-container);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

On Surface

+ +Use the on-surface color for text that contrasts well against a surface background. + +
+.mat-text-on-surface {
+  color: var(--mat-sys-on-surface);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Inverse On Surface

+ +Use the inverse-on-surface color for text that contrasts well against an inverse-surface background. + +
+.mat-text-inverse-on-surface {
+  color: var(--mat-sys-inverse-on-surface);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +## Typography + +Material Design provides five categories of font types: body, display, headline, label, and title. +Each category has three sizes: small, medium, and large. Learn more about how these categories and +their sizes should be used in your application by visiting Material +Design's [Applying Type](https://m3.material.io/styles/typography/applying-type) documentation. + +

Body

+ + +The small body typeface is useful for captions. In Angular Material, this is used for the subscript +text in a form field and the text in a paginator. + +
+.mat-font-body-sm {
+  font: var(--mat-sys-body-small);
+  letter-spacing: var(--mat-sys-body-small-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The medium body typeface is the default body font. In Angular Material, this is used for the text in +a table row and the supporting text in a dialog. + +
+.mat-font-body-md {
+  font: var(--mat-sys-body-medium);
+  letter-spacing: var(--mat-sys-body-medium-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The large body typeface is useful for an introductory paragraph. In Angular Material, this is used +for the text in a list item and the text in a select trigger. + +
+.mat-font-body-lg {
+  font: var(--mat-sys-body-large);
+  letter-spacing: var(--mat-sys-body-large-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Display

+ + +The small display typeface is useful for short, important text or numerals, such as in hero sections +or for marking key information. + +
+.mat-font-display-sm {
+  font: var(--mat-sys-display-small);
+  letter-spacing: var(--mat-sys-display-small-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The medium display typeface is useful for short, impactful text in hero sections or titles on larger +screens. + +
+.mat-font-display-md {
+  font: var(--mat-sys-display-medium);
+  letter-spacing: var(--mat-sys-display-medium-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The large display typeface is useful for short, high-emphasis text in hero sections or titles on +larger screens, providing the most visual weight. + +
+.mat-font-display-lg {
+  font: var(--mat-sys-display-large);
+  letter-spacing: var(--mat-sys-display-large-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Headline

+ + +The small headline typeface is useful for a page title. In Angular Material, this is used for the +headline in a dialog. + +
+.mat-font-headline-sm {
+  font: var(--mat-sys-headline-small);
+  letter-spacing: var(--mat-sys-headline-small-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The medium headline typeface is useful for a section title. + +
+.mat-font-headline-md {
+  font: var(--mat-sys-headline-medium);
+  letter-spacing: var(--mat-sys-headline-medium-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The large headline typeface is useful for a page title on a large screen. + +
+.mat-font-headline-lg {
+  font: var(--mat-sys-headline-large);
+  letter-spacing: var(--mat-sys-headline-large-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Label

+ + +The small label typeface is useful for text in a badge. + +
+.mat-font-label-sm {
+  font: var(--mat-sys-label-small);
+  letter-spacing: var(--mat-sys-label-small-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The medium label typeface is useful for the slider label. + +
+.mat-font-label-md {
+  font: var(--mat-sys-label-medium);
+  letter-spacing: var(--mat-sys-label-medium-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The large label typeface is useful for buttons, chips, and menu labels. + +
+.mat-font-label-lg {
+  font: var(--mat-sys-label-large);
+  letter-spacing: var(--mat-sys-label-large-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +

Title

+ + +The small title typeface is useful for a card title. In Angular Material, this is used for the +header of a table and the label of an option group. + +
+.mat-font-title-sm {
+  font: var(--mat-sys-title-small);
+  letter-spacing: var(--mat-sys-title-small-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The medium title typeface is useful for a dialog title or the primary text in a list item. In +Angular Material, this is used for the subtitle of a card and the header of an expansion panel. + +
+.mat-font-title-md {
+  font: var(--mat-sys-title-medium);
+  letter-spacing: var(--mat-sys-title-medium-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +The large title typeface is useful for a page title on a small screen. In Angular Material, this is +used for the title of a card and the title of a toolbar. + +
+.mat-font-title-lg {
+  font: var(--mat-sys-title-large);
+  letter-spacing: var(--mat-sys-title-large-tracking);
+}
+
+ +
Example text: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+ +## Shape + +Material Design uses border radius to help direct attention, identify components, communicate state, +and express brand. See Material +Design's [Corner Radius Scale](https://m3.material.io/styles/shape/corner-radius-scale) +documentation to learn more. + +In Angular Material, shape is scoped to varying levels of border-radius. The following code blocks +demonstate the levels of roundness. Their border sizes are increased to 2px to clearly show the +border radii. + +The extra small border radius is useful for components that need a small amount of rounding, such as +a chip. In Angular Material, this is used for the shape of a snackbar and a tooltip. + +
+.mat-corner-xs {
+  border-radius: var(--mat-sys-corner-extra-small);
+}
+
+The small border radius is useful for components that need a small amount of rounding, such as a +text field. + +
+.mat-corner-sm {
+  border-radius: var(--mat-sys-corner-small);
+}
+
+The medium border radius is useful for components that need a medium amount of rounding, such as a +button. In Angular Material, this is used for the shape of a card. + +
+.mat-corner-md {
+  border-radius: var(--mat-sys-corner-medium);
+}
+
+The large border radius is useful for components that need a large amount of rounding, such as a +card. In Angular Material, this is used for the shape of a floating action button and a datepicker. + +
+.mat-corner-lg {
+  border-radius: var(--mat-sys-corner-large);
+}
+
+The extra large border radius is useful for components that need a large amount of rounding. In +Angular Material, this is used for the shape of a button toggle and the shape of a dialog. + +
+.mat-corner-xl {
+  border-radius: var(--mat-sys-corner-extra-large);
+}
+
+The full border radius is useful for components that are circular, such as a user avatar. In Angular +Material, this is used for the shape of a badge and the shape of a button. + +
+.mat-corner-full {
+  border-radius: var(--mat-sys-corner-full);
+}
+
+ +## Elevation + +Material Design uses borders and shadows to create a sense of depth and hierarchy in the UI. See +Material Design's [Applying Elevation](https://m3.material.io/styles/elevation/applying-elevation) +documentation to +learn more. + +

Border

+ +The Material Design border is useful for components that need a visible boundary. In Angular +Material, this is used for the outline of an outlined button. + +
+.mat-border {
+  border: 1px solid var(--mat-sys-outline);
+}
+
+ +The subtle outline variant is useful for components that need a less obvious boundary. In Angular +Material, this is used for the outline of an outlined card and the color of the divider. + +
+.mat-border-subtle {
+  border: 1px solid var(--mat-sys-outline-variant);
+}
+
+ +

Shadow

+ +Level 1 elevation can be used to slightly raise the appearance of a surface. In Angular Material, +this is used for the elevation of an elevated card and the handle of a slider. + +
+.mat-shadow-1 {
+  box-shadow: var(--mat-sys-level1);
+}
+
+ +Level 2 elevation can be used to raise the appearance of a surface. In Angular Material, this is +used for the elevation of a menu and a select panel. + +
+.mat-shadow-2 {
+  box-shadow: var(--mat-sys-level2);
+}
+
+ +Level 3 elevation is used to raise the appearance of a surface. In Angular Material, this is used +for the elevation of a floating action button. + +
+.mat-shadow-3 {
+  box-shadow: var(--mat-sys-level3);
+}
+
+ +Level 4 elevation is generally reserved for elevation changes due to interaction like focus and +hover. In Angular Material, this is used for the elevation of a hovered floating action button. + +
+.mat-shadow-4 {
+  box-shadow: var(--mat-sys-level4);
+}
+
+ +Level 5 elevation is used to greatly raise the appearance of a surface and is generally reserved for +elevation changes due to interaction like focus and hover. + +
+.mat-shadow-5 {
+  box-shadow: var(--mat-sys-level5);
+}
+
+ +## Material Design 2 Support + +This guide is compatible for applications defining their theme with the "m2" Sass APIs using +the legacy theme-config approach. To take advantage of CSS variables and the utility classes, +you can call `@include mat.m2-theme($theme)` in your theme file, which will define +system tokens according to the Material Design 2 system that matches your current theme +configuration. + +```scss +@use '@angular/material' as mat; + +$theme: mat.m2-define-light-theme(( + color: ( + primary: mat.define-palette(mat.$indigo-palette, 500), + ), + ... +)); + +html { + @include mat.core-theme($theme); + @include mat.button-theme($theme); + ... + @include mat.m2-theme($theme); + @include mat.system-classes(); +} +``` + +By using CSS variables and utility classes, you can avoid creating component-specific theme files +and mixins that extract values from the `$theme` Sass map. For example, consider the following +example of how styles used to be applied in custom components: + +```scss +@use '@angular/material' as mat; +@use 'sass:map'; + +@mixin my-component-theme($theme) { + $foreground: map.get(mat.m2-get-color-config($theme), foreground); + $background: map.get(mat.m2-get-color-config($theme), background); + $primary: map.get(mat.m2-get-color-config($theme), primary); + $typography: mat.m2-get-typography-config($config-or-theme); + + .widget-a { + background-color: mat.m2-get-color-from-palette($background, card); + color: mat.m2-get-color-from-palette($foreground, text); + @include mat.m2-typography-level($config, body-1); + } + + .widget-b { + background-color: mat.m2-get-color-from-palette($primary, default); + color: mat.m2-get-color-from-palette($primary, default-contrast); + } +} +``` + +By using the CSS variables, you can define these theme styles in your component's +stylesheet and avoid creating a separate theme file or mixin: + +```scss +.widget-a { + background-color: var(--mat-sys-surface); + color: var(--mat-sys-on-surface); + font: var(--mat-sys-body-medium); +} + +.widget-b { + background-color: var(--mat-sys-primary); + color: var(--mat-sys-on-primary); +} +``` + +Taking it one step further, you can alternatively use the utility classes to achieve the same styles +in the component template: + +```html + + + +``` diff --git a/guides/theming.md b/guides/theming.md index 71d106e4767c..13188ce4cb1e 100644 --- a/guides/theming.md +++ b/guides/theming.md @@ -58,6 +58,20 @@ body { } ``` +You can also define a convenient set of CSS utility classes that let you apply +theme styles from your component templates. + +```scss +html { + ... + @include mat.system-classes(); +} +``` + +```html + +``` + The `mat.theme` mixin will only declare CSS variables for the categories included in the input. For example, if `typography` is not defined, then typography CSS variables will not be included in the output. @@ -357,7 +371,7 @@ typography variables to create an application-wide banner presenting important information to the user: ```scss -:host { +.my-component { background: var(--mat-sys-primary-container); color: var(--mat-sys-on-primary-container); border: 1px solid var(--mat-sys-outline-variant); @@ -365,8 +379,14 @@ information to the user: } ``` -See the [Theme Variables](https://material.angular.dev/guide/system-variables) guide for a -comprehensive list of these variables, examples of where they are used, and how +Alternatively, you can use utility classes to achieve the same styles: + +```html +
+``` + +See the [Theming your components](https://material.angular.dev/guide/theming-your-components) guide for a +comprehensive list of these variables and classes, including examples of where they are used, and how components can depend on them. ## Customizing Tokens