3

I have a component billing that includes ngb-tabset component of Ng Bootstrap.

ngb-tabset has the following DOM element:

<ngb-tabset _ngcontent-c3="" class="content">
  <!-- Tabset links-->
  <div class="tab-content">
    <div _ngcontent-c3="">
      <!-- Content -->
    </div>
  </div>
</ngb-tabset>

<div class="tab-content"> is dynamically displayed according the selected tab.

In my billing.component.scss, the following snippet doesn't work:

.tab-content {
  padding-right: 120px;
}

The CSS code is correctly compiled and, normally, seen by navigator but not effect on the item.

But if I apply it on the item outside the component, the code works correctly.

Any idea about this strange behavior?

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
clem
  • 799
  • 9
  • 20

2 Answers2

7

Method 1 - Set style classes in the tab content template

View encapsulation isolates the CSS styling of each component, preventing the parent component CSS from affecting the child components. The preferred solution in the present case would be to set the style classes in the tab content template definition. Here is an example:

<ngb-tabset>
  <ngb-tab title="Simple">
    <ng-template ngbTabContent>
      <div class="my-style-1">
        <p>Some content</p>
      </div>
    </ng-template>
  </ngb-tab>
  ...
</ngb-tabset>
.my-style-1 {
  padding-right: 120px;
  color: magenta;
  font-style: italic;
}

See this stackblitz for a demo.


Method 2 - Use the ::ng-deep pseudo-class selector

Another method is to use the ::ng-deep shadow-piercing descendant combinator to style the content of the NgbTabset child component:

::ng-deep .tab-content {
  padding-right: 120px;
}

See this stackblitz for a demo.


Method 3 - Turn off view encapsulation

Alternatively, you could turn off the view encapsulation of the parent component:

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  ...
  encapsulation: ViewEncapsulation.None
})

See this stackblitz for a demo.

ConnorsFan
  • 70,558
  • 13
  • 122
  • 146
  • Regarding method 2, that will currently work but the angular team have deprecated that. https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep – Jamie Rees Mar 22 '19 at 16:25
  • @JamieRees - Yes, `::ng-deep` is deprecated, but I agree with the conclusion of [dudewad](https://stackoverflow.com/a/49308475/1009922) on that subject: use it until Angular specifies what can be used instead. – ConnorsFan Mar 22 '19 at 16:29
  • I use method 3 and it works correctly. Method 1 has no effect, maybe due to ViewEncapsulation. – clem Mar 22 '19 at 18:34
  • @clem - Method 1 should work even with view encapsulation, as shown in [the stackblitz](https://stackblitz.com/edit/angular-qdtu97-41ugex?file=app%2Ftabset-basic.html). – ConnorsFan Mar 22 '19 at 18:36
0

Angular uses shadow DOM. That means it keeps DOM logics separate from other elements. Components have scoped styles of their own. They are encapsulated in a way that the styles should not effect globally. So, if you want to change ngb-tabset's style you have to come out of its scope. That's why you need to use ViewEncapsulation.None.

In @Component decorator use ViewEncapsulation.None

@Component({
selector: ....,
encapsulation: ViewEncapsulation.None,
styles: [...])} 

And, you can use ng-deep also. But you should not use ng-deep because it will be deprecated. See here- https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep

Shofol
  • 693
  • 1
  • 11
  • 26