Angular material 5 dark theme not applied to body
Solution 1
I had the same issue and found this solution on the Angular Material GitHub issue#3298 (post by JamieStill).
I wrapped all of my app.component.html content in a div
<div class="mat-typography app-frame mat-app-background">
<app-header></app-header>
<main>
<app-post-create></app-post-create>
<app-post-list></app-post-list>
</main>
</div>
And in app.component.css
html, body, app-root, .app-frame {
overflow: hidden;
margin: 0;
height: 100%;
box-sizing: border-box;
color: #e0e0e0;
}
I've only tested this in a practice app in Angular 6, but I suspect it will work in Angular 5 as well.
Before:
After:
Solution 2
if you add angular material after your project has started, you simply have to manually add mat-app-background class to your body element in your index.html as below:
<body class="mat-typography mat-app-background">
...
</body>
Solution 3
Only vh-100 mat-app-background
in app.component.html
<div class="vh-100 mat-app-background">
<router-outlet></router-outlet>
</div>
Solution 4
I'm not sure why you are you manipulating the CDK overlay container. That seems unnecessary. Just bind your theme classes to the document body. See https://stackblitz.com/edit/angular-ndmju6.
Snippet:
theme: string = 'Light';
constructor(private renderer: Renderer2) {
this.renderer.addClass(document.body, 'indigo-pink');
}
toggleTheme(): void {
if (this.theme === 'Light') {
this.theme = 'Dark';
this.renderer.addClass(document.body, 'indigo-pink-dark');
this.renderer.removeClass(document.body, 'indigo-pink');
} else {
this.theme = 'Light';
this.renderer.addClass(document.body, 'indigo-pink');
this.renderer.removeClass(document.body, 'indigo-pink-dark');
}
}
Solution 5
Late in the game, but try to set height to 100%. This is what fixed it for me. Here dark-theme is a global class that has my Angular Material dark theme in it. I put this HTML in app.component.html.
<div class="mat-app-background dark-theme" style="height: 100%;">
<app-root></app-root>
</div>
This was using Angular 9.
danwellman
Author and front-end developer jQuery tutorials and other blog posts by Dan Wellman My new video series Learning Grunt is now available!
Updated on June 08, 2022Comments
-
danwellman almost 2 years
I've created a "custom" theme, (using the theming documentation at https://material.angular.io/guide/theming, which is pretty bad) like this:
@import '~@angular/material/theming'; @include mat-core(); $ip-primary: mat-palette($mat-indigo); $ip-accent: mat-palette($mat-pink, A200, A100, A400); $ip-theme: mat-light-theme($ip-primary, $ip-accent); $ip-theme-dark: mat-dark-theme($ip-primary, $ip-accent); .indigo-pink { @include angular-material-theme($ip-theme); } .indigo-pink-dark { @include angular-material-theme($ip-theme-dark); }
My index.html contains this:
<body class="mat-app-background mat-typography"> <app-root></app-root> </body>
In the container for the
app-root
component, I switch between my custom class names (indigo-pink
andindigo-pink-dark
) using this:<div [ngClass]="appTheme">
I am also setting the CDK overlay container class to my custom class name using this:
setContainerClass(className: string): void { const containerClassToKeep = 'cdk-overlay-container'; const overlayClassList = this.overlayContainer.getContainerElement().classList; const existingClasses = Array.from(overlayClassList); existingClasses.forEach(classToken => { if (classToken !== containerClassToKeep) { overlayClassList.remove(classToken); } }); overlayClassList.add(className); }
The main problem is that when I switch into the dark theme, I do see the
indigo-pink-dark
class name get added to my app component container correctly, but only some styles change (e.g. the toolbar at the top goes dark, and Material components) - the body of the page stays white. The theming guide (and other blog posts) say that using themat-app-background
should fix this exact problem.Additionally though, if I try manually update the background-color of the body, using e.g.
.indigo-pink-dark { @include angular-material-theme($ip-theme-dark); body & { background-color: #000; } }
Then this "background-color" just overlays the entire page and you cannot see any elements on the page. This is something to do with the CDK overlay, because if I remove the part that adds the class name to the overlay, it kind of works - the background of the page does get set correctly, but then overlays do not get correct styling.
-
danwellman about 6 yearsPrimarily because the documentation says that you have to do this, and partly because overlay components were not being styled correctly before I added that part. The reason it works in the stackblitz is because you're using the sidenav-container component. But I am not using this, and would rather avoid it if possible. But thanks
-
G. Tranter about 6 yearsRight - I see. I think the problem is class hierarchy. Basically you define all of the Angular Material styling as a child of your light and dark theme classes. This works for the main app element (everything in it is a child), but the overlay element is not a child - it is a sibling. What needs to happen is to have the theme classes applied to <body> so that the overlay element is a child. That would also work for the main app element because it is also a child of <body>.
-
danwellman about 6 yearsThanks, yes. Unfortunately, the body is outside of the root of my app, and as such I cannot access it with Angular. In NG1x we could make the body the root of the app, but in NG2+ it does not seem possible.
-
G. Tranter about 6 yearsActually you can access it - you can inject the document or renderer object into the constructor of your app controller and add/remove classes (sorry for inline formatting):
constructor(private renderer: Renderer2) { this.renderer.addClass(document.body, 'indigo-pink'); }
. This won't work in stackblitz I don't think. -
Gishu about 3 yearsThanks.. the mat-app-background class on the body class did it for me. Before that controls on the main/app component were invisible - only seen on focus. Your tip made the dark theme complete :)
-
Robert about 2 yearsDoes it still work if you add a mat-select with mat-option?