components: Adding panelClass to mat-menu does nothing
Bug:
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.
What is the expected behavior?
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>
What is the current behavior?
Inspecting HTML tree, no classes were applied to any element, even though panelClass
property was set on mat-menu component.
What are the steps to reproduce?
Check the info given above
What is the use-case or motivation for changing an existing behavior?
I want to set position and width of overlay element rendering menu contents.
Which versions of Angular, Material, OS, TypeScript, browsers are affected?
Linux Mint 18.3 Angular 5.2.8 Angular Material 5.2.3 Typescript 2.7.1
Is there anything else we should know?
I know that people reported similar issue earlier, but there wasn’t any viable explanation or solution given to it.
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 7
- Comments: 26 (2 by maintainers)
try to use with
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.
The property on the menu is called
panelClass
, but the Angular input is actuallyclass
(source). Whateverclass
you set on themat-menu
will be proxied to the overlay.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.I created a small example in Stackblitz to demonstrate the not working class. Feel free to change it. https://stackblitz.com/edit/angular-jrdttp
@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.@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
@MyracleDesign I created a small example in Stackblitz too. It’s working fine.
https://stackblitz.com/edit/angular-p6m8x3
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.
try without space between .mat-menu-panel and .custom
.mat-menu-panel.custom { background-color: darkgrey; border-radius: 0px; }