Angular Material 9升级后mat-table排序表头多余下边框如何解决
你看到的那条CSS规则是Angular Material 9版本内置的mat-sort-header组件焦点态样式,作用是给键盘导航用户提供焦点位置的视觉提示,属于框架自带代码,不是项目里的业务样式。
之前自行写样式覆盖失败,基本都是两个原因:要么是把样式写在了业务组件的样式文件里,被Angular默认的Emulated视图封装拦住了,无法作用到Material组件的内部DOM;要么是选择器优先级不够,压不过框架自带的样式。
点击页面后边框自动消失,是因为点击动作让表头失去了焦点,CDK的焦点监测服务会自动移除DOM上的cdk-keyboard-focused、cdk-program-focused状态类,对应样式自然就不生效了。
全局覆盖(稳定性最高)
把覆盖规则直接写到项目的全局样式文件(一般是src/styles.scss或者src/styles.css),全局样式不受组件视图封装限制,只要选择器和框架规则匹配就能生效:
[mat-sort-header].cdk-keyboard-focused .mat-sort-header-container, [mat-sort-header].cdk-program-focused .mat-sort-header-container { border-bottom: none !important; }
如果需要兼顾键盘访问的可访问性,不用直接把边框设为none,也可以调整边框颜色、宽度和项目的设计规范对齐。
组件内局部覆盖
如果不想改动全局样式,只需要在当前表格页面去掉这个边框,可以在业务组件的样式文件里用穿透语法绕过视图封装,推荐加上:host前缀把样式限制在当前组件内,避免泄漏到全局:
:host ::ng-deep [mat-sort-header].cdk-keyboard-focused .mat-sort-header-container, :host ::ng-deep [mat-sort-header].cdk-program-focused .mat-sort-header-container { border-bottom: none; }
说明:
::ng-deep虽然被标记为废弃,但目前所有官方维护的Angular版本都支持该语法,在官方推出正式的组件样式穿透替代方案前,这是官方推荐的局部覆盖第三方组件样式的写法。
关闭组件视图封装
如果当前组件需要覆盖的Angular Material默认样式比较多,可以直接在组件装饰器里关闭视图封装,组件内写的所有样式都可以直接作用到子组件,不需要加穿透语法:
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-your-table', templateUrl: './your-table.component.html', styleUrls: ['./your-table.component.scss'], encapsulation: ViewEncapsulation.None })
用这个方案记得给组件的根DOM加一个专属类名,所有组件样式都带上这个类名前缀,避免和其他页面的样式冲突。
内容的提问来源于stack exchange,提问作者ani.lava

