TLDR: Here is a stackblitz with an example of how to edit a global style using a service rather than ::ng-deep. https://stackblitz.com/edit/angular-ivy-p4pkdu?file=src/app/app.component.html
::ng-deep is an angular feature that promotes the following css to apply globally (everywhere in your application). It should really be avoided, as there is usually a better way to apply global styles. This feature is actually being deprecated, I'll put an alternative at the end of this answer.
html > body > main#app-content is just a CSS selector. In this case we are selecting the main element with id app-content, which has body as a parent, which has html as a parent. Here is a good reference for CSS syntax: https://www.w3schools.com/cssref/css_selectors.asp.
So we are applying these css styles to an html element of type main and with id app-content, the style is applied globally, so it will still persist after the encapsulating component is destroyed.
A better alternative to ::ng-deep is to use a service to edit global styles. First off, any global styles should be stored or imported into the global styles file, usually called styles.css in an angular project. If you only need the style in one component, you can put this css in the respective component css file instead. We declare it as a class so we can add it to an element dynamically.
In styles.css
.noPaddingOrScrollbar {
overflow-y: hidden;
padding: 0;
}
Then generate a service with the cli using ng g service <serviceName>. For example, to generate a service named globalStyleService in a folder called services we do ng g service services/global-style. We'll add a boolean to our service to indicate whether we want the style applied or not.
One caveat is that we need to use setTimeout to set the boolean, to avoid the dreaded NG0100: Expression has changed after it was checked error. setTimeout will default to a timeout of zero, but will still delay the code execution until after Angular finishes a round of change detection.
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class GlobalStyleService {
private _noPaddingOrScrollbar = false;
set noPaddingOrScrollbar(value: boolean) {
//Delay setting until after change detection finishes
setTimeout(() => (this._noPaddingOrScrollbar = value));
}
get noPaddingOrScrollbar() {
return this._noPaddingOrScrollbar;
}
constructor() {}
}
Now you need to find in what component this main#app-content element is actually located. It'll be in the html file of one of the parent components. You can then inject the service into this parent component ts file, and set the class dynamically in the component's html file.
Parent component ts file
export class ParentComponent {
constructor(public globalStyle: GlobalStyleService) {}
...
}
We use the angular directive [class.className]="boolean" to set the class dynamically.
Parent component html file
...
<main
id="app-content"
[class.noPaddingOrScrollbar]="globalStyle.noPaddingOrScrollbar"
></main>
...
Now you can add or remove this class from anywhere in your application. So in the component containing the hacky css, we inject the service, add the style during ngOnInit and remove it during ngOnDestroy. Of course remove the ::ng-deep statement from the css file as well.
Child component ts file
export class MyComponent implements OnInit, OnDestroy {
constructor(private globalStyle: GlobalStyleService) {}
ngOnInit(): void {
this.globalStyle.noPaddingOrScrollbar = true;
}
ngOnDestroy(): void {
this.globalStyle.noPaddingOrScrollbar = false;
}
...
}