How and where to use ::ng-deep?
Usually /deep/ “shadow-piercing”
combinator can be used to force a style down to child components
. This selector had an alias >>> and now has another one called ::ng-deep.
since /deep/ combinator
has been deprecated, it is recommended to use ::ng-deep
For example:
<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>
and css
.overview {
::ng-deep {
p {
&:last-child {
margin-bottom: 0;
}
}
}
}
it will be applied to child components
What is the the scope of ::ng-deep?
:ng-deep is global. No matter where you put it, it applies to all components. Not just children.
If you use :host :ng-deep, then it will work from that component down (Into the children, grand children etc).
The main issue working with ng-deep is that styles in Angular are lazy loaded. So in some cases, you can be viewing the site perfectly fine, then you view a particular page that uses ng-deep, then you can go back to previous pages that were fine that are now broken because the ng-deep style is applied site wide. e.x. https://tutorialsforangular.com/2020/04/13/the-dangers-of-ng-deep-bleeding/
Generally speaking, if I need to style a child component slightly differently depending on where it's placed, then I create an input variable for the child, make the parent set it, then make it a class somewhere in the child component HTML. The child component can then style that class how it see's fit and you haven't had to break encapsulation.
How to access CSS of Angular child component with ::ng-deep
This solution to the problem is this:
:host ::ng-deep app-operator-filter{
.header-logos-card {
grid-template-columns: repeat(4,1fr) !important;
}
}
!important was a crucial addition as the changes were being overwritten without it.
What to use in place of ::ng-deep
FWIW In my research I have not found any replacement for ng-deep or the other applicable alternatives. This is because, I believe, the Angular team is deferring to the W3C spec on the shadow dom, which initially had selectors such as deep
. However, the W3c has since removed the recommendation, but not replaced it with a new one. Until that happens, I imagine that the Angular team will keep ::ng-deep
and it's alternatives available, but in deprecated state due to the pending state of W3C's drafts. I am not able to take the time to find the documentation to back this up right now but I did see it recently.
Long story short: Keep using ::ng-deep
and its alternatives until a replacement is created - the deprecation is just an early notice so that people aren't blindsided whenever the actual change materializes.
-- UPDATE --
https://drafts.csswg.org/css-scoping-1/
Here is the draft proposal if you're interested. It appears that they are working on a robust set of selectors for elements within a shadow dom tree; it is this spec, once approved, that I think will inform the angular clone, if there even is one (i.e. angular may not need to implement their own selectors once this goes live in browsers).
::ng-deep changes other components style
Answer is add parent class to dialog and use
::ng-deep
to apply styles for that component only
You can add class to dialog as shown below
const dialogRef = this.dialog.open(DialogOverviewExampleDialog, {
width: '250px',
data: {name: this.name, animal: this.animal},
panelClass: 'my-parent-class'
});
and add styles as
.my-parent-class ::ng-deep table {
border-collapse: collapse;
border-spacing: 0;
border:2px solid black;
}
.my-parent-class ::ng-deep th {
border:2px solid black;
}
.my-parent-class ::ng-deep td {
border:1px solid black;
}
Explanation: Material dialog is a dynamic component
Static component HTML
<table _ngcontent-c0>...</table>
Static component CSS
table[_ngcontent-c0] { ... }
Dynamic component HTML
<table>...</table>
Dynamic component CSS
table { ... }
Notice the difference for static component attribute _ngcontent-c0
is added by angular, Angular use this Technic to create component specific styles (To apply styles for that particular component), but for dynamic component no attribute is being added. This is the reason your static component styles not applied to dynamic component
To make this work we used ::ng-deep
before any class to remove that attribute _ngcontent-c0
and select dynamic component, so when ::ng-deep
is used your styles are no more component specific (it will be applied to all components). This is the reason we use parent class to apply styles for that component only and dynamically created component too.
how to use ng-deep with dynamic data
You can add dynamic CSS by injecting it into the <style>
element directly.
Example :
data = { fontSize : '13px' };
const textCss = `::ng-deep .text-huge {
font-size: ${data.fontSize};
}`
document.getElementsByTagName('style')[0].append(textCss);
NOTICE: The code above will add your CSS to the first style element in your document
Or you can create a style element and inject it directly to your component with your dynamic CSS.
How to use ng-deep at media query syntax inside?
::ng-deep
does work inside a media query... something else must be off for your specific case;
relevant CSS in typeahead-basic.ts:
::ng-deep .dropdown-menu.show { background:lightblue;}
::ng-deep .dropdown-item { color:red !important; }
@media screen and (max-width:768px){
::ng-deep .dropdown-menu.show { background:lightgreen;}
::ng-deep .dropdown-item { color:orange !important; }
}
complete working stackblitz here
update: for your shared stackblitz, the correct syntax is below... you gotta check your page on the widths between 1025px
and 1280px
and you will see the effect in action:
@media (min-width:1025px) and (max-width: 1280px) {
::ng-deep .third-party-content{
left:30px;
position: absolute;
color:red;
}
}
Use of ::ng-deep recommendation in angular
It's recommended to avoid using ng-deep
as it is marked deprecated.
See here in the angular documentation
There has been raised a question what's the alternative here on stackoverflow
Related Topics
Margin on Child Element Moves Parent Element
Can CSS Detect the Number of Children an Element Has
How to Really Isolate Stylesheets in the Google Chrome Extension
On a CSS Hover Event, How to Change Another Div'S Styling
Can a CSS Class Inherit One or More Other Classes
Hiding the Scroll Bar on an HTML Page
Custom CSS Scrollbar For Firefox
Using Only Css, Show Div on Hover Over Another Element
How to Select a Range of Elements in Repeated Pattern
How to Make Background-Size Work in Ie
Line Before and After Title Over Image
Disable Less-Css Overwriting Calc()
How to Define Colors as Variables in Css
Which CSS Properties Create a Stacking Context
How to Get a Parent Element to Appear Above Child