Angular2 Styling Issues Caused by Dom Attributes _Ngcontent-* VS. _Nghost-*

Angular2 styling issues caused by DOM attributes _ngcontent-* vs. _nghost-*

Well,

I found the answer myself. Using the default settings, you must not supply the wrapping my-comp element selector in the components css.

Instead use the * element selector to affect all elements nested in my-comp. Otherwise, angular will treat the my-comp selector as an additional element and thus add the _ng-content-* attribute, which of course is not present in the DOM.

Another option is to disable ViewEncapsulation for your component - be aware that it just affects the component my-comp

import {Component, ViewEncapsulation} from 'angular2/core'

@Component({
selector: 'my-comp',
encapsulation: ViewEncapsulation.None,
...
});

https://egghead.io/lessons/angular-2-controlling-how-styles-are-shared-with-view-encapsulation explains the three different settings modes perfectly.

Styles in component for D3.js do not show in angular 2

Update

Angular and SASS agreed on supporting ::ng-deep (instead of >>> or /deep/) a while ago until ::slotted or whatever makes it into browser standards becomes available in all browsers.

ViewEncapsulation.Emulated (default)

That's by design. Angular adds class names unique to components and rewrites the added styles to only apply to the components where they were added.

D3 generates HTML dynamically without Angulars knowledge and Angular can't apply the classes to make the styles apply on the generated HTML.

If you add the styles at the entry point HTML file, Angular also doesn't rewrite the styles and the added helper classes don't take effect.

ViewEncapsulation.None

With encapsulation: ViewEncapsulation.None Angular doesn't do this rewriting, therefore the result is similar to adding the HTML to the index.html.

"Shadow-piercing"

Alternatively you can use the recently introduced shadow piercing CSS combinators >>>, /deep/ and ::shadow (::shadow is just replaced by a and thus very limited). See also https://stackoverflow.com/a/36225709/217408 and the Plunker

:host /deep/ div {
color: red;
}

SASS

/deep/ works fine with SASS but the alias >>> doesn't.

The shadow-piersing CSS combinators are rewritten by Angular and they don't need to be supported by the browsers. Chrome supported them for a while but they are deprecated - but as said, that doesn't matter, because Angular rewrites them to use its encapsulation emulation.

ViewEncapsulation.Native

Angular doesn't support any way to style such components from the outside. Only if the browser provides support like CSS variables then these can be used.

What does _ngcontent-c# mean in Angular?

_ngcontent-c# attributes are added when you use ViewEncapsulation.Emulated - which is default. Angular uses these attributes to target specific elements with the styles. The number c is sort of a unique identifier of the host component. For example, if you have two components with the following templates:

ComponentA
<span></span>
<comp-b></comp-b>

ComponenB
<h1></h1>

Angular will mark all elements with styles inside component A as _ngcontent-c0 and all elements with styles inside component B with _ngcontent-c1:

<comp-a>
<span _ngcontent-c0></span>
<comp-b _ngcontent-c0>
<h1 _ngcontent-c1></h1>
</comp-b>
</comp-a>

How to style ng-content

update

::slotted is now supported by all new browsers and can be used with ViewEncapsulation.ShadowDom

https://developer.mozilla.org/en-US/docs/Web/CSS/::slotted

original

::content xxx { ... } might work as well or :host xxx { ... }. The shimming is not very strict or accurate. AFAIK (>>> /deep/ old) ::ng-deep (supported by SASS) and a space do currently the same.

Attributes set on Angular 5 Component host element not taking effect within jsPlumb

Setting :host{display: block;} will solve the problem.

You can not directly access selector of template as it's not in the component scope to apply CSS.

The :host selector is the only way to target the host element. You
can't reach the host element from inside the component with other
selectors because it's not part of the component's own template. The
host element is in a parent component's template.

Angular Docs: https://angular.io/guide/component-styles#host



Related Topics



Leave a reply



Submit