I am currently updating an Angular project from v8 to v9, and I have discovered an issue with using CSS class attributes together with Angular Material components. I have also updated to Material v9.
With this simplified HTML,
// Example List 1
<mat-nav-list >
<mat-list-item> SOME HTML.. </mat-list-item>
</mat-nav-list>
// Example List 2
<div >
<mat-list-item> SOME HTML.. </mat-list-item>
</div>
the following SCSS,
[class^="example-list"] {
mat-list-item {
SOME SCSS..
}
}
is only adding style to the <mat-list-item>
in Example List 2, where <div>
is being used.
It works fine if I, for example, use id instead of class in both HTML and SCSS, but I would prefer not to have to do a lot of tinkering with the code.
Update
I have also found out it works fine if I disable Ivy.
"angularCompilerOptions": {
"enableIvy": false
}
Why is it not working with Ivy? Is this expected behavior?
CodePudding user response:
I think you faced a bug that was introduced with Ivy https://github.com/angular/angular/issues/33111
The issue here is the wrong order of adding css classes.
MatNavList
component has a host
property binding within metadata:
@Component({
selector: 'mat-nav-list',
host: {
'role': 'navigation',
'class': 'mat-nav-list mat-list-base',
},
...
})
export class MatNavList
Before Ivy your class was added first to class attribute of element:
<mat-nav-list
with early Ivy version it became the last added class:
<mat-nav-list
As a result your selector doesnt work for second case. But there is an alternative:
[class*="example-list"] {
...
}