|
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 | +By default, Angular Material is configured to use [Google's Roboto font][roboto] with the 300, 400, |
| 18 | +and 500 font-weight styles. To use Roboto, your application must load the font, which is |
| 19 | +not inlcuded with Angular Material. The easiest way to load Roboto is by using Google Fonts. The |
| 20 | +following snippet can be placed in your application's `<head>` to load Roboto from Google Fonts. |
33 | 21 |
|
34 | 22 | ```html
|
35 | 23 | <link rel="preconnect" href="https://fonts.gstatic.com">
|
36 | 24 | <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
|
37 | 25 | ```
|
38 | 26 |
|
39 |
| -Now you can add the appropriate CSS classes to the elements that you want to style: |
| 27 | +See [Getting Started with the Google Fonts API][fonts-api] for more about using Google Fonts. |
40 | 28 |
|
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 |
| -``` |
| 29 | +[roboto]: https://fonts.google.com/share?selection.family=Roboto:wght@300;400;500 |
| 30 | +[fonts-api]: https://developers.google.com/fonts/docs/getting_started |
45 | 31 |
|
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. |
| 32 | +## Typography levels |
49 | 33 |
|
50 |
| -```html |
51 |
| -<!-- By default, Angular Material applies no global styles to native elements. --> |
52 |
| -<h1>This header is unstyled</h1> |
| 34 | +A **typography level** is a collection of typographic styles that corresponds to a specific |
| 35 | +part of an application's structure, such as a header. Each level includes styles for font family, |
| 36 | +font weight, font size, and letter-spacing. Angular Material uses the [typography levels |
| 37 | +from the 2014 version of the Material Design specification][2014-typography], outlined in the |
| 38 | +table below. |
53 | 39 |
|
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> |
58 |
| -``` |
| 40 | +| Name | Description | |
| 41 | +|-----------------|-----------------------------------------------------------------------------| |
| 42 | +| `display-4` | Large, one-off header, usually at the top of the page (e.g. a hero header). | |
| 43 | +| `display-3` | Large, one-off header, usually at the top of the page (e.g. a hero header). | |
| 44 | +| `display-2` | Large, one-off header, usually at the top of the page (e.g. a hero header). | |
| 45 | +| `display-1` | Large, one-off header, usually at the top of the page (e.g. a hero header). | |
| 46 | +| `headline` | Section heading corresponding to the `<h1>` tag. | |
| 47 | +| `title` | Section heading corresponding to the `<h2>` tag. | |
| 48 | +| `subheading-2` | Section heading corresponding to the `<h3>` tag. | |
| 49 | +| `subheading-1` | Section heading corresponding to the `<h4>` tag. | |
| 50 | +| `body-1` | Base body text. | |
| 51 | +| `body-2` | Bolder body text. | |
| 52 | +| `caption` | Smaller body and hint text. | |
| 53 | +| `button` | Buttons and anchors. | |
| 54 | +| `input` | Form input fields. | |
59 | 55 |
|
60 |
| -## Customization |
| 56 | +[2014-typography]: https://material.io/archive/guidelines/style/typography.html#typography-styles |
61 | 57 |
|
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**. |
| 58 | +### Define a level |
| 59 | + |
| 60 | +You can define a typography level with the `define-typography-config` Sass function. This function |
| 61 | +accepts, in order, CSS values for `font-size`, `line-height`, `font-weight`, `font-family`, and |
| 62 | +`letter-spacing`. You can also specify the parameters by name, as demonstrated in the example below. |
64 | 63 |
|
65 | 64 | ```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 |
| - ) |
| 65 | +@use '~@angular/material' as mat; |
| 66 | + |
| 67 | +$my-custom-level: mat.define-typography-level( |
| 68 | + $font-family: Roboto, |
| 69 | + $font-weight: 400, |
| 70 | + $font-size: 1rem, |
| 71 | + $line-height: 1, |
| 72 | + $letter-spacing: normal, |
76 | 73 | );
|
77 |
| -``` |
| 74 | +``` |
78 | 75 |
|
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. |
| 76 | +## Typography config |
84 | 77 |
|
| 78 | +A **typography config** is a collection of all typography levels. Angular Material represents this |
| 79 | +config as a Sass map. This map contains the styles for each level, keyed by name. You can create |
| 80 | +a typography config with the `define-typography-config` Sass function. Every parameter for |
| 81 | +`define-typography-config` is optional; the styles for a level will default to Material Design's |
| 82 | +baseline if unspecified. |
85 | 83 |
|
86 |
| -Once the custom typography definition is created, it can be consumed to generate styles via |
87 |
| -different Sass mixins. |
| 84 | +```scss |
| 85 | +@use '~@angular/material' as mat; |
| 86 | + |
| 87 | +$my-custom-typography-config: mat.define-typography-config( |
| 88 | + $display-4: mat.define-typography-level(112px, 112px, 300, $letter-spacing: -0.05em), |
| 89 | + $display-3: mat.define-typography-level(56px, 56px, 400, $letter-spacing: -0.02em), |
| 90 | + $display-2: mat.define-typography-level(45px, 48px, 400, $letter-spacing: -0.005em), |
| 91 | + $display-1: mat.define-typography-level(34px, 40px, 400), |
| 92 | + $headline: mat.define-typography-level(24px, 32px, 400), |
| 93 | + // ... |
| 94 | +); |
| 95 | +``` |
| 96 | + |
| 97 | +To customize component typography for your entire application, you can pass your custom typography |
| 98 | +config to the `core` mixin described in the [theming guide][theming-system]. |
88 | 99 |
|
89 | 100 | ```scss
|
90 |
| -// Override typography CSS classes (e.g., mat-h1, mat-display-1, mat-typography, etc.). |
91 |
| -@include mat-base-typography($custom-typography-theme); |
| 101 | +@use '~@angular/material' as mat; |
92 | 102 |
|
93 |
| -// Override typography for a specific Angular Material components. |
94 |
| -@include mat-checkbox-typography($custom-typography-theme); |
| 103 | +$my-custom-typography: mat.define-typography-config( |
| 104 | + $headline: mat.define-typography-level(3rem, 1, 700), |
| 105 | +); |
95 | 106 |
|
96 |
| -// Override typography for all Angular Material, including mat-base-typography and all components. |
97 |
| -@include angular-material-typography($custom-typography-theme); |
| 107 | +@include mat.core($my-custom-typography); |
98 | 108 | ```
|
99 | 109 |
|
100 |
| -If you're using Material's theming, you can also pass in your typography config to the |
101 |
| -`mat-core` mixin: |
| 110 | +Passing your typography config to `core` mixin will apply your specified values to all Angular |
| 111 | +Material components. If a config is not specified, `core` will emit the default Material Design |
| 112 | +typography styles. |
| 113 | + |
| 114 | +### Typography configs and theming |
| 115 | + |
| 116 | +In addition to the `core` mixin, you can specify your typography config when including any `theme` |
| 117 | +mixin, as described in the [theming guide][theming-system]. Because the `core` mixin always emits |
| 118 | +typography styles, specifying a typography config to a theme mixin results in duplicate typography |
| 119 | +CSS. You should only provide a typography config when applying your theme if you need to specify |
| 120 | +multiple typography styles that are conditionally applied based on your application's behavior. |
| 121 | + |
| 122 | +The following example shows a typical theme definition and a "kids theme" that only applies when |
| 123 | +the ".kids-theme" CSS class is present. You can [see the theming guide for more guidance on defining |
| 124 | +multiple themes](https://material.angular.io/guide/theming#defining-multiple-themes). |
102 | 125 |
|
103 | 126 | ```scss
|
104 |
| -// Override the typography in the core CSS. |
105 |
| -@include mat-core($custom-typography-theme); |
| 127 | +@use '~@angular/material' as mat; |
| 128 | + |
| 129 | +@include mat.core(); |
| 130 | + |
| 131 | +$my-primary: mat.define-palette(mat.$indigo-palette, 500); |
| 132 | +$my-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400); |
| 133 | + |
| 134 | +$my-theme: mat.define-light-theme(( |
| 135 | + color: ( |
| 136 | + primary: $my-primary, |
| 137 | + accent: $my-accent, |
| 138 | + ) |
| 139 | +)); |
| 140 | + |
| 141 | +@include mat.all-component-themes($my-theme); |
| 142 | + |
| 143 | +.kids-theme { |
| 144 | + $kids-primary: mat.define-palette(mat.$cyan-palette); |
| 145 | + $kids-accent: mat.define-palette(mat.$yellow-palette); |
| 146 | + $kids-typography: mat.define-typography-config( |
| 147 | + // Specify "Comic Sans" as the default font family for all levels. |
| 148 | + $font-family: 'Comic Sans', |
| 149 | + ); |
| 150 | + |
| 151 | + $kids-theme: mat.define-light-theme(( |
| 152 | + color: ( |
| 153 | + primary: $my-primary, |
| 154 | + accent: $my-accent, |
| 155 | + ), |
| 156 | + typography: $kids-typography, |
| 157 | + )); |
| 158 | + |
| 159 | + @include mat.all-component-themes($kids-theme); |
| 160 | +} |
106 | 161 | ```
|
107 | 162 |
|
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). |
| 163 | +Each component also has a `typography` mixin that emits only the typography styles for that |
| 164 | +component, based on a provided typography config. The following example demonstrates applying |
| 165 | +typography styles only for the button component. |
110 | 166 |
|
| 167 | +```scss |
| 168 | +@use '~@angular/material' as mat; |
111 | 169 |
|
112 |
| -## Material typography in your custom CSS |
| 170 | +$kids-typography: mat.define-typography-config( |
| 171 | + // Specify "Comic Sans" as the default font family for all levels. |
| 172 | + $font-family: 'Comic Sans', |
| 173 | +); |
113 | 174 |
|
114 |
| -Angular Material includes typography utility mixins and functions that you can use to customize your |
115 |
| -own components: |
| 175 | +// Now we have sweet buttons with Comic Sans. |
| 176 | +@include mat.button-typography($kids-typography); |
| 177 | +``` |
116 | 178 |
|
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. |
| 179 | +## Using typography styles in your application |
| 180 | + |
| 181 | +By default, the `core` and theming mixins only apply styles to Angular Material components. You |
| 182 | +can additionally add CSS classes for styling your application by including the |
| 183 | +`typography-hierarchy` mixin. This mixin emits CSS classes corresponding to each typography level. |
| 184 | +The `typography-hierarchy` mixin also emits styles for native header elements scoped to the provided |
| 185 | +CSS selector, defaulting to `.mat-typography`. The table below lists the the CSS classes |
| 186 | +emitted and the native elements styled. |
| 187 | + |
| 188 | +| CSS class | Level name | Native elements | |
| 189 | +|-------------------------------------|----------------|-----------------| |
| 190 | +| `.mat-display-4` | `display-4` | None | |
| 191 | +| `.mat-display-3` | `display-3` | None | |
| 192 | +| `.mat-display-2` | `display-2` | None | |
| 193 | +| `.mat-display-1` | `display-1` | None | |
| 194 | +| `.mat-h1` or `.mat-headline` | `headline` | `<h1>` | |
| 195 | +| `.mat-h2` or `.mat-title` | `title` | `<h2>` | |
| 196 | +| `.mat-h3` or `.mat-subheading-2` | `subheading-2` | `<h3>` | |
| 197 | +| `.mat-h4` or `.mat-subheading-1` | `subheading-1` | `<h4>` | |
| 198 | +| `.mat-h5` | None | `<h5>` | |
| 199 | +| `.mat-h6` | None | `<h6>` | |
| 200 | +| `.mat-body` or `.mat-body-1` | `body-1` | Body text | |
| 201 | +| `.mat-body-strong` or `.mat-body-2` | `body-2` | None | |
| 202 | +| `.mat-small` or `.mat-caption` | `caption` | None | |
| 203 | + |
| 204 | +In addition to the typographic styles, these style rules also include a `margin-bottom` for |
| 205 | +headers and paragraphs. For `body-1` styles, text is styled within the provided CSS selector. |
| 206 | + |
| 207 | +The `.mat-h5` and `.mat-h6` styles don't directly correspond to a specific Material Design |
| 208 | +typography level. The `.mat-h5` style uses the `body-1` level with the font-size scaled down by |
| 209 | +`0.83`. The `.mat-h6` style uses the `body-1` level with the font-size scaled down by `0.67`. |
| 210 | + |
| 211 | +The `button` and `input` typography levels do not map to CSS classes. |
| 212 | + |
| 213 | +The following example demonstrates the usage of the `typography-hierarchy` mixin. |
125 | 214 |
|
126 | 215 | ```scss
|
127 |
| -@import '~@angular/material/theming'; |
| 216 | +@use '~@angular/material' as mat; |
128 | 217 |
|
129 |
| -// Create a config with the default typography levels. |
130 |
| -$config: mat-typography-config(); |
| 218 | +// Use the default configuration. |
| 219 | +$my-typography: mat.define-typography-config(); |
131 | 220 |
|
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 |
| -} |
| 221 | +// Apply the application hierarchy styles. |
| 222 | +@include mat.typography-hierarchy($my-typography); |
| 223 | +``` |
137 | 224 |
|
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 |
| -} |
| 225 | +```html |
| 226 | +<body> |
| 227 | + <!-- This header will *not* be styled because it is outside `.mat-typography` --> |
| 228 | + <h1>Top header</h1> |
| 229 | + |
| 230 | + <!-- This paragraph will be styled as `body-1` via the `.mat-body` CSS class applied --> |
| 231 | + <p class="mat-body">Introductory text</p> |
| 232 | + |
| 233 | + <div class="mat-typography"> |
| 234 | + <!-- This header will be styled as `title` because it is inside `.mat-typography` --> |
| 235 | + <h2>Inner header</h2> |
| 236 | + |
| 237 | + <!-- This paragraph will be styled as `body-1` because it is inside `.mat-typography` --> |
| 238 | + <p>Some inner text</p> |
| 239 | + </div> |
| 240 | +</body> |
142 | 241 | ```
|
143 | 242 |
|
| 243 | +### Reading typography values from a config |
144 | 244 |
|
145 |
| -[1]: https://material.io/archive/guidelines/style/typography.html |
146 |
| -[2]: https://fonts.google.com/ |
| 245 | +You can read typography style values from a typography config via the following Sass functions. Each |
| 246 | +accepts a typography config and a level. |
| 247 | + |
| 248 | +| Function | Example usage | |
| 249 | +|---------------|---------------------------------------| |
| 250 | +| `font-size` | `mat.font-size($config, 'body-1');` | |
| 251 | +| `font-family` | `mat.font-family($config, 'body-1');` | |
| 252 | +| `font-weight` | `mat.font-weight($config, 'body-1');` | |
| 253 | +| `line-height` | `mat.line-height($config, 'body-1');` | |
| 254 | + |
| 255 | +Addionally, you can use the `typography-level` Sass mixin to directly emit the CSS styles for a |
| 256 | +given typography level. |
| 257 | + |
| 258 | +```scss |
| 259 | +@use '~@angular/material' as mat; |
| 260 | + |
| 261 | +// Use the default configuration. |
| 262 | +$my-typography: mat.define-typography-config(); |
| 263 | + |
| 264 | +.some-class-name { |
| 265 | + @include mat.typography-level($my-typography, 'body-1'); |
| 266 | +} |
| 267 | +``` |
0 commit comments