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.
Related
I am using vue js's ELEMENT UI. And i want to override its style. I can do it with global style. But scoped style doesnt work. When i used global style it changes my all pages design. but i want to do it just for one page.
Here is my style(global style. and this is working):
<style>
.el-icon-close:before{
content: "Back" !important;
}
</style>
but when i used scoped it doesnt work:
<style scoped>
.el-icon-close:before{
content: "Back" !important;
}
</style>
Is there any idea about this?
The scoped keyword means that this the changes to the style will apply only to the elements in the current scope. Meaning all custom made elements in the page. If you want to access elements "created" somewhere else you will have to skip the scoped keyword. The code that is in the scoped tag will apply only for the current page/view else it will apply for all pages/views.
All not scoped elements usually are style in the App.vue file. If you want to apply style of element that is not scoped just wrap it in a div add the class to it and style it in the scoped tag:
<style scoped>
.my-custom-div{
.el-icon-close:before{
content: "Back" !important;
}
}
</style>
Atleast that is working with me.
You must use custom class:
.custom-class{
smthng goes here...
}
This is achievable with Deep selectors
For your use case:
<style scoped>
.parent-div /deep/ .el-icon-close:before{
content: "Back" !important;
}
</style>
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.
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.
In the following example I have a Bootstrap button style which is hijacked by the color: inherit entry set by .k-grid of Kendo-UI:
.k-grid a {
color: inherit;
}
<div class="k-grid">
<a class="btn btn-secondary" href="#">Button</a>
</div>
Demo here: http://jsfiddle.net/aq9Laaew/299912/
You can observe that the inherit property of .k-grid a bypasses any other classes passed to the a tag. Eventually the Bootstrap Button is displayed with the wrong color inside a Kendo-grid table.
What is the correct way to fix this? I am not sure that adding a !important to the SASS of Bootstrap is the best solution.
After taking a look at your fiddle, I can see in the inspector that Bootstrap's reset applies the following: a:not([href]):not([tabindex]) {color: inherit;}
On top of this, the anchor in your fiddle doesn't have an href so the above CSS applies.
<link href="http://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="k-grid">
Button
<a class="btn btn-secondary">Button</a>
</div>
So trying to style your button (without a href) with:
.btn-secondary {color: white;} will not work due to CSS specificity.
If you are still confused about CSS specificity, find yourself a specificity calculator like this one and paste both selectors in.
You will find that .btn-secondary is not specific enough to override this rule coming from Bootstrap's reset that applies styles for your button.
Given that kendo-ui is also affecting your button styles with: .k-grid a {color: inherit;}, the best way to solve your issue is by targeting the button with (you guessed it) a selector of higher specificity.
.k-grid a {
color: inherit;
}
.btn.btn-secondary {
color: white;
}
<link href="http://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet" />
<div class="k-grid">
Button
<a class="btn btn-secondary">Button</a>
</div>
I recommend you to understand the css specificity
For example: http://cssspecificity.com
In your case .one-class is less specific than .on-class and an element
The inherit CSS keyword causes the element for which it is specified to take the computed value of the property from its parent element. It can be applied to any CSS property, including the CSS shorthand all.
For inherited properties, this reinforces the default behavior, and is only needed to override another rule.
This would help you :
https://developer.mozilla.org/en-US/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance
If you want to dig in more :
https://developer.mozilla.org/en-US/docs/Web/CSS/inherit ,
https://developer.mozilla.org/en-US/docs/Web/CSS/computed_value
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 ;-)