PrimeNg styleClass not change style of p-panel - css

I am using primeNg. My .html and .scss file like below. But I can't give any styleClass to p-panel. What is wrong in my code?
.html file
<p-panel header="Student Info" styleClass="test">
<div class="ui-g">
<div class="ui-g-12 ui-md-3">
<div class="ui-g-12">
<b>Student</b>
</div>
</div>
</p-panel>
.scss file
.test {
margin-top: 50px;
}

To apply a CSS style to a child component, use ::ng-deep. See this stackblitz for a demo.
:host ::ng-deep .test {
margin-top: 50px;
}
According to Angular documentation:
Component styles normally apply only to the HTML in the component's
own template.
Use the /deep/ shadow-piercing descendant combinator to force a style
down through the child component tree into all the child component
views. The /deep/ combinator works to any depth of nested components,
and it applies to both the view children and content children of the
component.
Use /deep/, >>> and ::ng-deep only with emulated view encapsulation.
Emulated is the default and most commonly used view encapsulation.
...
::ng-deep should be preferred for a broader compatibility with the
tools.
An alternative solution is to set the view encapsulation of the component to ViewEncapsulation.None.
Another alternative is to define the style globally in styles.css, as shown for the second panel in the stackblitz.

One more solution is to use the parent element of <p-panel> element. So for,
<div class="panel-container">
<p-panel>
..
</p-panel>
</div>
We could simply have a class as:
.panel-container div.ui-panel-titlebar {
..
}
and/or
.panel-container div.ui-panel-content {
..
}
BTW to fix #HasanOzdemir's problem we could simply add a little padding to the top of parent element ;-)

Related

*ngIf for style tag

My problem does not appear to be solvable by using traditional ways of conditional styling, like [ngStyle] or [ngClass]. I want to conditionally define a CSS-selector using :host ::ng-deep, for example:
<style *ngIf='preventXScroll'>
:host ::ng-deep .p-datatable-wrapper {overflow-x: hidden !important;}
</style>
But doing it this way always applies the style, regardless of the actual state of preventXScroll. Any ideas?
Actually, the problem can be solved via [ngClass].
Template:
<div class='outer-wrapper' [ngClass]='{"prevent-x-scroll": preventXScroll}'>
<p-table>
...
</p-table>
</div>
Stylesheet:
:host ::ng-deep .prevent-x-scroll .p-datatable-wrapper {
overflow-x: hidden !important;
}
This way the style is only applied to p-datatable-wrapper (within p-table child component) while it is contained in prevent-x-scroll.

How do I change the Background Color of the middle of mat-expansion-panel (when expanded)?

<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
This is the expansion title
</mat-panel-title>
<mat-panel-description>
This is a summary of the content
</mat-panel-description>
</mat-expansion-panel-header>
<p>This is the primary content of the panel.</p>
</mat-expansion-panel>
How do I change the mat-panel-description area (and only the mat-panel-description area so it is a different background color (e.g. red)?
I've tried various styles but cannot seem to get the entire background of that particular background to change (while keeping the header and footer their original colors).
Using chrome dev tools, adding a background-color to the following .mat-expansion-panel-body works, e.g.:
.mat-expansion-panel-body {
background-color: red;
}
But this does not work when I try to put this in my stylesheet (or even via inline style).
Note: This also works when I put this in my global stylesheet (styles.css) -- but I want to avoid doing this if possible.
Here is a screenshot where I have a red circle indicating the area I want to change the background-color for.
Thanks
in Angular use /deep/ to change styles for material component to force the style down with Emulated encapsulation without changing the encapsulation, so try this:
/deep/ .mat-expansion-panel-body {
background-color: red;
}
or ::ng-deep since /deep/ is deprecated
::ng-deep .mat-expansion-panel-body {
background-color: red;
}
add encapsulation property into your #Component decorator
encapsulation: ViewEncapsulation.None
and then you can simply add styles in your css file.
.mat-expansion-panel-body {
background-color: red;
}
Hope this helps!!
I ended up solving this using global styles, but using a component-specific class as a parent (to prevent overriding all occurrences of .mat-expansion-panel-body)
I chose this method because I didn't want to use deprecated ng-deep or mess with my component's encapsulation.
expansion-overview-example.component.html
<div class="expansion-overview-example">
<p>This is the primary content of the panel.</p>
</div>
styles.css
.expansion-overview-example .mat-expansion-panel-body {
background-color: red;
}

CSS From Parent Component Not Applying to Child Component Angular 9

I have a component nested within a component with a bunch of HTML. In the parent component, I am trying to have the CSS written there apply to the nested component.
Example:
/* this is within the parent css */
button{
color: red;
}
But then in the child the component's button is not red.
I am linking the components like so:
<!-- this is within the HTML of the parent -->
<div>
<nested-component></nested-component>
</div>
You can prepend :host ::ng-deep to achieve this.
:host ::ng-deep button {
color: red;
}

How to apply a component's [ngClass] to its child element

Is there a way to allow ngClass to be set on a parent element, but redirect it so the classes are actually applied to a child element?
<!-- Parent Component -->
<app-progress-bar [ngClass]="someObject"><!-- Specify [ngClass] here… -->
</app-progress-bar>
<!-- Child Component -->
<div class="progress-bar" [ngClass]="ngClass"><!-- …but it actually applies here -->
<progress [max]="max" [attr.value]="value">
</progress>
</div>
Obviously this could be done by using a custom #Input on the parent component, then feeding that input into the [ngClass] declaration in the child. Can it be done directly without an intermediary property?
You could achieve this with the ::ng-deep selector. The css styles will be applied on the app-progress-bar component but the styles will be activated on the child.
:host {
.some-style-evaluated-by-ng-class {
::ng-deep .progress-bar {
background: red;
}
}
}
ng-deep
The shadow-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such we plan to drop support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until then ::ng-deep should be preferred for a broader compatibility with the tools.

Why :host-context is required when :host can suffice the needs in Angular

As I understand :host-context is used to apply styles based on selector of parent.
Lets consider a rule as follows:
:host-context(.red-theme) { background-color: red; }
same can be written using :host selector as folows:
.red-theme :host { background-color: red; }
Then whh is host-context explicitly required?
Use :host if you want to style the component custom HTML element itself.
Where as :host-context is used when you also want to have a component apply a style taking into account context in which component is rendered.
So for example, you could do: (with host-context)
<div class="red-theme">
<app-component></app-component>
</div>
where app-component
<button class="btn btn-theme">Button</button>
and the component style is defined:
:host-context(.red-theme) .btn-theme {
background: red;
}
Useful if you want to have multiple alternative themes on your web application.
:host and :host-context are not Angular features, but CSS features.
Within the demo provided at stackblitz.com/edit/angular-z3xxtu, the Angular components are merged into the DOM and allow plain old CSS selector structure like .parent :host .child { color: red; }.
This changes when using Webcomponents and ShadowDOM.
The ShadowDOM acts as a barrier and encapsulates the contained markup and style, so the .parent cannot style the things on the :host and vice versa. Note cannot is not totally true, see ::part and CSS Custom Properties.
With a structure like <parent> <my-component> ShadowDOM <child> the above CSS rule no longer works and :host-context(.parent) (which could be read as .parent :host) is needed. Sadly as of 2023-01-10 this doesn't work in Firefox and Safari.
In the above demo, :host-context(.red) { color: red; } and .red :host { color: red; } produce the same output because there's no ShadowDOM involved. On top of that, Angular transforms the invalid .test :host in the CSS to .test [_nghost-some-id] which is a valid CSS selector.

Resources