Skip to content

Commit 34dba13

Browse files
authored
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.
1 parent 48e22f3 commit 34dba13

File tree

1 file changed

+215
-102
lines changed

1 file changed

+215
-102
lines changed

guides/typography.md

Lines changed: 215 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,146 +1,259 @@
1-
# Angular Material typography
1+
# Customizing Typography
22

33
## What is typography?
4-
Typography is a way of arranging type to make text legible, readable, and appealing when displayed.
5-
Angular Material's typography is based on the guidelines from the [Material Design spec][1] and is
6-
arranged into typography levels. Each level has a `font-size`, `line-height` and `font-weight`. The
7-
available levels are:
8-
94

10-
| Name | CSS classes | Description |
11-
|-----------------|----------------------------------|-----------------------------------------------------------------------------|
12-
| `display-4` | `.mat-display-4` | Large, one-off header, usually at the top of the page (e.g. a hero header). |
13-
| `display-3` | `.mat-display-3` | Large, one-off header, usually at the top of the page (e.g. a hero header). |
14-
| `display-2` | `.mat-display-2` | Large, one-off header, usually at the top of the page (e.g. a hero header). |
15-
| `display-1` | `.mat-display-1` | Large, one-off header, usually at the top of the page (e.g. a hero header). |
16-
| `headline` | `.mat-h1`, `.mat-headline` | Section heading corresponding to the `<h1>` tag. |
17-
| `title` | `.mat-h2`, `.mat-title` | Section heading corresponding to the `<h2>` tag. |
18-
| `subheading-2` | `.mat-h3`, `.mat-subheading-2` | Section heading corresponding to the `<h3>` tag. |
19-
| `subheading-1` | `.mat-h4`, `.mat-subheading-1` | Section heading corresponding to the `<h4>` tag. |
20-
| `body-1` | `.mat-body`, `.mat-body-1` | Base body text. |
21-
| `body-2` | `.mat-body-strong`, `.mat-body-2`| Bolder body text. |
22-
| `caption` | `.mat-small`, `.mat-caption` | Smaller body and hint text. |
23-
| `button` | None. Used only in components. | Buttons and anchors. |
24-
| `input` | None. Used only in components. | Form input fields. |
5+
Typography is a way of arranging type to make text legible, readable, and appealing when displayed.
6+
Angular Material's [theming system][theming-system] supports customizing the typography settings
7+
for the library's components. Additionally, Angular Material provides APIs for applying typography
8+
styles to elements in your own application.
259

10+
Angular Material's theming APIs are built with [Sass](https://sass-lang.com). This document assumes
11+
familiary with CSS and Sass basics, including variables, functions, and mixins.
2612

27-
The typography levels are collected into a typography config which is used to generate the CSS.
13+
[theming-system]: https://material.angular.io/guide/theming
2814

29-
## Usage
15+
## Including font assets
3016

31-
To get started, you first include the `Roboto` font with the 300, 400 and 500 weights.
32-
You can host it yourself or include it from [Google Fonts][2]:
17+
Angular Material's typography APIs lets you specify any font-face. The default font-face value is
18+
configured to [Google's Roboto font][roboto] with the 300, 400, and 500 font-weight styles. To use
19+
Roboto, your application must load the font, which is not included with Angular Material. The
20+
easiest way to load Roboto, or any other custom font, is by using Google Fonts. The following
21+
snippet can be placed in your application's `<head>` to load Roboto from Google Fonts.
3322

3423
```html
3524
<link rel="preconnect" href="https://fonts.gstatic.com">
3625
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
3726
```
3827

39-
Now you can add the appropriate CSS classes to the elements that you want to style:
28+
See [Getting Started with the Google Fonts API][fonts-api] for more about using Google Fonts. Also
29+
note that, by default, [the Angular CLI inlines assets from Google Fonts to reduce render-blocking
30+
requests][font-inlining].
31+
32+
[roboto]: https://fonts.google.com/share?selection.family=Roboto:wght@300;400;500
33+
[fonts-api]: https://developers.google.com/fonts/docs/getting_started
34+
[font-inlining]: https://angular.io/guide/workspace-config#fonts-optimization-options
35+
36+
## Typography levels
37+
38+
A **typography level** is a collection of typographic styles that corresponds to a specific
39+
part of an application's structure, such as a header. Each level includes styles for font family,
40+
font weight, font size, and letter spacing. Angular Material uses the [typography levels
41+
from the 2014 version of the Material Design specification][2014-typography], outlined in the
42+
table below.
43+
44+
| Name | Description |
45+
|-----------------|-----------------------------------------------------------------------------|
46+
| `display-4` | 112px, one-off header, usually at the top of the page (e.g. a hero header). |
47+
| `display-3` | 56px, one-off header, usually at the top of the page (e.g. a hero header). |
48+
| `display-2` | 45px, one-off header, usually at the top of the page (e.g. a hero header). |
49+
| `display-1` | 34px, one-off header, usually at the top of the page (e.g. a hero header). |
50+
| `headline` | Section heading corresponding to the `<h1>` tag. |
51+
| `title` | Section heading corresponding to the `<h2>` tag. |
52+
| `subheading-2` | Section heading corresponding to the `<h3>` tag. |
53+
| `subheading-1` | Section heading corresponding to the `<h4>` tag. |
54+
| `body-1` | Base body text. |
55+
| `body-2` | Bolder body text. |
56+
| `caption` | Smaller body and hint text. |
57+
| `button` | Buttons and anchors. |
58+
| `input` | Form input fields. |
59+
60+
[2014-typography]: https://material.io/archive/guidelines/style/typography.html#typography-styles
61+
62+
### Define a level
63+
64+
You can define a typography level with the `define-typography-config` Sass function. This function
65+
accepts, in order, CSS values for `font-size`, `line-height`, `font-weight`, `font-family`, and
66+
`letter-spacing`. You can also specify the parameters by name, as demonstrated in the example below.
4067

41-
```html
42-
<h1 class="mat-display-1">Jackdaws love my big sphinx of quartz.</h1>
43-
<h2 class="mat-h2">The quick brown fox jumps over the lazy dog.</h2>
44-
```
68+
```scss
69+
@use '~@angular/material' as mat;
70+
71+
$my-custom-level: mat.define-typography-level(
72+
$font-family: Roboto,
73+
$font-weight: 400,
74+
$font-size: 1rem,
75+
$line-height: 1,
76+
$letter-spacing: normal,
77+
);
78+
```
4579

46-
By default, Angular Material doesn't apply any global CSS. To apply the library's typographic styles
47-
more broadly, you can take advantage of the `mat-typography` CSS class. This class will style all
48-
descendant native elements.
80+
## Typography config
4981

50-
```html
51-
<!-- By default, Angular Material applies no global styles to native elements. -->
52-
<h1>This header is unstyled</h1>
82+
A **typography config** is a collection of all typography levels. Angular Material represents this
83+
config as a Sass map. This map contains the styles for each level, keyed by name. You can create
84+
a typography config with the `define-typography-config` Sass function. Every parameter for
85+
`define-typography-config` is optional; the styles for a level will default to Material Design's
86+
baseline if unspecified.
5387

54-
<!-- Applying the mat-tyography class adds styles for native elements. -->
55-
<section class="mat-typography">
56-
<h1>This header will be styled</h1>
57-
</section>
88+
```scss
89+
@use '~@angular/material' as mat;
90+
91+
$my-custom-typography-config: mat.define-typography-config(
92+
$display-4: mat.define-typography-level(112px, 112px, 300, $letter-spacing: -0.05em),
93+
$display-3: mat.define-typography-level(56px, 56px, 400, $letter-spacing: -0.02em),
94+
$display-2: mat.define-typography-level(45px, 48px, 400, $letter-spacing: -0.005em),
95+
$display-1: mat.define-typography-level(34px, 40px, 400),
96+
$headline: mat.define-typography-level(24px, 32px, 400),
97+
// ...
98+
);
5899
```
59100

60-
## Customization
61-
62-
Typography customization is an extension of Angular Material's Sass-based theming. Similar to
63-
creating a custom theme, you can create a custom **typography configuration**.
101+
To customize component typography for your entire application, you can pass your custom typography
102+
config to the `core` mixin described in the [theming guide][theming-system].
64103

65104
```scss
66-
@import '~@angular/material/theming';
67-
68-
// Define a custom typography config that overrides the font-family as well as the
69-
// `headlines` and `body-1` levels.
70-
$custom-typography-theme: (
71-
typography: mat-typography-config(
72-
$font-family: 'Roboto, monospace',
73-
$headline: mat-typography-level(32px, 48px, 700),
74-
$body-1: mat-typography-level(16px, 24px, 500)
75-
)
105+
@use '~@angular/material' as mat;
106+
107+
$my-custom-typography: mat.define-typography-config(
108+
$headline: mat.define-typography-level(3rem, 1, 700),
76109
);
77-
```
78110

79-
As the above example demonstrates, a typography configuration is created by using the
80-
`mat-typography-config` function, which is given both the font-family and the set of typographic
81-
levels described earlier. Each typographic level is defined by the `mat-typography-level` function,
82-
which requires a `font-size`, `line-height`, and `font-weight`. **Note** that the `font-family`
83-
has to be in quotes.
111+
@include mat.core($my-custom-typography);
112+
```
84113

114+
Passing your typography config to `core` mixin will apply your specified values to all Angular
115+
Material components. If a config is not specified, `core` will emit the default Material Design
116+
typography styles.
85117

86-
Once the custom typography definition is created, it can be consumed to generate styles via
87-
different Sass mixins.
118+
### Typography configs and theming
88119

89-
```scss
90-
// Override typography CSS classes (e.g., mat-h1, mat-display-1, mat-typography, etc.).
91-
@include mat-base-typography($custom-typography-theme);
120+
In addition to the `core` mixin, you can specify your typography config when including any `theme`
121+
mixin, as described in the [theming guide][theming-system]. Because the `core` mixin always emits
122+
typography styles, specifying a typography config to a theme mixin results in duplicate typography
123+
CSS. You should only provide a typography config when applying your theme if you need to specify
124+
multiple typography styles that are conditionally applied based on your application's behavior.
92125

93-
// Override typography for a specific Angular Material components.
94-
@include mat-checkbox-typography($custom-typography-theme);
126+
The following example shows a typical theme definition and a "kids theme" that only applies when
127+
the `".kids-theme"` CSS class is present. You can [see the theming guide for more guidance on
128+
defining multiple themes](https://material.angular.io/guide/theming#defining-multiple-themes).
95129

96-
// Override typography for all Angular Material, including mat-base-typography and all components.
97-
@include angular-material-typography($custom-typography-theme);
130+
```scss
131+
@use '~@angular/material' as mat;
132+
133+
@include mat.core();
134+
135+
$my-primary: mat.define-palette(mat.$indigo-palette, 500);
136+
$my-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);
137+
138+
$my-theme: mat.define-light-theme((
139+
color: (
140+
primary: $my-primary,
141+
accent: $my-accent,
142+
)
143+
));
144+
145+
@include mat.all-component-themes($my-theme);
146+
147+
.kids-theme {
148+
$kids-primary: mat.define-palette(mat.$cyan-palette);
149+
$kids-accent: mat.define-palette(mat.$yellow-palette);
150+
$kids-typography: mat.define-typography-config(
151+
// Specify "Comic Sans" as the default font family for all levels.
152+
$font-family: 'Comic Sans',
153+
);
154+
155+
$kids-theme: mat.define-light-theme((
156+
color: (
157+
primary: $my-primary,
158+
accent: $my-accent,
159+
),
160+
typography: $kids-typography,
161+
));
162+
163+
@include mat.all-component-themes($kids-theme);
164+
}
98165
```
99166

100-
If you're using Material's theming, you can also pass in your typography config to the
101-
`mat-core` mixin:
167+
Each component also has a `typography` mixin that emits only the typography styles for that
168+
component, based on a provided typography config. The following example demonstrates applying
169+
typography styles only for the button component.
102170

103171
```scss
104-
// Override the typography in the core CSS.
105-
@include mat-core($custom-typography-theme);
106-
```
172+
@use '~@angular/material' as mat;
107173

108-
For more details about the typography functions and default config, see the
109-
[source](https://github.com/angular/components/blob/master/src/material/core/typography/_typography.scss).
174+
$kids-typography: mat.define-typography-config(
175+
// Specify "Comic Sans" as the default font family for all levels.
176+
$font-family: 'Comic Sans',
177+
);
110178

179+
// Now we have sweet buttons with Comic Sans.
180+
@include mat.button-typography($kids-typography);
181+
```
111182

112-
## Material typography in your custom CSS
183+
## Using typography styles in your application
113184

114-
Angular Material includes typography utility mixins and functions that you can use to customize your
115-
own components:
185+
In addition to styles shared between components, the `core` mixin includes CSS classes for styling
186+
your application. These CSS classes correspond to the typography levels in your typography config.
187+
This mixin also emits styles for native header elements scoped within the `.mat-typography` CSS
188+
class. The table below lists the the CSS classes emitted and the native elements styled.
116189

117-
* `mat-font-size($config, $level)` - Gets the `font-size`, based on the provided config and level.
118-
* `mat-font-family($config)` - Gets the `font-family`, based on the provided config.
119-
* `mat-line-height($config, $level)` - Gets the `line-height`, based on the provided
120-
config and level.
121-
* `mat-font-weight($config, $level)` - Gets the `font-weight`, based on the provided
122-
config and level.
123-
* `mat-typography-level-to-styles($config, $level)` - Mixin that takes in a configuration object
124-
and a typography level, and outputs a short-hand CSS `font` declaration.
190+
| CSS class | Level name | Native elements |
191+
|-------------------------------------|----------------|-----------------|
192+
| `.mat-display-4` | `display-4` | None |
193+
| `.mat-display-3` | `display-3` | None |
194+
| `.mat-display-2` | `display-2` | None |
195+
| `.mat-display-1` | `display-1` | None |
196+
| `.mat-h1` or `.mat-headline` | `headline` | `<h1>` |
197+
| `.mat-h2` or `.mat-title` | `title` | `<h2>` |
198+
| `.mat-h3` or `.mat-subheading-2` | `subheading-2` | `<h3>` |
199+
| `.mat-h4` or `.mat-subheading-1` | `subheading-1` | `<h4>` |
200+
| `.mat-h5` | None | `<h5>` |
201+
| `.mat-h6` | None | `<h6>` |
202+
| `.mat-body` or `.mat-body-1` | `body-1` | Body text |
203+
| `.mat-body-strong` or `.mat-body-2` | `body-2` | None |
204+
| `.mat-small` or `.mat-caption` | `caption` | None |
125205

126-
```scss
127-
@import '~@angular/material/theming';
206+
In addition to the typographic styles, these style rules also include a `margin-bottom` for
207+
headers and paragraphs. For `body-1` styles, text is styled within the provided CSS selector.
128208

129-
// Create a config with the default typography levels.
130-
$config: mat-typography-config();
209+
The `.mat-h5` and `.mat-h6` styles don't directly correspond to a specific Material Design
210+
typography level. The `.mat-h5` style uses the `body-1` level with the font-size scaled down by
211+
`0.83`. The `.mat-h6` style uses the `body-1` level with the font-size scaled down by `0.67`.
131212

132-
// Custom header that uses only the Material `font-size` and `font-family`.
133-
.unicorn-header {
134-
font-size: mat-font-size($config, headline);
135-
font-family: mat-font-family($config);
136-
}
213+
The `button` and `input` typography levels do not map to CSS classes.
137214

138-
// Custom title that uses all of the typography styles from the `title` level.
139-
.unicorn-title {
140-
@include mat-typography-level-to-styles($config, title);
141-
}
215+
The following example demonstrates usage of the typography styles emitted by the `core` mixin.
216+
217+
```html
218+
<body>
219+
<!-- This header will *not* be styled because it is outside `.mat-typography` -->
220+
<h1>Top header</h1>
221+
222+
<!-- This paragraph will be styled as `body-1` via the `.mat-body` CSS class applied -->
223+
<p class="mat-body">Introductory text</p>
224+
225+
<div class="mat-typography">
226+
<!-- This header will be styled as `title` because it is inside `.mat-typography` -->
227+
<h2>Inner header</h2>
228+
229+
<!-- This paragraph will be styled as `body-1` because it is inside `.mat-typography` -->
230+
<p>Some inner text</p>
231+
</div>
232+
</body>
142233
```
143234

235+
### Reading typography values from a config
144236

145-
[1]: https://material.io/archive/guidelines/style/typography.html
146-
[2]: https://fonts.google.com/
237+
You can read typography style values from a typography config via the following Sass functions. Each
238+
accepts a typography config and a level.
239+
240+
| Function | Example usage |
241+
|---------------|---------------------------------------|
242+
| `font-size` | `mat.font-size($config, 'body-1');` |
243+
| `font-family` | `mat.font-family($config, 'body-1');` |
244+
| `font-weight` | `mat.font-weight($config, 'body-1');` |
245+
| `line-height` | `mat.line-height($config, 'body-1');` |
246+
247+
Additionally, you can use the `typography-level` Sass mixin to directly emit the CSS styles for a
248+
given typography level.
249+
250+
```scss
251+
@use '~@angular/material' as mat;
252+
253+
// Use the default configuration.
254+
$my-typography: mat.define-typography-config();
255+
256+
.some-class-name {
257+
@include mat.typography-level($my-typography, 'body-1');
258+
}
259+
```

0 commit comments

Comments
 (0)