CSS 一个组件导致另一个组件出现不需要的格式
CSS of one component causing unwanted formatting in another
我还在学习Angular、CSS和HTML(这三个都是新的),所以请耐心等待我。
我收到了一些代码,并被赋予了修复一些格式的任务。
问题是:
首次加载页面时,页眉有一些填充。见左下图。
但是,当我导航到另一个页面时,该页面包含以下代码:
/* Removing padding and scroll bar from main page */
::ng-deep html > body > main#app-content {
overflow-y: hidden;
padding: 0;
}
然后导航到任何其他 component/page,填充消失了,所有内容都一直移动到屏幕左侧,这非常烦人。见右下图。注意:有人告诉我这是导致这种情况的代码,我实际上不知道它实际上在做什么(除了设置填充和 y-scroll)。
这张照片显示了两个 components/pages 在我使用上面的代码访问页面之前(显示在图片的左侧),然后在我使用上面的代码导航到该页面之后(显示在 t 上)嗯在图片的右侧)。请注意,绿线供参考,以显示填充是如何消失的。
所以我想在使用上面的代码访问页面后导航回原来的padding/formatting。
此外,有人可以向我解释为什么这样做吗?如果可能的话,代码的实际含义是什么?以下是一些具体问题:
- 我怎样才能阻止这种情况发生在另一个页面上?
- “::ng-deep html > body > main#app-content”是什么意思?
- 大号有什么作用?
TLDR: 这是一个 stackblitz,其中包含一个示例,说明如何使用服务而不是 ::ng-deep
来编辑全局样式。 https://stackblitz.com/edit/angular-ivy-p4pkdu?file=src/app/app.component.html
::ng-deep
是一项 angular 功能,可促进以下 css 全局应用(在您的应用程序中的任何地方)。它真的应该避免,因为通常有更好的方法来应用全局样式。此功能实际上已被弃用,我将在本答案末尾放置一个替代方案。
html > body > main#app-content
只是一个 CSS 选择器。在本例中,我们选择具有 id
app-content
的 main
元素,其父元素为 body
,父元素为 html
。这是 CSS 语法的一个很好的参考:https://www.w3schools.com/cssref/css_selectors.asp.
所以我们将这些 css 样式应用到类型为 main
且 ID 为 app-content
的 html 元素,该样式是全局应用的,因此它仍然会封装组件销毁后仍然存在。
::ng-deep
更好的替代方法是使用服务来编辑全局样式。首先,任何全局样式都应该存储或导入到全局样式文件中,通常在 angular 项目中称为 styles.css
。如果你只需要一个组件中的样式,你可以将这个 css 放在相应的组件 css 文件中。我们将其声明为 class 以便我们可以将其动态添加到元素中。
在styles.css
.noPaddingOrScrollbar {
overflow-y: hidden;
padding: 0;
}
然后使用 ng g service <serviceName>
通过 cli 生成服务。例如,要在名为 services
的文件夹中生成名为 globalStyleService
的服务,我们需要执行 ng g service services/global-style
。我们将向我们的服务添加一个布尔值以指示我们是否要应用样式。
一个警告是我们需要使用 setTimeout
来设置布尔值,以避免可怕的 NG0100: Expression has changed after it was checked
错误。 setTimeout
将默认超时为零,但仍会延迟代码执行,直到 Angular 完成一轮更改检测。
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() {}
}
现在您需要找到这个 main#app-content
元素实际位于哪个组件中。它将位于父组件之一的 html 文件中。然后就可以在这个父组件的ts文件中注入服务,在组件的html文件中动态设置class
父组件ts文件
export class ParentComponent {
constructor(public globalStyle: GlobalStyleService) {}
...
}
我们使用 angular 指令 [class.className]="boolean"
来动态设置 class。
父组件html文件
...
<main
id="app-content"
[class.noPaddingOrScrollbar]="globalStyle.noPaddingOrScrollbar"
></main>
...
现在您可以在应用程序的任何位置添加或删除此 class。所以在包含 hacky css 的组件中,我们注入服务,在 ngOnInit
期间添加样式并在 ngOnDestroy
期间删除它。当然,也要从 css 文件中删除 ::ng-deep
语句。
子组件ts文件
export class MyComponent implements OnInit, OnDestroy {
constructor(private globalStyle: GlobalStyleService) {}
ngOnInit(): void {
this.globalStyle.noPaddingOrScrollbar = true;
}
ngOnDestroy(): void {
this.globalStyle.noPaddingOrScrollbar = false;
}
...
}
我还在学习Angular、CSS和HTML(这三个都是新的),所以请耐心等待我。
我收到了一些代码,并被赋予了修复一些格式的任务。
问题是:
首次加载页面时,页眉有一些填充。见左下图。
但是,当我导航到另一个页面时,该页面包含以下代码:
/* Removing padding and scroll bar from main page */
::ng-deep html > body > main#app-content {
overflow-y: hidden;
padding: 0;
}
然后导航到任何其他 component/page,填充消失了,所有内容都一直移动到屏幕左侧,这非常烦人。见右下图。注意:有人告诉我这是导致这种情况的代码,我实际上不知道它实际上在做什么(除了设置填充和 y-scroll)。
这张照片显示了两个 components/pages 在我使用上面的代码访问页面之前(显示在图片的左侧),然后在我使用上面的代码导航到该页面之后(显示在 t 上)嗯在图片的右侧)。请注意,绿线供参考,以显示填充是如何消失的。
所以我想在使用上面的代码访问页面后导航回原来的padding/formatting。
此外,有人可以向我解释为什么这样做吗?如果可能的话,代码的实际含义是什么?以下是一些具体问题:
- 我怎样才能阻止这种情况发生在另一个页面上?
- “::ng-deep html > body > main#app-content”是什么意思?
- 大号有什么作用?
TLDR: 这是一个 stackblitz,其中包含一个示例,说明如何使用服务而不是 ::ng-deep
来编辑全局样式。 https://stackblitz.com/edit/angular-ivy-p4pkdu?file=src/app/app.component.html
::ng-deep
是一项 angular 功能,可促进以下 css 全局应用(在您的应用程序中的任何地方)。它真的应该避免,因为通常有更好的方法来应用全局样式。此功能实际上已被弃用,我将在本答案末尾放置一个替代方案。
html > body > main#app-content
只是一个 CSS 选择器。在本例中,我们选择具有 id
app-content
的 main
元素,其父元素为 body
,父元素为 html
。这是 CSS 语法的一个很好的参考:https://www.w3schools.com/cssref/css_selectors.asp.
所以我们将这些 css 样式应用到类型为 main
且 ID 为 app-content
的 html 元素,该样式是全局应用的,因此它仍然会封装组件销毁后仍然存在。
::ng-deep
更好的替代方法是使用服务来编辑全局样式。首先,任何全局样式都应该存储或导入到全局样式文件中,通常在 angular 项目中称为 styles.css
。如果你只需要一个组件中的样式,你可以将这个 css 放在相应的组件 css 文件中。我们将其声明为 class 以便我们可以将其动态添加到元素中。
在styles.css
.noPaddingOrScrollbar {
overflow-y: hidden;
padding: 0;
}
然后使用 ng g service <serviceName>
通过 cli 生成服务。例如,要在名为 services
的文件夹中生成名为 globalStyleService
的服务,我们需要执行 ng g service services/global-style
。我们将向我们的服务添加一个布尔值以指示我们是否要应用样式。
一个警告是我们需要使用 setTimeout
来设置布尔值,以避免可怕的 NG0100: Expression has changed after it was checked
错误。 setTimeout
将默认超时为零,但仍会延迟代码执行,直到 Angular 完成一轮更改检测。
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() {}
}
现在您需要找到这个 main#app-content
元素实际位于哪个组件中。它将位于父组件之一的 html 文件中。然后就可以在这个父组件的ts文件中注入服务,在组件的html文件中动态设置class
父组件ts文件
export class ParentComponent {
constructor(public globalStyle: GlobalStyleService) {}
...
}
我们使用 angular 指令 [class.className]="boolean"
来动态设置 class。
父组件html文件
...
<main
id="app-content"
[class.noPaddingOrScrollbar]="globalStyle.noPaddingOrScrollbar"
></main>
...
现在您可以在应用程序的任何位置添加或删除此 class。所以在包含 hacky css 的组件中,我们注入服务,在 ngOnInit
期间添加样式并在 ngOnDestroy
期间删除它。当然,也要从 css 文件中删除 ::ng-deep
语句。
子组件ts文件
export class MyComponent implements OnInit, OnDestroy {
constructor(private globalStyle: GlobalStyleService) {}
ngOnInit(): void {
this.globalStyle.noPaddingOrScrollbar = true;
}
ngOnDestroy(): void {
this.globalStyle.noPaddingOrScrollbar = false;
}
...
}