我该如何覆盖primeng组件的样式?

45

我希望能够按组件级别覆盖primeng组件的样式,而不是整个应用程序。 我必须更改主题中的样式 theme.css 文件或内联样式,但似乎内联样式有时无法按预期工作。 例如,我必须使用

<p-dropdown [options]="cities" formControlName="selectedCity"></p-dropdown>

我需要根据文档更改类名为ui-dropdown-item的样式。

我需要同一个组件使用两种不同的样式,应该采取什么正确的方法?


1
请确保在angular.json文件的底部,将styles.scss放置在最后一行,并覆盖primeng提供的styleClass。例如,<p-dropdown styleClass="dropdown-style">,然后在styles.scss中使用.dropdown-style来覆盖现有的primeng样式。 - iBlehhz
angular.json 中将 styles.css 放在最后一位的这个提示,让我能够删除之前开发人员的 CSS 中很多 !important,并编写更简明的 CSS 规则。 - Rin and Len
8个回答

42

因为>>>已经被弃用,现在需要使用::ng-deep替代。 适用于material2 v6primeng v5.2.*

:host {
    ::ng-deep .prime-slider-override {
        background-color: #26A3D1;
        background-image:none;
        border:none;
        color:white;

        .ui-slider-range {
            background: red;
        }
    }    
}
<p-slider [(ngModel)]="rangeValues"
              styleClass="prime-slider-override"></p-slider>


16
它们俩都已被弃用了吗? - John White

32

尝试使用

:host >>> .ui-dropdown-item {...}

您不需要任何包围的 div 或将样式添加到主 style.css


3
尽管被接受的答案暂时也解决了我的问题,但在 Angular 6+ 中,“穿透影子”操作符将被弃用,因此我们需要找到另一种方式。 https://blog.angular-university.io/angular-host-context/ - AsGoodAsItGets
11
:host ::ng-deep { Your styles } - Alex Beugnet
此外,这是实验性功能。因此,请务必检查您的浏览器兼容性。 - mwalter
对不起,这对我来说没有起作用,恐怕无法满足您的要求。 - java-addict301

22

关闭组件中的视图封装,然后添加样式。

@Component({
 selector: 'new-employee-flow',
 templateUrl: './app/components/my.html',
 styleUrls: ['./app/components/my.css'],
 encapsulation: ViewEncapsulation.None
})

4
这样做意味着每次使用时都需要为每个组件设置样式,这样太冗长了,不太适合。 - Pardeep Jain
1
如果你这样做,你将共享风格并可能导致不良行为。 - Elialber Lopes
我认为前面评论中的“不良行为”是指您失去了封装性,这意味着您的样式将应用于整个应用程序。对于组件来说,通常不希望出现这种情况,这也正是封装性存在的原因之一。 - Koert van Kleef
是的,我同意大部分评论,这只是我使用的临时解决方案。最终我使用了host和/deep/,这应该是理想的选择。 - velsim
3
我认为关闭封装并没有什么问题。如果它被关闭了,那不是不良行为,而只是传统的CSS。只需像在任何其他网站中一样限定您的样式即可。 - elliottregan

10
我所知道的唯一方法是使用:host和::ng-deep这两个被称为“穿透影子CSS组合器”的属性。你可以启用ViewEncapsulation.Native来使用Shadow DOM,但据我了解,它还没有得到广泛的支持。Chrome和Safari支持它,我认为Firefox也可能支持,但IE还有一段时间才能添加该功能。
关于Angular中的View Encapsulation的好文章在这里,关于穿透影子的好文章在这里。您也可以从Angular团队的这里查看有关此文档的信息。
在我的应用程序中,我也使用了PrimeNG。由于我将一个PrimeNG组件导入到一个名为MyComponent的组件中,因此应用于MyComponent的样式将被封装而不会应用于我正在集成的PrimeNG UI元素。穿透影子组合器允许我“穿透”Angular的“模拟”Shadow DOM来为PrimeNG内容设置样式,但这似乎有点混乱并且不理想。我已经寻找了解决此问题的方法,但我不知道有没有其他更好的方法。

8
您想将组件包装在一个带有特定类的div中。
<div class="myOverride">

现在,在您的style.css文件中,您可以通过以下方式针对primeng组件进行定位:
.myOverride .ui-dropdown-item {...} 

这样只有被包装的组件才会被设置样式。


1
首先感谢您的回答,实际上这个方法并不起作用,而且也不是最佳方式,是否有其他选项可以实现相同的功能? - Pardeep Jain
3
由于Angular现在使用模拟视图封装,因此在某些情况下,包括组件在运行时生成元素时,该方法将无法正常工作。我已经通过使用:host和/deep/选择器来解决了这个问题。:host选择组件的根元素,而/deep/将子选择器应用于每个子元素。有关:host和/deep/的更多详细信息,请参见:https://angular.io/docs/ts/latest/guide/component-styles.html#!#special-selectors实际上看起来像是在组件的.scss文件中将:host: /deep/添加到父选择器中。 - jmcmichael
@jmcmichael 我正在尝试在自定义组件中覆盖预定义组件的样式,正如你所指出的,预定义组件在运行时生成元素。我该如何从我的组件中覆盖这些元素的样式? - Nitesh
1
这对我有效。其他建议使用:host和::ng-deep的答案,我相当确定这些已经过时或将会过时。 - Gurnard

4
<p-menubar [model]="items" [style]="{'background-color': 'red'}">
</p-menubar>

3
我们可以使用以下代码覆盖PrimenNg组件的样式。
[style]="{'width':'285px'}" [inputStyle]="{'width':'285px'}"

这仅适用于内联样式。在上述情况下,我正在将自动完成下拉菜单的宽度更改为285px。对我有用。


2
每个组件都配备了一组样式类,使用它们可以修改样式。例如:
 <p-dropdown [options]="cities" [(ngModel)]="selectedCity"></p-dropdown>

相应的样式将会如下所示

.ui-dropdown    {
  background-color:black;
}
.ui-dropdown-label  {
  color:white;
}

.ui-dropdown-label:hover{
  color:red
}
.ui-dropdown-item   {
  color:white;
  background-color:black;
}

LIVE DEMO


如何使Primeng组件(如下拉框和文本框)在<td>元素上透明?td背景颜色将赋予Primeng组件颜色。 - CREM
4
你的解决方案无效,新样式在主要的style.css文件中。同时,我也想改变来自angular样式文件组件的primeng样式,它会将样式注入到<head>标签中。 - jcdsr
1
你有没有机会查看“实时演示”? - Aravind

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