如何自定义Angular Material组件?新手样式修改失效求助
先解决你当前的样式不生效问题
你在全局styles.scss里写的代码有两个问题:一是全局样式不需要加::ng-deep(它是用来打破组件样式封装的,全局样式本身就没有封装限制);二是代码格式混乱(比如.mat-form-field-label紧挨着上一个选择器的闭合括号,导致SCSS解析错误)。
修正后的全局样式代码如下(可以直接替换你的styles.scss内容):
.mat-form-field { .mat-input-element { color: red; } .mat-form-field-label { color: red; } .mat-form-field-underline { background-color: red; } .mat-form-field-ripple { background-color: red; } .mat-form-field-required-marker { color: red; } }
如果还是不生效,可能是Angular Material自带的样式优先级更高,你可以给样式加!important临时提升优先级(不推荐长期用,更好的方式是用更具体的选择器):
.mat-form-field { .mat-input-element { color: red !important; } /* 其他样式同理 */ }
两种修改Material样式的常用方式
1. 全局样式修改(适合全站统一风格)
直接在styles.scss(全局样式文件)里编写样式,不需要::ng-deep。为了避免影响所有mat-form-field,可以给目标组件加自定义类:
<!-- app.component.html --> <mat-form-field class="custom-red-form"> <input matInput placeholder="Input"> </mat-form-field>
/* styles.scss */ .custom-red-form { .mat-input-element { color: red; } .mat-form-field-label { color: red; } .mat-form-field-underline { background-color: red; } .mat-form-field-ripple { background-color: red; } .mat-form-field-required-marker { color: red; } }
2. 组件内样式修改(仅作用于当前组件)
如果只想让样式生效在某个组件内,就在该组件的.scss文件里用::ng-deep,同时配合:host限定作用范围(避免影响其他组件的Material元素):
/* app.component.scss */ :host ::ng-deep .mat-form-field { .mat-input-element { color: red; } .mat-form-field-label { color: red; } .mat-form-field-underline { background-color: red; } .mat-form-field-ripple { background-color: red; } .mat-form-field-required-marker { color: red; } }
关于View Encapsulation的简单解释
Angular默认给每个组件开启了Emulated样式封装:它会给组件内的DOM元素自动添加一个独特的属性(比如_ngcontent-xxx),同时给组件内的CSS选择器也附加这个属性,这样组件的样式只会作用于自己内部的元素,不会污染全局或其他组件的样式。
而Angular Material组件是独立的子组件,它们的DOM元素没有当前组件的_ngcontent属性,所以你在组件内写的普通样式无法影响到它们。这时候就需要用::ng-deep打破封装,让样式穿透到子组件内部。
更推荐的长期方案:定制Angular Material主题
如果要大规模修改Material组件的外观,不建议一个个写CSS,最好用Angular Material自带的主题定制功能:通过自定义调色板、排版规则,一次性统一所有组件的样式,这样更符合Material设计规范,也更易维护。
内容的提问来源于stack exchange,提问作者ienjir

