Adding panelClass to mat-menu does nothing. The problem is that material menu gets rendered using cdk-overlay-pane
, which is outside of the component and imposible to style without using ::ng-deep
, which interferes with other components using overlay panel.
Accoring to documentation:
@Input('class')
panelClass: string
This method takes classes set on the host mat-menu element and applies them on the menu template that displays in the overlay container. Otherwise, it's difficult to style the containing menu from outside the component.
Example of non-working code:
<div class="container" [matMenuTriggerFor]="avatarMenu" matTooltip="{{account?.tenantCode}}">
<span [ngClass]="serverIsReachable ? 'avatar' : 'offline'"></span>
<div class="account" *ngIf="serverIsReachable">
<span class="name">{{account?.firstName + ' ' + account?.lastName}}</span>
<span class="email">{{account?.email}}</span>
</div>
<div class="account" *ngIf="!serverIsReachable">
<span>{{'server-is-unreachable' | translate}}</span>
</div>
</div>
<mat-menu #avatarMenu="matMenu" yPosition="below" panelClass="custom" [overlapTrigger]="false">
<div class="settings">
<label>{{'language'|translate}}</label>
<div class="languages">
<span [ngClass]="{ 'sel': trans.currentLang === 'sr' }" (click)="setLang('sr')">SRP</span>
<span [ngClass]="{ 'sel': trans.currentLang === 'en' }" (click)="setLang('en')">ENG</span>
</div>
</div>
<button mat-menu-item class="logout" (click)="logout()">
<mat-icon>power_settings_new</mat-icon>
<span>{{'logout'|translate}}</span>
</button>
</mat-menu>
Inspecting HTML tree, no classes were applied to any element, even though panelClass
property was set on mat-menu component.
Check the info given above
I want to set position and width of overlay element rendering menu contents.
Linux Mint 18.3
Angular 5.2.8
Angular Material 5.2.3
Typescript 2.7.1
I know that people reported similar issue earlier, but there wasn't any viable explanation or solution given to it.
The property on the menu is called panelClass
, but the Angular input is actually class
(source). Whatever class
you set on the mat-menu
will be proxied to the overlay.
using the "class" input does the job, but this is still a bug, or at least the API documentation is misleading. This bug should not have been closed imho.
Consider should clearly state in official doc, else people might use "panelClass" and lead to the confusion.
hey all, how do we add custom classes to the mat-menu?
I have: .mat-menu-panel .custom {
background-color: darkgrey;
border-radius: 0px;
}
in my global styles file.
And I have <mat-menu #appMenu="matMenu" [class]="custom" [overlapTrigger]="false">
also.
But, the custom styles aren't being applied. Am I doing something wrong? I've also tried to add .cdk-overlay-pane
into the global style but that didn't work either.
@Kempo You're supposed to use the class
input without square brackets unless you're binding it to a property:
<mat-menu #appMenu="matMenu" class="custom" [overlapTrigger]="false">
<!-- Menu contents go here -->
</mat-menu>
@Chan4077 Got it. Even without the brackets, the custom styles aren't being applied. Everything else is the same as above.
Sorry if I'm spamming. But does anyone know what I'm doing wrong?
I have the below code in my styles.scss
class where I do other global style changes.
.mat-menu-panel .custom {
background-color: darkgrey;
border-radius: 0px;
}
And I have my mat-menu html as so:
<mat-menu #appMenu="matMenu" class="custom" [overlapTrigger]="false">
<!-- menu stuff -->
</mat-menu>
But when the mat-menu is rendered, there still is a border-radius and not a dark grey background and it doesn't look like the .custom
class is even being detected or used when I inspect element.
@Kempo you can turn off encapsulation on your component
@Component({
selector: 'my-navbar',
templateUrl: './navbar.component.html',
styleUrls: ['./navbar.component.scss'],
encapsulation: ViewEncapsulation.None
})
but make sure you scope your styles, otherwise, this will affect other components
also this might help you https://material.angular.io/guide/customizing-component-styles
try to use with
::ng-deep .custom {
//whatever your rules
}
try without space between .mat-menu-panel and .custom
.mat-menu-panel.custom {
background-color: darkgrey;
border-radius: 0px;
}
here is how I could override the width of the menu panel:
html
<mat-menu class="dashboard-toolbar-mat-menu-panel">
scss
.dashboard-toolbar-mat-menu-panel {
max-width: 100% !important;
}
ts
@Component({
...
encapsulation: ViewEncapsulation.None
})
try to use with
::ng-deep .custom { //whatever your rules }
Keep the ::ng-deep part, but when you put your class in square brackets, it needs to have single quotes inside double quotes, such as:
[class]="'custom'" This works.
[class]="custom" This does not work. Notice the single quotes inside double quotes above which works.
Hello everyone.
Recently, I had the same issues as everybody here but none of your solutions applies to me. Literally none of them.
I also needed to make the menu fixed width but then, I realised that the menu gets width from the content.
So, what you can do, is create an element that is not part of angular material and give that element its width. For example...
<div class="ProfileBar">
<mat-icon [matMenuTriggerFor]="profileMenu" class="ProfileImage">account_circle</mat-icon>
<mat-menu #profileMenu="matMenu">
<div class="ProfileInfo">
<mat-icon class="ProfileInfo-user-icon">account_circle</mat-icon>
<p class="full-name">Some full name</p>
<p class="nickname">@SomeNickname</p>
</div>
<button (click)="logout()" mat-menu-item>Logout <mat-icon>exit_to_app</mat-icon></button>
</mat-menu>
</div>
So what we have here is a ProfileInfo
class that on which you can put the width normally like this
.ProfileInfo { width: 300px }
or something like that. That will give the menu its width and <mat-menu-item
s will follow that width. You don't even have to make it functional, it can be only like
<mat-menu #profileMenu="matMenu">
<div class="ClassOnlyForTheWidth"></div>
</mat-menu>
and that is it.
On another point, and I don't know if this is going to be of any use to you, you can completely remove material styling by putting [class]="'MyClass'"
. This will remove the material styling all together and, for example, render a button
element natively, depending on the browser you are using, without any styling. If you then do this, [class]="'MyClass mat-menu-item'"
, it will return the styling of the menu item (or any angular component) but then you are back to the issues of this entire github thread.
Enjoy and I hope this will help someone
Try to set the class on
instead of the button that trigger the menu ;-)
not sure why this is closed as this is bug int he API ...
Hello everyone.
Recently, I had the same issues as everybody here but none of your solutions applies to me. Literally none of them.
I also needed to make the menu fixed width but then, I realised that the menu gets width from the content.
So, what you can do, is create an element that is not part of angular material and give that element its width. For example...
<div class="ProfileBar"> <mat-icon [matMenuTriggerFor]="profileMenu" class="ProfileImage">account_circle</mat-icon> <mat-menu #profileMenu="matMenu"> <div class="ProfileInfo"> <mat-icon class="ProfileInfo-user-icon">account_circle</mat-icon> <p class="full-name">Some full name</p> <p class="nickname">@SomeNickname</p> </div> <button (click)="logout()" mat-menu-item>Logout <mat-icon>exit_to_app</mat-icon></button> </mat-menu> </div>
So what we have here is a
ProfileInfo
class that on which you can put the width normally like this
.ProfileInfo { width: 300px }
or something like that. That will give the menu its width and<mat-menu-item
s will follow that width. You don't even have to make it functional, it can be only like<mat-menu #profileMenu="matMenu"> <div class="ClassOnlyForTheWidth"></div> </mat-menu>
and that is it.
On another point, and I don't know if this is going to be of any use to you, you can completely remove material styling by putting
[class]="'MyClass'"
. This will remove the material styling all together and, for example, render abutton
element natively, depending on the browser you are using, without any styling. If you then do this,[class]="'MyClass mat-menu-item'"
, it will return the styling of the menu item (or any angular component) but then you are back to the issues of this entire github thread.Enjoy and I hope this will help someone
@NodeSwapCeo I did but it didn't work. None of the solutions here worked for me.
@crisbeto can you please take a look at this issue? This should not be closed by reports in this thread, as applying the class
property is not only misleading in the documentation, but also, it is not working either.
I created a small example in Stackblitz to demonstrate the not working class. Feel free to change it.
https://stackblitz.com/edit/angular-jrdttp
I created a small example in Stackblitz to demonstrate the not working class. Feel free to change it.
https://stackblitz.com/edit/angular-jrdttp
Hi there, I believe I did not understood your issue, kindly have a look in this exemple the background is changed to be red.
https://stackblitz.com/edit/angular-qxzjsr?file=src/app/app.component.html
I am under the impression that the solution anyway shall to use the CDK to build up your own solution.
On my side I gave up to try to hack the style as it was not clean anyway.
Would it be possible using the cdk overlay, like in this article ? https://mentormate.com/blog/create-modal-window-with-angular-cdk/
I did not try myself yet so not sure at all
I created a small example in Stackblitz to demonstrate the not working class. Feel free to change it.
https://stackblitz.com/edit/angular-jrdttp
Someone changed it already to ::ng-deep in the style section. I did not know that this will work fine. I tried only to set the class and give the class. Also, I could not find anything in the documentation that this is the way to go.
@MyracleDesign I created a small example in Stackblitz too. It's working fine.
https://stackblitz.com/edit/angular-p6m8x3
@MyracleDesign I created a small example in Stackblitz too. It's working fine.
https://stackblitz.com/edit/angular-p6m8x3
Really far better and cleaner css than mine!
@MyracleDesign I created a small example in Stackblitz too. It's working fine.
https://stackblitz.com/edit/angular-p6m8x3Really far better and cleaner css than mine!
That works for backGroundClass but not for class (or panelClass).
If you notice on angular material documentation, input property panelClass is written like this:
@Input('class')
panelClass;
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
try to use with