覆盖外部组件封装的CSS

33

我想知道如何覆盖外部组件的封装CSS。

所以我正在我的项目中使用material2组件库,而选项卡组件在tab-body上设置了overflow属性。是否可以覆盖overflow的值?


是的。创建一个比应用溢出更高特异性的CSS选择器。 - hungerstar
但这不会覆盖生成元素的样式。 - Salma Hamed
6个回答

38
你可以使用特殊的 CSS /deep/ 指令。 请查看文档 所以,如果你有:
app
  sub-component
    target-component
      <div class="target-class">...</div>

您可以在您的应用程序中放置 CSS(或 Less):

/deep/ .target-class {
  width: 20px;
  background: #ff0000;
}

显然,您也可以将此 CSS 片段放在子组件中。


8
/deep/已被废弃,主要浏览器不再支持它。请参考Angular文档。因此,建议在CSS中编写一个同名的类target-class,并使用!important属性标记被覆盖的属性。 - Alex Klaus
4
作为一条经验法则,您应该使用CSS 优先级来覆盖之前的声明,并将!important属性作为最后的选择(因为它可能已经被使用过)。在需要覆盖!important时,使用_CSS 优先级_和!important的组合。 - Alex Klaus
1
@AlexKlaus 即使指定更高的规范性,它仍然无法正常工作。 - LppEdd
4
从Angular 8开始,/deep/已经无法编译通过(参见https://github.com/angular/angular/issues/30815)。`::ng-deep`仍然可用。我尝试使用`!important`和CSS特异性,但在许多情况下这两个解决方案都不起作用。 - Pankaj

16

从这篇文章

尽管组件的样式被良好地隔离,但如果需要,它仍然可以轻松被覆盖。为此,我们只需要在页面主体中添加一个属性:

<body override>
    <app></app>
</body>

属性的名称可以是任何内容。不需要值,而名称覆盖使其明显用于什么目的。为了覆盖组件样式,我们可以执行以下操作:

[override] hello-world h1 {
    color:red;
}

其中override是属性,hello-world 是目标组件,而h1则是您要重新样式化的内容。(如果这个不对,则无法生效)

你的组件 hello-world将会

selector: 'hello-world',
styles: [`
   h1 {
      color: blue;
   }
`],
template: ` <h1>Hello world</h1> `

我认为这是最优雅的方式。


或者,如果您正在构建某种库,您可以通过在css中进行一些花哨的操作来完全重置样式:

:host-context(.custom-styles) { //.. 当任何父元素中有css类custom-styles时,此处的css将仅应用于该组件 }

因此,要使用您的组件,您需要使用:

<hello-world class="custom-styles">

但这比第一种选项不方便得多。


2
这太棒了。我同意这比搞 !important 更优雅的解决方案。 - max
我认为最好给body元素添加'override' id而不是'override'属性,因为CSS选择器优先级的原因。 - Koji Hisano

9
::ng-deep .tag-or-css-class-you-want-to-override {    
   /* Add your custom css property value. */    
}

语法::ng-deep用于在不使用ViewEncapsulation.None的情况下覆盖外部CSS类或标记。

ng-deep已经被弃用了相当长的时间。最好禁用viewEncapsulation并将样式包装在组件选择器中。 - Lars Rødal

5

我经常看到这种问题的变体,由于这是该主题的热门问题,我想给出最简单的答案。 ng-deep和类似功能已被弃用,因此最好只依赖基本 CSS。

只需创建具有更高特定性的CSS选择器即可

大多数人(包括我自己)会卡在那里,因为他们不了解两件事:

  1. Angular 视图封装
  2. CSS 特定性

Angular 视图封装

视图封装确保组件内部的 CSS 只影响该组件。要影响其他组件,您需要一些全局 CSS。您可以通过使用像 styles.css 这样的全局样式文件或在组件上禁用视图封装来实现这一点。

@Component({
  ...
  encapsulation: ViewEncapsulation.None
})

CSS特异性

当两个选择器选择同一个元素时,实际应用的CSS是基于特异性来决定的:https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity

你可以通过在CSS选择器中添加更多元素来增加特异性。例如,p.className比仅有.className更为特异。如果你懒得写,只需重复一个类名即可增加特异性。 .className.className.className更为特异。


因此,要覆盖Angular项目中的任何CSS,请进入styles.css并重复类选择器,直到你的CSS比原始CSS具有更高的特异性。

.className.className.className {
  color: red;
}

没生效?再加一个 .className


好的回答,只是我不明白这个全局的styles.css会在哪里声明。 - Cesar Lopes
@CesarLopes 当使用Angular CLI创建新项目时,styles.css会自动生成。您可以通过将全局样式文件的文件路径添加到angular.json文件中的styles数组来手动添加全局样式文件。 - Chris Hamilton

1

只需检查外部组件应用的类(使用检查器或其他工具)。在您的样式css文件中,为选项卡添加相同名称的类,并设置overflow属性,同时添加!important,以确保它覆盖之前的属性。还要确保如果有任何外部组件css链接,您的css链接添加在页面之后。

希望这能帮到你。


1

::ng-deep .css-class-you-want-to-override{

/*您自定义的CSS属性值。如下所示*/

background: white !important;

}


你好!感谢您贡献答案!您能否添加一些关于您的代码如何解决问题的说明?请查看编辑帮助以正确格式化您的代码。 - Jeanne Dark

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