|
1 |
| -# Angular Material typography |
| 1 | +# Customizing Typography |
2 | 2 |
|
3 | 3 | ## 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 |
| - |
9 | 4 |
|
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. |
25 | 9 |
|
| 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. |
26 | 12 |
|
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 |
28 | 14 |
|
29 |
| -## Usage |
| 15 | +## Including font assets |
30 | 16 |
|
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. |
33 | 22 |
|
34 | 23 | ```html
|
35 | 24 | <link rel="preconnect" href="https://fonts.gstatic.com">
|
36 | 25 | <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
37 | 26 | ```
|
38 | 27 |
|
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. |
40 | 67 |
|
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 | +``` |
45 | 79 |
|
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 |
49 | 81 |
|
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. |
53 | 87 |
|
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 | +); |
58 | 99 | ```
|
59 | 100 |
|
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]. |
64 | 103 |
|
65 | 104 | ```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), |
76 | 109 | );
|
77 |
| -``` |
78 | 110 |
|
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 | +``` |
84 | 113 |
|
| 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. |
85 | 117 |
|
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 |
88 | 119 |
|
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. |
92 | 125 |
|
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). |
95 | 129 |
|
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 | +} |
98 | 165 | ```
|
99 | 166 |
|
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. |
102 | 170 |
|
103 | 171 | ```scss
|
104 |
| -// Override the typography in the core CSS. |
105 |
| -@include mat-core($custom-typography-theme); |
106 |
| -``` |
| 172 | +@use '~@angular/material' as mat; |
107 | 173 |
|
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 | +); |
110 | 178 |
|
| 179 | +// Now we have sweet buttons with Comic Sans. |
| 180 | +@include mat.button-typography($kids-typography); |
| 181 | +``` |
111 | 182 |
|
112 |
| -## Material typography in your custom CSS |
| 183 | +## Using typography styles in your application |
113 | 184 |
|
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. |
116 | 189 |
|
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 | |
125 | 205 |
|
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. |
128 | 208 |
|
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`. |
131 | 212 |
|
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. |
137 | 214 |
|
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> |
142 | 233 | ```
|
143 | 234 |
|
| 235 | +### Reading typography values from a config |
144 | 236 |
|
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