45

I want to overright the style of primeng components as per component level not for whole app. Either I have to change the style in main theme.css file or inline style, but seems inline not works sometimes as expected. As example, I have to use

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

And I have to change the style of class ui-dropdown-item class name as per documentation.

I need same component with two diff style what is the correct approach for doing this?

Braiam
  • 1
  • 11
  • 47
  • 78
Pardeep Jain
  • 84,110
  • 37
  • 165
  • 215
  • 1
    Make sure styles.scss at the most bottom line in angular.json, then override the styleClass provided by primeng. For example and in styles.scss use .dropdown-style to override the existing primeng style – iBlehhz Jun 10 '19 at 10:23
  • This tip about having styles.css last in the list in `angular.json` allowed me to delete a lot of `!important` from the previous developer's CSS, and write more concise CSS rules. – Rin and Len Feb 04 '22 at 13:52

8 Answers8

42

Since >>> is deprecated have to use ::ng-deep instead. With material2 v6 and primeng 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>
ZR87
  • 1,463
  • 16
  • 27
32

Try using

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

You won't need any surrounded div or adding the styles to the main style.css.

JuanDM
  • 1,250
  • 10
  • 24
jcdsr
  • 1,123
  • 1
  • 17
  • 35
  • 3
    Although the accepted answer did temporarily solve my problem as well, it appears that in Angular 6+ the "shadow piercing" operators will be deprecated, so we need to find another way. https://blog.angular-university.io/angular-host-context/ – AsGoodAsItGets Aug 06 '18 at 09:19
  • 11
    `:host ::ng-deep { Your styles }` – Alex Beugnet Aug 13 '18 at 08:23
  • Additionally this is [experimental functionality](https://developer.mozilla.org/en-US/docs/Web/CSS/:host()). So be sure to check your browser's compatibility. – mwalter Oct 09 '18 at 13:58
  • didn't work for me I'm afraid – java-addict301 Jul 10 '23 at 20:14
22

Disable view encapsulation in your component, and then add the styles,

@Component({
 selector: 'new-employee-flow',
 templateUrl: './app/components/my.html',
 styleUrls: ['./app/components/my.css'],
 encapsulation: ViewEncapsulation.None
})
velsim
  • 553
  • 1
  • 7
  • 17
  • 4
    By doing so you have to style each component every time you use , this is too much lengthy and not suitable process. – Pardeep Jain Mar 07 '17 at 17:30
  • 1
    If you did this, you would be sharing the style and could cause bad behavior – Elialber Lopes Jun 04 '18 at 21:26
  • I think "bad behavior" in previous comment is meant to say: you lose encapsulation, meaning your styles will be applied throughout all of your app. This is usually undesired for components and exactly one of the reasions why encapsulation exists in the first place. – Koert van Kleef Aug 29 '18 at 11:36
  • Yes I agree with most of the comments, this was a temporary fix that I used. I eventually used host and /deep/ which should what be ideally used. – velsim Aug 30 '18 at 13:04
  • 3
    I don't see any issues with turning encapsulation off. If its off, that's not bad behavior, that's just traditional CSS. Just scope your styles the way you would in any other website. – elliottregan Oct 24 '21 at 03:02
10

The only way to do this that I'm aware of is by using the :host and ::ng-deep, called "shadow piercing CSS combinators"

You could enable ViewEncapsulation.Native to employ the Shadow DOM, but my understanding is its not widely supported yet. Chrome and Safari support it, I think Firefox might be there, but IE is still a ways off from adding the feature.

Good article about View Encapsulation in angular here, and a good post about shadow piercing here. You can also view the documentation on this from the Angular team here

In my application im using PrimeNG as well. Since I'm importing a primeNG component into, lets call it MyComponent, that means the styles applied to MyComponent will be encapsulated and wont apply to the primeNG UI elements im incorporating. Shadow piercing combinators allow me to "pierce" through Angular's "emulated" Shadow DOM to style the PrimeNG stuff, but it seems a little messy and not ideal. I've looked for a way around this but I'm not aware of anything.

Dave
  • 627
  • 1
  • 7
  • 17
8

You want to wrap your component in a div with some specific class.

<div class="myOverride">

Now in your style.css you target the primeng component this way:

.myOverride .ui-dropdown-item {...} 

This way only the wrapped component gets styled.

Alexander Ciesielski
  • 10,506
  • 5
  • 45
  • 66
  • 1
    firstly thanks for the answer, actually this is not working also this is not best way is there any other option for the same ? – Pardeep Jain Oct 19 '16 at 13:55
  • 3
    Since Angular now uses emulated ViewEncapsulation, this method will not work in some cases, including when the component generates elements at runtime. I've solved this problem by using the :host and /deep/ selectors. :host selects the component's root element, and /deep/ applies child selectors to every child element. More detail on :host and /deep/ here: https://angular.io/docs/ts/latest/guide/component-styles.html#!#special-selectors What this looks like in practice is simply adding :host: /deep/ to the parent selector in your component's .scss file. – jmcmichael Mar 24 '17 at 18:48
  • @jmcmichael I am trying to override styles of a pre-defined component in my custom component and as you pointed out, the pre-defined component is generating elements at runtime. How can I override style of these elements from my component? – Nitesh Feb 19 '18 at 15:17
  • 1
    this worked for me. the other answers that suggest :host and ::ng-deep I am pretty sure these are/will be deprecated. – Gurnard Oct 29 '20 at 15:37
4
<p-menubar [model]="items" [style]="{'background-color': 'red'}">
</p-menubar>
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
Feng Zhang
  • 1,698
  • 1
  • 17
  • 20
3

We can override the styles of PrimenNg components by using the following code.

[style]="{'width':'285px'}" [inputStyle]="{'width':'285px'}"

This will work for inline style only. In the above case, I am changing the width of autocomplete dropdown to 285px. It worked for me.

Tomer Shetah
  • 8,413
  • 7
  • 27
  • 35
2

Every component is provided with the set of styling classes, using them you can modify the styles, For instance

 <p-dropdown [options]="cities" [(ngModel)]="selectedCity"></p-dropdown>

And the corresponding styles will be as

.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

Aravind
  • 40,391
  • 16
  • 91
  • 110
  • How to make Primeng components like dropdowns and textboxes contained on elements transparent?. The td background color will give the color to the primeng component – CREM Sep 04 '17 at 21:08
  • 4
    your solution doesn't work, the new styles are in the main style.css, I looking as well to change the primeng styles from the angular style file component, which injects the style into the head – jcdsr Jan 03 '18 at 15:00
  • 1
    did you get a chance to look at the `Live Demo` – Aravind Jan 03 '18 at 15:01