SASS子选择器无法找到目标

3

好的,我有以下HTML(通过Angular 6):

<mat-tab-group class="mat-tab-group is-third-party">
<mat-tab-header class="mat-tab-header">

我现在有以下的SASS代码,想要让它正常工作。
 mat-tab-group {
      background-color: yellow;
      height: 100%;
      display: inherit; 

      &.is-third-party {
           background-color: blue;

           mat-tab-header {
                display: none !important;
           }
      }

一切都正常,直到isThirdParty(我添加了蓝色背景来查看发生了什么)。

我尝试了各种组合,以使mat-tab-header被命中,但它并没有起作用。我尝试过类名“.”、子选择器“>”等,但无论我做什么,都无法命中mat-tab-header,因此也无法隐藏它。

我只是涉猎SASS,请问有人能看出我做错了什么吗? 更新:请参见下面的我的图片,HTML中有一些多余的内容,但您可以看到这个SASS的HTML看起来是否正确?

enter image description here


你是说标题没有隐藏? - Huangism
我不明白为什么 mat-tab-header 被点击后会被隐藏。 - Simon
正确的,它仍然可见。我添加的任何样式都不会影响mat-tab-header。 - Simon
代码看起来没问题,你确定你看到的标题是在 mat-tab-group.is-third-party 里面吗? - Huangism
尝试在 mat-tab-header 前添加:& > .mat-tab-header。还有一点需要注意, - dAxx_
dAxx不确定那个评论是否已经完成,但我有&>mat-tab-header {,但仍然无法工作。你似乎也有:,但那似乎无效。 - Simon
2个回答

5
由于 Angular 的 样式封装特性,您的样式不适用于嵌套在您的 Angular 组件中的 Angular Material 组件。默认情况下,组件样式不会被任何嵌套在您组件模板中的组件继承。
您有以下选项来定义适用于其他嵌套在组件中的组件(如您的 Angular Material 组件)的样式:
  • 将样式添加到全局 styles.scss 文件中
  • 保留组件中的样式,并为此组件关闭 视图封装
  • 保留组件中的样式,并使用一个已弃用的影子穿透后代组合器来强制应用于所有子元素的样式。(请参见下面的原始答案)

禁用视图封装

在使用Angular Material组件的组件上禁用视图封装

@Component({
  selector: 'app-mycomp',
  templateUrl: './mycomp.component.html',
  styleUrls: ['./mycomp.component.scss'],
  encapsulation: ViewEncapsulation.None
})

ViewEncapsulation.None 表示 Angular 不进行视图封装。Angular 将 CSS 添加到全局样式中。之前讨论的作用域、隔离和保护规则不适用。这本质上就像将组件的样式粘贴到 HTML 中一样。 Angular Docs

如果关闭视图封装,请确保仅针对您真正想要的 html 元素,因为为此组件定义的样式现在适用于整个 Angular 应用程序(而不仅仅是一个组件)。 (例如,向元素添加自定义 id

我发现当禁用 view encapsulation 时,您可能还需要在 CSS 中使用 !important 来覆盖现有的 Angular Material 样式,而在使用 ::ng-deep 时并不总是需要。


使用::ng-deep

在父选择器前加上::ng-deep

请注意,::ng-deep目前已弃用

::ng-deep mat-tab-group {
  background-color: yellow;
  height: 100%;
  display: inherit; 

  &.is-third-party {
       background-color: blue;

       mat-tab-header {
            display: none !important;
       }
  }
}

那个可以工作,但很快就会被弃用。您能解释一下为什么它可以工作吗?这样也许可以突出另一种解决问题的方法,因为我仍然不完全理解为什么前两个父类没问题,而第三个却有问题... - Simon
我自己也不确定为什么这里需要这个,因为它只需要针对子组件中的HTML元素。我猜这可能与Angular Material的工作方式有关... - frido
好的,那给了我需要的线索...那个类是由Angular Material组件呈现的HTML的一部分。如果我把CSS放到父级别的styles.scss中,它就可以工作了。但我真的想避免这样做。有什么办法吗? - Simon
另一种选择是在您的组件上禁用视图封装:@Component({encapsulation: ViewEncapsulation.None}). 然后,您必须确保仅针对您真正想要的mat-tab-header进行目标定位,而不是子组件中的任何其他标头。可能需要为其添加自定义类。我还没有测试过这个方法,但很快就会尝试,因为我正在处理同样的问题。 - frido
1
我在我的项目中测试了“禁用VIE封装”的方法,它对我有效。我更新了我的答案。 - frido
你想将这个作为答案添加吗?我会将其标记起来。 - Simon

0

在你的Sass中,你有

mat-tab-group {
  background-color: yellow;
  height: 100%;
  display: inherit; 

  &.is-third-party {
       background-color: blue;

       mat-tab-header {
            display: none !important;
       }
  }

应该是这样的(注意 mat-tab-group 前面的“.”)

.mat-tab-group {
  background-color: yellow;
  height: 100%;
  display: inherit; 

  &.is-third-party {
       background-color: blue;

       mat-tab-header {
            display: none !important;
       }
  }

1
那不起作用。注意:黄色和蓝色背景正在显示,因此我的代码现在可以做到这一点,但 mat-tab-header 查询不起作用。 - Simon
同时,.mat-tab-header { display: none !important; } - Adam
尝试了.mat-tab-header。请参见我编辑后的问题,其中包含HTML图像。 - Simon
@robertoLL 这里的问题不在于特定性,而在于Angular的视图封装,正如所选答案所述。 - Chuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接