The Use of /Deep/ and >>> in Angular 2

The use of /deep/ and in Angular 2

  1. Is /deep/ here to stay? Do we have any source, a quote, or anything from any specification saying that it will be adopted? Or if it has officially been deprecated?

    The /deep/ syntax is obsolete, last seen in css-scoping in 2014, and its replacement >>> was deprecated about half a year ago in Chrome 45.

    The entire concept of the shadow-piercing descendant combinator is slated to be removed from the Shadow DOM entirely. Implementations may either remove it altogether or alias it to the regular descendant combinator (which depending on how the Shadow DOM is implemented in the future may or may not make sense).

  2. Can we suppress this error in Visual Studio Code without all-together disabling syntax checking?

    Unfortunately not.

    Angular allows both in emulated view encapsulation for compatibility purposes, but authors are strongly encouraged to use >>> going forward, since /deep/ is technically invalid now, and therefore unsupported in native view encapsulation.

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 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).

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.

Difference between :host::ng-deep .class and .class :host::ng-deep?

First of all, :host and ::ng-deep are Angular constructs, nothing to do with SASS

Now, let's say you have a component named "blog" defined in Angular and blog.component.scss is where you define the SASS for it. Then,

CASE 1 :

:host::ng-deep .content-body {
...
}

will apply style defined to any element with the class .content-body inside the component scope. Eg:

<div>
<blog>
<div class="content-body"></div>
<div class="some-extra-content">
<div class="content-body"></div>
</div>
</blog>
</div>

In the above case, both the class="content-body" divs will have the style applied.

CASE 2 :

.content-body :host::ng-deep {
...
}

will apply style defined to only the component instances which are defined inside an element which has class="content-body"

Eg:

<blog></blog> <!-- Style won't be applied here -->
<div class="content-body">
<blog></blog> <!-- Style will be applied here -->
</div>

You can check a StackBlitz here. In the StackBlitz example, color:red is applied because of CASE 1 inside app.component.css and color:yellow is applied to only one of the hello components because of CASE 2.

Feel free to fork the Stackblitz and play around.

NOTE : If you don't know already, the shadow piercing combinator ::ng-deep is being deprecated

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.

Create deep copy in angular 2

Just use the following function :

/**
* Returns a deep copy of the object
*/

public deepCopy(oldObj: any) :any {
var newObj = oldObj;
if (oldObj && typeof oldObj === "object") {
newObj = Object.prototype.toString.call(oldObj) === "[object Array]" ? [] : {};
for (var i in oldObj)
newObj[i] = this.deepCopy(oldObj[i]);
}
return newObj;
}


Related Topics



Leave a reply



Submit