Typography in Angular Material 18
Tags: angular, angularmaterial, webdev
Published: 2024-06-16 14:06:14

---
title: Typography in Angular Material 18
published: true
description: In this quick guide, we will learn the usage of typography and modifications with CSS variables for Angular Material 18
tags: angular, angularmaterial,webdevelopment
cover_image: https://vercel-og-nextjs-delta-one.vercel.app/api/home?title=Typography%20in%20Angular%20Material%2018&description=Using%20and%20modifying%20typescale%20using%20CSS%20variables
canonical_url: https://angular-material.dev/articles/angular-material-18-typography
---

## Angular Material 18 Project

We will simply use the project from my earlier article [Angular Material Theming with CSS Variables](https://angular-material.dev/articles/angular-material-theming-css-vars). You can clone it from [GitHub](https://github.com/Angular-Material-Dev/angular-material-theming-css-vars).

## The `typography-hierarchy` mixin

`typography-hierarchy` 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.

Let's include it in `src/styles.scss`:

```scss
:root {
  @include mat.all-component-themes($angular-material-theming-css-vars-theme);

  @include mat.typography-hierarchy($angular-material-theming-css-vars-theme); // 👈 Added

  @include mat.system-level-colors($angular-material-theming-css-vars-theme);
  @include mat.system-level-typography($angular-material-theming-css-vars-theme);
}
```

Now if you add header elements, like `<h1>`, you will notice that it has a set of styling applied it to it. Earlier, `<h1>` did not have any custom styling. Try to comment out `typography-hierarchy` to see the difference.

## Generated CSS Classes

The `typography-hierarchy` generates a set of CSS classes based on type scale levels. A **type scale** is a selection of font styles that can be used across an app.

There are `large`, `medium`, and `small` variations for **Display**, **Headline**, **Title**, **Body** and **Label**. You can read more about it [here](https://material.angular.io/guide/typography#type-scale-levels).

The table below lists the CSS classes emitted and the native elements styled:

| CSS class              | Typescale level   | Native Element |
| ---------------------- | ----------------- | -------------- |
| `.mat-display-large`   | `display-large`   | `<h1>`         |
| `.mat-display-medium`  | `display-medium`  | `<h2>`         |
| `.mat-display-small`   | `display-small`   | `<h3>`         |
| `.mat-headline-large`  | `headline-large`  | `<h4>`         |
| `.mat-headline-medium` | `headline-medium` | `<h5>`         |
| `.mat-headline-small`  | `headline-small`  | `<h6>`         |
| `.mat-title-large`     | `title-large`     | None           |
| `.mat-title-medium`    | `title-medium`    | None           |
| `.mat-title-small`     | `title-small`     | None           |
| `.mat-body-large`      | `body-large`      | None           |
| `.mat-body-medium`     | `body-medium`     | None           |
| `.mat-body-small`      | `body-small`      | None           |
| `.mat-label-large`     | `label-large`     | None           |
| `.mat-label-medium`    | `label-medium`    | None           |
| `.mat-label-small`     | `label-small`     | None           |

## Reading typescale properties

There are 2 ways to read:

1. Through `get-theme-typography` SCSS function - You can read more about it [here](https://material.angular.io/guide/theming-your-components#reading-typescale-properties) 
2. Through CSS Variables

Let's see how we can use CSS variables to read typescale properties.

### Through CSS Variables

If you take a look at devtools in browser, you will notice many CSS variables for typography. And it may become difficult to explore around so many variables and find the correct one.

To get the needed CSS variable, you can keep 3 things in mind and it will help you get the correct CSS variable:

1. Pre-typescale levels
   1. `display`
   2. `headline`
   3. `title`
   4. `body`
   5. `label`
2. Variations
   1. `large`
   2. `medium`
   3. `small`
3. Properties
   1. `font` (The CSS font shorthand, includes all font properties except letter-spacing) - No token
   2. `font-family` - `font`
   3. `font-size` - `size`
   4. `font-weight` - `weight`
   5. `line-height` - `line-height`
   6. `letter-spacing` - `tracking`

Now, just use below format to get the correct CSS variable:

```css
.some-class {
    some-property: var(--sys-<pre_typescale_level>-<variation>-<property_token>);
}
```

So, for example, to get `font` of `display-large`, you would write CSS like below:

```css
.display-large-clone {
    font: var(--sys-display-large);

    /* As --sys-display-large-font does not include letter-spacing, make sure to include that, too */
    letter-spacing: var(--sys-display-large-tracking);
}
```

One more example, to get `font-weight` of `<h6>`, you will write CSS like below:

```css
.h6-font-weight {
    font-weight: var(--sys-headline-small-weight)
}
```

## Modifying typescale properties

To modify any of typescale properties, simply override it's CSS variables value.

So, for example, to change `font-size` and `line-height` of `<h1>`, you can write below CSS

```css
:root {
    --sys-display-large-size: 128px;
    --sys-display-large-line-height: 1.25;

    /* <h1> (and display-large) uses --sys-display-large, hence we also need to update that variable to see the changes */
    --sys-display-large: 400 var(--sys-display-large-size) / var(--sys-display-large-line-height) Roboto, sans-serif
}
```

Let's create an input through which user can change the `font-size`s of button labels and headings.

```html
<mat-form-field>
  <mat-label>Flat Button Font Size</mat-label>
  <input
    type="number"
    matInput
    [defaultValue]="14"
    (change)="changeFlatButtonFontSize($event)"
  />
</mat-form-field>
<mat-form-field>
  <mat-label>Heading Font Size</mat-label>
  <input
    type="number"
    matInput
    [defaultValue]="'56.992'"
    (change)="changeHeadingFontSize($event)"
  />
</mat-form-field>
```

```ts
changeFlatButtonFontSize(ev: Event) {
  const size = (ev.target as HTMLInputElement).value ?? '14';

  const targetElement = document.documentElement;
  targetElement.style.setProperty('--sys-label-large-size', size + 'px');
}

changeHeadingFontSize(ev: Event) {
  const size = (ev.target as HTMLInputElement).value ?? '56.992';

  const targetElement = document.documentElement;
  targetElement.style.setProperty('--sys-display-large-size', size + 'px');

  // setting the line-height relationally
  targetElement.style.setProperty('--sys-display-large-line-height', '1.25');

  // <h1> (and display-large) uses --sys-display-large, hence we also need to update that variable to see the changes
  targetElement.style.setProperty(
    '--sys-display-large',
    '400 var(--sys-display-large-size) / var(--sys-display-large-line-height) Roboto, sans-serif'
  );
}
```

Once you make above changes, the output will look like below:

{% embed https://dev.to/shhdharmen/unpublished-video-29pb-4jpd-temp-slug-1155028?preview=b0aa13a5b42132ad1a6e2a587514135cad82e2aef28abc2e307b5a1ea8a8e7a06f917592a72fb4ee5fe0d73dcbb3d625c6c53961677dc51280f19afe %}

## Live Playground

{% embed https://stackblitz.com/github/Angular-Material-Dev/angular-material-theming-css-vars %}