-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs(material/core): rewrite typography guide for
@use
(#22366)
This change completely rewrites the typography guide to be more complete, correct, and concise. Summary of changes: * Explain the concepts of "typography level" and "typography config". * Ensure all content is conceptual and not task-based. * Use new Sass `@use` API introduiced in #22173 * Split up level descriptions from CSS classes * Clarify that the system currently uses the 2014-era typography levels This is the second PR in a series, following #22268. After this will be PRs for theming-your-components, customizing-component-styles, and new docs for strong focus indicators.
- Loading branch information
Showing
1 changed file
with
215 additions
and
102 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,146 +1,259 @@ | ||
# Angular Material typography | ||
# Customizing Typography | ||
|
||
## What is typography? | ||
Typography is a way of arranging type to make text legible, readable, and appealing when displayed. | ||
Angular Material's typography is based on the guidelines from the [Material Design spec][1] and is | ||
arranged into typography levels. Each level has a `font-size`, `line-height` and `font-weight`. The | ||
available levels are: | ||
|
||
|
||
| Name | CSS classes | Description | | ||
|-----------------|----------------------------------|-----------------------------------------------------------------------------| | ||
| `display-4` | `.mat-display-4` | Large, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `display-3` | `.mat-display-3` | Large, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `display-2` | `.mat-display-2` | Large, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `display-1` | `.mat-display-1` | Large, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `headline` | `.mat-h1`, `.mat-headline` | Section heading corresponding to the `<h1>` tag. | | ||
| `title` | `.mat-h2`, `.mat-title` | Section heading corresponding to the `<h2>` tag. | | ||
| `subheading-2` | `.mat-h3`, `.mat-subheading-2` | Section heading corresponding to the `<h3>` tag. | | ||
| `subheading-1` | `.mat-h4`, `.mat-subheading-1` | Section heading corresponding to the `<h4>` tag. | | ||
| `body-1` | `.mat-body`, `.mat-body-1` | Base body text. | | ||
| `body-2` | `.mat-body-strong`, `.mat-body-2`| Bolder body text. | | ||
| `caption` | `.mat-small`, `.mat-caption` | Smaller body and hint text. | | ||
| `button` | None. Used only in components. | Buttons and anchors. | | ||
| `input` | None. Used only in components. | Form input fields. | | ||
Typography is a way of arranging type to make text legible, readable, and appealing when displayed. | ||
Angular Material's [theming system][theming-system] supports customizing the typography settings | ||
for the library's components. Additionally, Angular Material provides APIs for applying typography | ||
styles to elements in your own application. | ||
|
||
Angular Material's theming APIs are built with [Sass](https://sass-lang.com). This document assumes | ||
familiary with CSS and Sass basics, including variables, functions, and mixins. | ||
|
||
The typography levels are collected into a typography config which is used to generate the CSS. | ||
[theming-system]: https://material.angular.io/guide/theming | ||
|
||
## Usage | ||
## Including font assets | ||
|
||
To get started, you first include the `Roboto` font with the 300, 400 and 500 weights. | ||
You can host it yourself or include it from [Google Fonts][2]: | ||
Angular Material's typography APIs lets you specify any font-face. The default font-face value is | ||
configured to [Google's Roboto font][roboto] with the 300, 400, and 500 font-weight styles. To use | ||
Roboto, your application must load the font, which is not included with Angular Material. The | ||
easiest way to load Roboto, or any other custom font, is by using Google Fonts. The following | ||
snippet can be placed in your application's `<head>` to load Roboto from Google Fonts. | ||
|
||
```html | ||
<link rel="preconnect" href="https://fonts.gstatic.com"> | ||
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet"> | ||
``` | ||
|
||
Now you can add the appropriate CSS classes to the elements that you want to style: | ||
See [Getting Started with the Google Fonts API][fonts-api] for more about using Google Fonts. Also | ||
note that, by default, [the Angular CLI inlines assets from Google Fonts to reduce render-blocking | ||
requests][font-inlining]. | ||
|
||
[roboto]: https://fonts.google.com/share?selection.family=Roboto:wght@300;400;500 | ||
[fonts-api]: https://developers.google.com/fonts/docs/getting_started | ||
[font-inlining]: https://angular.io/guide/workspace-config#fonts-optimization-options | ||
|
||
## Typography levels | ||
|
||
A **typography level** is a collection of typographic styles that corresponds to a specific | ||
part of an application's structure, such as a header. Each level includes styles for font family, | ||
font weight, font size, and letter spacing. Angular Material uses the [typography levels | ||
from the 2014 version of the Material Design specification][2014-typography], outlined in the | ||
table below. | ||
|
||
| Name | Description | | ||
|-----------------|-----------------------------------------------------------------------------| | ||
| `display-4` | 112px, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `display-3` | 56px, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `display-2` | 45px, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `display-1` | 34px, one-off header, usually at the top of the page (e.g. a hero header). | | ||
| `headline` | Section heading corresponding to the `<h1>` tag. | | ||
| `title` | Section heading corresponding to the `<h2>` tag. | | ||
| `subheading-2` | Section heading corresponding to the `<h3>` tag. | | ||
| `subheading-1` | Section heading corresponding to the `<h4>` tag. | | ||
| `body-1` | Base body text. | | ||
| `body-2` | Bolder body text. | | ||
| `caption` | Smaller body and hint text. | | ||
| `button` | Buttons and anchors. | | ||
| `input` | Form input fields. | | ||
|
||
[2014-typography]: https://material.io/archive/guidelines/style/typography.html#typography-styles | ||
|
||
### Define a level | ||
|
||
You can define a typography level with the `define-typography-config` Sass function. This function | ||
accepts, in order, CSS values for `font-size`, `line-height`, `font-weight`, `font-family`, and | ||
`letter-spacing`. You can also specify the parameters by name, as demonstrated in the example below. | ||
|
||
```html | ||
<h1 class="mat-display-1">Jackdaws love my big sphinx of quartz.</h1> | ||
<h2 class="mat-h2">The quick brown fox jumps over the lazy dog.</h2> | ||
``` | ||
```scss | ||
@use '~@angular/material' as mat; | ||
|
||
$my-custom-level: mat.define-typography-level( | ||
$font-family: Roboto, | ||
$font-weight: 400, | ||
$font-size: 1rem, | ||
$line-height: 1, | ||
$letter-spacing: normal, | ||
); | ||
``` | ||
|
||
By default, Angular Material doesn't apply any global CSS. To apply the library's typographic styles | ||
more broadly, you can take advantage of the `mat-typography` CSS class. This class will style all | ||
descendant native elements. | ||
## Typography config | ||
|
||
```html | ||
<!-- By default, Angular Material applies no global styles to native elements. --> | ||
<h1>This header is unstyled</h1> | ||
A **typography config** is a collection of all typography levels. Angular Material represents this | ||
config as a Sass map. This map contains the styles for each level, keyed by name. You can create | ||
a typography config with the `define-typography-config` Sass function. Every parameter for | ||
`define-typography-config` is optional; the styles for a level will default to Material Design's | ||
baseline if unspecified. | ||
|
||
<!-- Applying the mat-tyography class adds styles for native elements. --> | ||
<section class="mat-typography"> | ||
<h1>This header will be styled</h1> | ||
</section> | ||
```scss | ||
@use '~@angular/material' as mat; | ||
|
||
$my-custom-typography-config: mat.define-typography-config( | ||
$display-4: mat.define-typography-level(112px, 112px, 300, $letter-spacing: -0.05em), | ||
$display-3: mat.define-typography-level(56px, 56px, 400, $letter-spacing: -0.02em), | ||
$display-2: mat.define-typography-level(45px, 48px, 400, $letter-spacing: -0.005em), | ||
$display-1: mat.define-typography-level(34px, 40px, 400), | ||
$headline: mat.define-typography-level(24px, 32px, 400), | ||
// ... | ||
); | ||
``` | ||
|
||
## Customization | ||
|
||
Typography customization is an extension of Angular Material's Sass-based theming. Similar to | ||
creating a custom theme, you can create a custom **typography configuration**. | ||
To customize component typography for your entire application, you can pass your custom typography | ||
config to the `core` mixin described in the [theming guide][theming-system]. | ||
|
||
```scss | ||
@import '~@angular/material/theming'; | ||
|
||
// Define a custom typography config that overrides the font-family as well as the | ||
// `headlines` and `body-1` levels. | ||
$custom-typography-theme: ( | ||
typography: mat-typography-config( | ||
$font-family: 'Roboto, monospace', | ||
$headline: mat-typography-level(32px, 48px, 700), | ||
$body-1: mat-typography-level(16px, 24px, 500) | ||
) | ||
@use '~@angular/material' as mat; | ||
|
||
$my-custom-typography: mat.define-typography-config( | ||
$headline: mat.define-typography-level(3rem, 1, 700), | ||
); | ||
``` | ||
|
||
As the above example demonstrates, a typography configuration is created by using the | ||
`mat-typography-config` function, which is given both the font-family and the set of typographic | ||
levels described earlier. Each typographic level is defined by the `mat-typography-level` function, | ||
which requires a `font-size`, `line-height`, and `font-weight`. **Note** that the `font-family` | ||
has to be in quotes. | ||
@include mat.core($my-custom-typography); | ||
``` | ||
|
||
Passing your typography config to `core` mixin will apply your specified values to all Angular | ||
Material components. If a config is not specified, `core` will emit the default Material Design | ||
typography styles. | ||
|
||
Once the custom typography definition is created, it can be consumed to generate styles via | ||
different Sass mixins. | ||
### Typography configs and theming | ||
|
||
```scss | ||
// Override typography CSS classes (e.g., mat-h1, mat-display-1, mat-typography, etc.). | ||
@include mat-base-typography($custom-typography-theme); | ||
In addition to the `core` mixin, you can specify your typography config when including any `theme` | ||
mixin, as described in the [theming guide][theming-system]. Because the `core` mixin always emits | ||
typography styles, specifying a typography config to a theme mixin results in duplicate typography | ||
CSS. You should only provide a typography config when applying your theme if you need to specify | ||
multiple typography styles that are conditionally applied based on your application's behavior. | ||
|
||
// Override typography for a specific Angular Material components. | ||
@include mat-checkbox-typography($custom-typography-theme); | ||
The following example shows a typical theme definition and a "kids theme" that only applies when | ||
the `".kids-theme"` CSS class is present. You can [see the theming guide for more guidance on | ||
defining multiple themes](https://material.angular.io/guide/theming#defining-multiple-themes). | ||
|
||
// Override typography for all Angular Material, including mat-base-typography and all components. | ||
@include angular-material-typography($custom-typography-theme); | ||
```scss | ||
@use '~@angular/material' as mat; | ||
|
||
@include mat.core(); | ||
|
||
$my-primary: mat.define-palette(mat.$indigo-palette, 500); | ||
$my-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); | ||
|
||
$my-theme: mat.define-light-theme(( | ||
color: ( | ||
primary: $my-primary, | ||
accent: $my-accent, | ||
) | ||
)); | ||
|
||
@include mat.all-component-themes($my-theme); | ||
|
||
.kids-theme { | ||
$kids-primary: mat.define-palette(mat.$cyan-palette); | ||
$kids-accent: mat.define-palette(mat.$yellow-palette); | ||
$kids-typography: mat.define-typography-config( | ||
// Specify "Comic Sans" as the default font family for all levels. | ||
$font-family: 'Comic Sans', | ||
); | ||
|
||
$kids-theme: mat.define-light-theme(( | ||
color: ( | ||
primary: $my-primary, | ||
accent: $my-accent, | ||
), | ||
typography: $kids-typography, | ||
)); | ||
|
||
@include mat.all-component-themes($kids-theme); | ||
} | ||
``` | ||
|
||
If you're using Material's theming, you can also pass in your typography config to the | ||
`mat-core` mixin: | ||
Each component also has a `typography` mixin that emits only the typography styles for that | ||
component, based on a provided typography config. The following example demonstrates applying | ||
typography styles only for the button component. | ||
|
||
```scss | ||
// Override the typography in the core CSS. | ||
@include mat-core($custom-typography-theme); | ||
``` | ||
@use '~@angular/material' as mat; | ||
|
||
For more details about the typography functions and default config, see the | ||
[source](https://github.com/angular/components/blob/master/src/material/core/typography/_typography.scss). | ||
$kids-typography: mat.define-typography-config( | ||
// Specify "Comic Sans" as the default font family for all levels. | ||
$font-family: 'Comic Sans', | ||
); | ||
|
||
// Now we have sweet buttons with Comic Sans. | ||
@include mat.button-typography($kids-typography); | ||
``` | ||
|
||
## Material typography in your custom CSS | ||
## Using typography styles in your application | ||
|
||
Angular Material includes typography utility mixins and functions that you can use to customize your | ||
own components: | ||
In addition to styles shared between components, the `core` mixin includes CSS classes for styling | ||
your application. These CSS classes correspond to the typography levels in your typography config. | ||
This mixin also emits styles for native header elements scoped within the `.mat-typography` CSS | ||
class. The table below lists the the CSS classes emitted and the native elements styled. | ||
|
||
* `mat-font-size($config, $level)` - Gets the `font-size`, based on the provided config and level. | ||
* `mat-font-family($config)` - Gets the `font-family`, based on the provided config. | ||
* `mat-line-height($config, $level)` - Gets the `line-height`, based on the provided | ||
config and level. | ||
* `mat-font-weight($config, $level)` - Gets the `font-weight`, based on the provided | ||
config and level. | ||
* `mat-typography-level-to-styles($config, $level)` - Mixin that takes in a configuration object | ||
and a typography level, and outputs a short-hand CSS `font` declaration. | ||
| CSS class | Level name | Native elements | | ||
|-------------------------------------|----------------|-----------------| | ||
| `.mat-display-4` | `display-4` | None | | ||
| `.mat-display-3` | `display-3` | None | | ||
| `.mat-display-2` | `display-2` | None | | ||
| `.mat-display-1` | `display-1` | None | | ||
| `.mat-h1` or `.mat-headline` | `headline` | `<h1>` | | ||
| `.mat-h2` or `.mat-title` | `title` | `<h2>` | | ||
| `.mat-h3` or `.mat-subheading-2` | `subheading-2` | `<h3>` | | ||
| `.mat-h4` or `.mat-subheading-1` | `subheading-1` | `<h4>` | | ||
| `.mat-h5` | None | `<h5>` | | ||
| `.mat-h6` | None | `<h6>` | | ||
| `.mat-body` or `.mat-body-1` | `body-1` | Body text | | ||
| `.mat-body-strong` or `.mat-body-2` | `body-2` | None | | ||
| `.mat-small` or `.mat-caption` | `caption` | None | | ||
|
||
```scss | ||
@import '~@angular/material/theming'; | ||
In addition to the typographic styles, these style rules also include a `margin-bottom` for | ||
headers and paragraphs. For `body-1` styles, text is styled within the provided CSS selector. | ||
|
||
// Create a config with the default typography levels. | ||
$config: mat-typography-config(); | ||
The `.mat-h5` and `.mat-h6` styles don't directly correspond to a specific Material Design | ||
typography level. The `.mat-h5` style uses the `body-1` level with the font-size scaled down by | ||
`0.83`. The `.mat-h6` style uses the `body-1` level with the font-size scaled down by `0.67`. | ||
|
||
// Custom header that uses only the Material `font-size` and `font-family`. | ||
.unicorn-header { | ||
font-size: mat-font-size($config, headline); | ||
font-family: mat-font-family($config); | ||
} | ||
The `button` and `input` typography levels do not map to CSS classes. | ||
|
||
// Custom title that uses all of the typography styles from the `title` level. | ||
.unicorn-title { | ||
@include mat-typography-level-to-styles($config, title); | ||
} | ||
The following example demonstrates usage of the typography styles emitted by the `core` mixin. | ||
|
||
```html | ||
<body> | ||
<!-- This header will *not* be styled because it is outside `.mat-typography` --> | ||
<h1>Top header</h1> | ||
|
||
<!-- This paragraph will be styled as `body-1` via the `.mat-body` CSS class applied --> | ||
<p class="mat-body">Introductory text</p> | ||
|
||
<div class="mat-typography"> | ||
<!-- This header will be styled as `title` because it is inside `.mat-typography` --> | ||
<h2>Inner header</h2> | ||
|
||
<!-- This paragraph will be styled as `body-1` because it is inside `.mat-typography` --> | ||
<p>Some inner text</p> | ||
</div> | ||
</body> | ||
``` | ||
|
||
### Reading typography values from a config | ||
|
||
[1]: https://material.io/archive/guidelines/style/typography.html | ||
[2]: https://fonts.google.com/ | ||
You can read typography style values from a typography config via the following Sass functions. Each | ||
accepts a typography config and a level. | ||
|
||
| Function | Example usage | | ||
|---------------|---------------------------------------| | ||
| `font-size` | `mat.font-size($config, 'body-1');` | | ||
| `font-family` | `mat.font-family($config, 'body-1');` | | ||
| `font-weight` | `mat.font-weight($config, 'body-1');` | | ||
| `line-height` | `mat.line-height($config, 'body-1');` | | ||
|
||
Additionally, you can use the `typography-level` Sass mixin to directly emit the CSS styles for a | ||
given typography level. | ||
|
||
```scss | ||
@use '~@angular/material' as mat; | ||
|
||
// Use the default configuration. | ||
$my-typography: mat.define-typography-config(); | ||
|
||
.some-class-name { | ||
@include mat.typography-level($my-typography, 'body-1'); | ||
} | ||
``` |