Fix broken Angular material legacy styles
January 12, 2023
With Angular version 15 many of the Angular material components have been refactored to use the Material Design Components
for web (MDC). This change itself is awesome for all Angular folks because now the accessibility drastically improved and
the components are closer to the official material specs.
However this also means that you need adapt and check your entire application because for some components even the API changed.
To reduce the pain of upgrade (everything at once) Angular is providing the previous material components under a separate
legacy import, e.g. import {MatSelectModule} from '@angular/material/select';
becomes
import {MatLegacySelectModule as MatSelectModule} from '@angular/material/legacy-select';
(important: you really should use
ng update
then the cli will convert all imports automatically).
In my case I wanted to use the legacy components in all places to get the Angular upgrade done and tackle the new style components
afterwards. After I upgraded everything with ng update
nearly everything was broken and looked wrong.
I discovered that the way how you define a theme is now different for Angular Material 15 (See docs).
@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,
),
typography: mat.define-typography-config(),
density: 0,
));
@include mat.all-component-themes($my-theme);
But even with those changes the legacy components still look off.
Solution
We need to include another scss mixin for the core and legacy styles.
@use '@angular/material' as mat;
@include mat.core();
@include mat.legacy-core();
...
...
@include mat.all-component-themes($my-theme);
@include mat.all-legacy-component-themes($my-theme);
If you do not include the all-component-mixin you can also include individual legacy themes. They are always prefixed with legacy-
@include mat.button-theme($my-theme);
@include mat.legacy-button-theme($my-theme);
Personal Blog written by Nicolas Gehlert, software developer from Freiburg im Breisgau. Developer & Papa. Github | Twitter
Add a comment
Comments
Craig Anderson
July 09, 2024
Nico
April 01, 2024
Hi nks, unfortunately the Angular team dropped the support for legacy styles with Angular version 17. For now you need to keep your Material dependency to version 16 and migrate to the regular modules instead. As far as I know Material 16 is perfectly compatible with Angular 17 - but this should really be used for emergencies and you really need to migrate your modules ;)
Best Nico
nks
January 10, 2024
Any solution for Angular 17? I am getting this error
./node_modules/css-loader/dist/cjs.js??ruleSet[1].rules[6].rules[0].oneOf[0].use[1]!./node_modules/postcss-loader/dist/cjs.js??ruleSet[1].rules[6].rules[0].oneOf[0].use[2]!./node_modules/resolve-url-loader/index.js??ruleSet[1].rules[6].rules[1].use[0]!./node_modules/sass-loader/dist/cjs.js??ruleSet[1].rules[6].rules[1].use[1]!./src/styles.scss?ngGlobalStyle - Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js): Undefined mixin. ╷ 10 │ @include mat.legacy-core(); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ ╵ src\styles.scss 10:1 root stylesheet
× Failed to compile.
Khaled Sharafuddin
October 18, 2023
Your solution worked like magic for many parts of my UI
before you answered my last question, I’d added a question in SO with +300 points. I’ll like if you can add your same answer there so I can award them to you. There are only couple of days left.
I still have difficulties with other parts of the dialog UI, but I was able to fix many areas with that solution.
Nico
October 18, 2023
Hi Khaled,
awesome, thanks for this tip. Just added the answer.
Let me know if you have any more questions.
Best
Nico
Nico
October 16, 2023
Hi Khaled, thanks for your question. This is a mistake in the article. It should be $my-theme everywhere :)
Hi Ravi, can you try adding the config path to the Angular.json config? I will answer in stackoverflow as well. Hope this helps.
Best regards Nico
Khaled
October 13, 2023
Could you please explain where was the $app-theme declared and where did it come from? You defined the $my-theme: mat.define-light-theme(( but don’t see definition of $app-theme
Thank you!
Kotresha A M S
September 26, 2023
Great Article, it saved me from migration blocker. Thanks Nicolas
Ravi
June 07, 2023
I have client.scss file that was written based on @angular/material@11 but recently I got requirement to update the client.scss to be compatible with @angular/material@15.
Also, I changed scss file compiler from node-sass to dart sass( formally known as sass).
I’m getting compilation errors when I try to compile the newly updated client.scss file. The errors are related to imports.
I have created a question on stackoverflow but unfortunately I haven’t got any answers.
Can someone please help me in fixing the issue?
Here is the link to stackoverflow question - https://stackoverflow.com/questions/76370395/scss-file-compilation-error-with-angular-material15
Zuhair
May 30, 2023
Thanks so much for this blog, I also had my material form fields broken after 14 to 15 angular upgrade, In my case the migrate path had put the legacy mixin at wrong place.
Blueice
April 09, 2023
Hi, That was great information for our project while upgrade material 14 to 15. We tried your solution but it didn’t work until some search and find it solution because of missing information. We should add this line
“@include mat.all-legacy-component-typographies();”
Thanks
Stas
April 03, 2023
The very important part is missing, it makes work all component the are under mat-form-field @include mat.all-legacy-component-typographies();
Michael
March 10, 2023
Thanks so much <3
Torsten
March 07, 2023
Many thanks from mee, too.
Christophe
February 15, 2023
Hi, Thanks for the post! It saves my week! Everything works fine after that.
I clearly regret my migration. It was so simple before … Material 15 is just awfull (to stay polite) and unnecessarily complicated … especially with its default fixed font-sized inputs, making all components look enormous and ugly. Before it was herited from the context … it was so simple and intuitive. Now you need to code dozen of sass lines to get it worked (and need to know complex sass things to do a simple css changes)
In my opinion, they make a very wrong step and they gonna loose fans. Myself, I am thinking about quiting Material and finding something simpler to manipulate.
So thank you very much for this piece of code which works like a charm. For your information, I had to replace “$app-theme” by “$my-theme” in the last line.
++ Christophe
it would be helpful to see what the names of the files are that are changing, and what the original contents were.