How to Style Ng-Bootstrap - Alternative to /Deep/

How to Style ng-bootstrap - Alternative to /deep/

I've done some digging and it is possible to overwrite the ng-bootstrap styles if you turn off the view encapsulation for a component, like so:

@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ExampleComponent {

constructor(public activeModal: NgbActiveModal) { }

}

For example, here I am customizing the styles for a modal dialog, because I assumed that my example component should be shown as a modal dialog and I want its width to be at maximum 70% of the view port in small screen sizes:

.modal-dialog {
@include media-breakpoint-down(xs) {
max-width: 70vw;
margin: 10px auto;
}
}

Please note that turning off the view encapsulation means that the styles for this particular component will be available throughout the application, therefore other components will have access to them and will eventually use them if you are not careful.

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

How to style ng-bootstrap accordion?

Following Solution is for ng-bootstrap version 5.x.x & 6.x.x & Angular 8 & 9

Fade style won't apply if the content of accordion gets removed from the DOM, So, You need to add [destroyOnHide]='false' along with ngb-accordion selector. Now, Content won't get removed from DOM when content gets hidden.

accordion.component.html:

<div class="card">
<div class="card-body">

<!-- ngb Accordion starts -->

<ngb-accordion [destroyOnHide]='false' [closeOthers]="true" activeIds="panel1">

<ngb-panel id="panel1">
<ng-template ngbPanelTitle>
<span>Accordion Item 1 </span>
</ng-template>
<ng-template ngbPanelContent>
Donut caramels sweet roll bonbo
</ng-template>
</ngb-panel>

<ngb-panel id="panel2">
<ng-template ngbPanelTitle>
<span>Accordion Item 2 </span>
</ng-template>
<ng-template ngbPanelContent>
tootsie roll sweet gummi bears chocolate bar.
</ng-template>
</ngb-panel>

<ngb-panel id="panel3">
<ng-template ngbPanelTitle>
<span>Accordion Item 3 </span>
</ng-template>
<ng-template ngbPanelContent>
tootsie roll sweet gummi bears chocolate bar.
</ng-template>
</ngb-panel>

<ngb-panel id="panel4" [disabled]="true">
<ng-template ngbPanelTitle>
<span>Accordion Item 4 </span>
</ng-template>
<ng-template ngbPanelContent>
gummi bears jujubes cotton candy cake marshmallow. Tart cake danish dessert
</ng-template>
</ngb-panel>

</ngb-accordion>

<!-- ngb Accordion ends -->

</div>
</div>

accordion.component.scss :

// collapse toggle
::ng-deep .collapse {
transition: max-height .55s, opacity .35s ease-in-out;
max-height: 0;
opacity: 0;
display: block !important;

&.show {
max-height: 100rem;
opacity: 1;
}
}

::ng-deep .accordion {
.card {
margin-bottom: 0 !important;
border-bottom: 1px solid rgba(0, 0, 0, .04) !important;

.card-header {
// padding-top: 0;
padding: 0;

button {
padding: 1.2rem;
width: 100%;

span {
float: left;
font-size: 1.2rem;
}
}
}

.card-body {
padding: 1rem;
}
}
}

You can see live demo from here.

Style ng-bootstrap accordion with css

As @ChristopherMoore said in his comment, it was a problem due to Shadow DOM. Adding /deep/ fixed it. Here the updated functional code.

  /deep/ .card {
border: none;
}

/deep/ .card-header {
margin-top: 0.75em !important;
border: 1px solid rgba(0, 0, 0, 0.125);
}

/deep/ .card-block {
text-align: left

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

Angular 6 - ng-bootstrap - Style Tabs

For the following template which uses ng-bootstrap tabs:

<ngb-tabset class="tabset1">
<ngb-tab title="Tab 1">
<ng-template ngbTabContent>
Tab 1
</ng-template>
</ngb-tab>
<ngb-tab title="Tab 2">
<ng-template ngbTabContent>
Tab 2
</ng-template>
</ngb-tab>
</ngb-tabset>

you can override the default tab title style with these CSS rules:

:host ::ng-deep .tabset1 a.nav-link {
color: green;
}

:host ::ng-deep .tabset1 a.nav-link.active {
color: red;
font-weight: bold;
}

See this stackblitz for a demo.

Note: If the attribute class="tabset1" is not set on the ngb-tabset element, the selector .tabset1 should be removed from the CSS styles.

How modify CSS of ng-bootstrap carousel using Angular 2

This question has more to do with how styles encapsulation work in Angular rather than something specific to ng-bootstrap, but the short answer is that in the default style encapsulation (from https://angular.io/docs/ts/latest/guide/component-styles.html):

Component styles normally apply only to the HTML in the component's
own template

Since ngb-carousel is not part of the component HTML (it is a different component altogether) you have to force styles to propagate down the components structure:

Use the /deep/ selector to force a style down through the child
component tree into all the child component views. The /deep/ selector
works to any depth of nested components, and it applies to both the
view children and content children of the component

Translating this to your particular problem would mean that you should write:

  styles: [`
/deep/ .carousel-item.active {
border: solid 0.3em;
border-color: red;
}
`]

Here is a live example in a plunker: http://plnkr.co/edit/7J3CItUtSua1zJ7GG1xH?p=preview



Related Topics



Leave a reply



Submit