From d259c4bd9824a0affd752f2c799270444f932fc0 Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Mon, 29 Mar 2021 18:03:27 -0700 Subject: [PATCH] docs(material/core): rewrite typography guide for `@use` 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. --- guides/typography.md | 317 +++++++++++++++++++++++++++++-------------- 1 file changed, 215 insertions(+), 102 deletions(-) diff --git a/guides/typography.md b/guides/typography.md index d5790fecc7ce..fa5c82f4b756 100644 --- a/guides/typography.md +++ b/guides/typography.md @@ -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 `

` tag. | -| `title` | `.mat-h2`, `.mat-title` | Section heading corresponding to the `

` tag. | -| `subheading-2` | `.mat-h3`, `.mat-subheading-2` | Section heading corresponding to the `

` tag. | -| `subheading-1` | `.mat-h4`, `.mat-subheading-1` | Section heading corresponding to the `

` 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 `` to load Roboto from Google Fonts. ```html ``` -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 `

` tag. | +| `title` | Section heading corresponding to the `

` tag. | +| `subheading-2` | Section heading corresponding to the `

` tag. | +| `subheading-1` | Section heading corresponding to the `

` 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 -

Jackdaws love my big sphinx of quartz.

-

The quick brown fox jumps over the lazy dog.

-``` +```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 - -

This header is unstyled

+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. - -
-

This header will be styled

-
+```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` | `

` | +| `.mat-h2` or `.mat-title` | `title` | `

` | +| `.mat-h3` or `.mat-subheading-2` | `subheading-2` | `

` | +| `.mat-h4` or `.mat-subheading-1` | `subheading-1` | `

` | +| `.mat-h5` | None | `

` | +| `.mat-h6` | None | `
` | +| `.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 + + +

Top header

+ + +

Introductory text

+ +
+ +

Inner header

+ + +

Some inner text

+
+ ``` +### 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'); +} +```