Angular Material Typography not being set correctly

17.3k Views Asked by At

I am trying to implement Angular Material Typography however I have been having some difficulties and I am unsure what may be the issue.

I followed the instructions provided by Angular here however I run into a problem. The problem is that it looks like everything in the appliciation is being affected however some are being overridden with what looks like the default typography and I am unsure what I am doing wrong.

Typography created and used

$typography-configuration: mat-typography-config(
  $font-family: 'Roboto, "Helvetica Neue", sans-serif',
  $display-4: mat-typography-level(112px, 112px, 300),
  $display-3: mat-typography-level(100px, 56px, 400),
  $display-2: mat-typography-level(100px, 48px, 400),
  $display-1: mat-typography-level(100px, 34px, 400),
  $headline: mat-typography-level(100px, 32px, 400),
  $title: mat-typography-level(100px, 32px, 500),
  $subheading-2: mat-typography-level(100px, 28px, 400),
  $subheading-1: mat-typography-level(100px, 24px, 400),
  $body-2: mat-typography-level(100px, 24px, 500),
  $body-1: mat-typography-level(100px, 22px, 400),
  $caption: mat-typography-level(100px, 22px, 400),
  $button: mat-typography-level(100px, 14px, 500),
  $input: mat-typography-level(100px, 1.125, 400)
);

@include angular-material-typography($typography-configuration);

As you can see for the typography I set the first parameter (font size) to 100px on purpose so that I can see if everything on the application is effected.

Example #1: Material Button

For the Angular Material buttons (using 'mat-button' on the html element 'button') I see what I would expected as shown below. The text being set to 100px. enter image description here

Example #2: Toolbar

For the Mat Toolbar however I do not see the font-size set to 100px. It looks like to me as the default font size as shown below is overriding the 100px size:

enter image description here

Example #3: Different Toolbar with multiple override

For the last example on another toolbar we can see that the 100px is added a few times overriding each other each time until the final one that overrides is also 20px so the font size is not 100px.

enter image description here

Details:

The Angular Material guide found here shows that we have 3 ways to use the typography within the application:

// Override typography CSS classes (e.g., mat-h1, mat-display-1, mat-typography, etc.).
@include mat-base-typography($custom-typography);

// Override typography for a specific Angular Material components.
@include mat-checkbox-typography($custom-typography);

// Override typography for all Angular Material, including mat-base-typography and all components.
@include angular-material-typography($custom-typography);

To my understanding the 3rd option I used should apply to anything under where you use class="mat-typography". So I added this to the body of the app as well as tried on the app-root. However as we see above only some of the application is affected correctly.

I tried adding it to smaller parts within the application in components but the outcome ends up the same.

I am not sure if my understanding is wrong and I am not using it correctly or if there is a problem somewhere else, I am assuming I am using it wrong however I cannot find any tutorials and examples created by others surprisingly.

I tried appending the classes myself to items such as class="mat-display-1" which seems to work fine however this doesn't seem like a good solution if I have to apply it everywhere throughout the app.

I would like if possible to have it apply throughout the application without having to set 100s of classes for typography alone.

I know I could do what is suggested here for apply to my own elements in sass, however I think they do it themselves.

2

There are 2 best solutions below

3
On BEST ANSWER

This can occur from a few reasons relating to the order of sass files as well as their functions being called:

Reason:

The reasons this happens is due to the order of sass mixins being called by Angular Material's _theming.scss file which can be found at node_modules\@angular\material\_theming.scss.

The trouble mixin's are mat-core as well as angular-material-typography.

Using a Theme:

When you create a theme and call Angular Material's theming mixin mat-core it has a number of mixins that it includes.

@mixin mat-core($typography-config: null) {
  @include angular-material-typography($typography-config);
  @include mat-ripple();
  @include cdk-a11y();
  @include cdk-overlay();
  @include cdk-text-field();
}

As you can see in the code snippet above angular-material-typography mixin is indeed being called. When mat-core is being called is is looking for a typography configuration, if none is provided it will use a default configuration.

Using a Typography:

When you use only a typography file it is common to see something like below:

@import '~@angular/material/theming';

$typography-configuration: mat-typography-config(
  $font-family: 'Roboto, "Helvetica Neue", sans-serif',
  $display-4: mat-typography-level(112px, 112px, 300),
  $display-3: mat-typography-level(100px, 56px, 400),
  $display-2: mat-typography-level(100px, 48px, 400),
  $display-1: mat-typography-level(100px, 34px, 400),
  $headline: mat-typography-level(100px, 32px, 400),
  $title: mat-typography-level(100px, 32px, 500),
  $subheading-2: mat-typography-level(100px, 28px, 400),
  $subheading-1: mat-typography-level(100px, 24px, 400),
  $body-2: mat-typography-level(100px, 24px, 500),
  $body-1: mat-typography-level(100px, 22px, 400),
  $caption: mat-typography-level(100px, 22px, 400),
  $button: mat-typography-level(100px, 14px, 500),
  $input: mat-typography-level(100px, 1.125, 400)
);

@include angular-material-typography($typography-configuration);

As you can see from the code snippet above we created a typography configuration. As well as we call Angular Material's theming mixin typography-configuration. This will and does set the Typography for you however if you are using both an Angular Material Theme as well as Angular Material Typography you can have cases where your typography is being overridden. This is where the order is the problem.

Incorrect Implementation Causing your Issue:

@import './_theme-master.scss';
@import './theme-typography';
@include mat-core();

For example above: let's say in your styles.scss file you import a theme file containing setting a a themes palette and calling @include angular-material-theme($theme);. After this you decide to import your typography file. Your typography file has a typography configuration as well as you call @include angular-material-typography($typography-configuration); passing your configuration in.

Now after those are done you decided to call your mat-core. At this time your styles are created for your typography and you are happy, however, when calling mat-core Angular creates another set of styles using the default typography configurations. Now those are the newest styles and therefor your styles get overridden with the newest ones created.

Essentially your calling mixins look like this:

@include angular-material-typography($typography-configuration);
@include mat-core();

To fix your issue:

Instead load your typography configuration like this:

@include mat-core($typography-configuration);

Now for the issue of having many typography styles being created and overriding each other. This is most likely due to a file (probably your file which contains your typography) being imported multiple times causing the mixin to recall a few times. Try to place your typography file in 1 central space like calling the file once in styles.scss

1
On

For whoever comes after ngV14 here is what you need to do along with @L1ghtk3ira's answer:

Slight correction as after ngV14 @include mat.core($typography); will not work so you need to make sure it's like @include mat.core(); this.

Please add the below line after your theme declaration @include mat.typography-hierarchy($theme);

They didn't update their docs though this mention in GitHub issues section. Here is the link for you: Github issue page.

In v15 the typography hierarchy isn't included by default anymore. You have to add it yourself with @include mat.typography-hierarchy($theme);

So you need to do something like this:

// Define the palettes for your theme using the Material Design palettes available in palette.scss
// (imported above). For each palette, you can optionally specify a default, lighter, and darker
// hue. Available color palettes: https://material.io/design/color/
$my-primary: mat.define-palette(mat.$indigo-palette);
$my-accent: mat.define-palette(mat.$pink-palette, A200, A100, A400);

// The warn palette is optional (defaults to red).
$my-warn: mat.define-palette(mat.$red-palette);

$my-typography: mat.define-typography-config();


// Create the theme object. A theme consists of configurations for individual
// theming systems such as "color" or "typography".
$my-theme: mat.define-light-theme((
  color: (
    primary: $my-primary,
    accent: $my-accent,
    warn: $my-warn,
  ),
  typography: $my-typography
));

// Include theme styles for core and each component used in your app.
// Alternatively, you can import and @include the theme mixins for each component
// that you are using.
@include mat.all-component-themes($my-theme);
@include mat.typography-hierarchy($my-theme);

Happy Coding :D