如何以及在何处使用 ::ng-deep?
How and where to use ::ng-deep?
我是 Angular 4 的新手,所以谁能解释一下 Angular 4 中如何以及在何处使用 ::ng-deep
?
其实我想从父组件中覆盖子组件的一些CSS属性。另外IE11支持吗?
感谢您的帮助。
通常 /deep/ “shadow-piercing”
组合子可用于将样式强制降低为 child components
。这个选择器有一个别名 >>>,现在有另一个名为 ::ng-deep 的别名。
由于/deep/ combinator
已弃用,建议使用::ng-deep
例如:
<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>
和css
.overview {
::ng-deep {
p {
&:last-child {
margin-bottom: 0;
}
}
}
}
它将应用于子组件
用法
::ng-deep
、>>>
和 /deep/
禁用特定 CSS 规则的视图封装,换句话说,它允许您访问 DOM 元素,它们不在您的组件 HTML 中。例如,如果您正在使用 Angular Material(或任何其他类似的第三方库),一些生成的元素在您的组件区域之外(例如 dialog)并且您无法访问这些元素元素直接或使用常规 CSS 方式。如果你想改变那些元素的样式,你可以使用这三个东西之一,例如:
::ng-deep .mat-dialog {
/* styles here */
}
目前 Angular 团队建议仅使用 EMULATED 视图封装进行 "deep" 操作。
弃用
"deep"操作实际上是deprecated too, BUT it stills working for now, because Angular does pre-processing support (don't rush to refuse ::ng-deep
today, take a look at deprecation practices先)。
无论如何,在采用这种方式之前,我建议您先看看 禁用视图封装 方法(这也不太理想,它允许您的样式泄漏到其他组件中),但在某些情况下,这是更好的方法。如果您决定禁用视图封装,强烈建议使用特定的 类 来避免 CSS 规则交集,最后,避免样式表混乱。在组件的 .ts
文件中禁用它真的很容易:
@Component({
selector: '',
template: '',
styles: [''],
encapsulation: ViewEncapsulation.None // Use to disable CSS Encapsulation for this component
})
您可以在 this 文章中找到有关视图封装的更多信息。
确保不要错过 angular 指南中 ::ng-deep
正上方的 :host-context
的解释:https://angular.io/guide/component-styles。直到现在我都错过了它,希望我能早点看到它。
::ng-deep
在您没有编写组件且无权访问其源代码时通常是必需的,但是 :host-context
在您编写时可能是一个非常有用的选项。
例如,我设计的组件中有一个黑色 <h1>
header,我希望能够在它显示在深色主题背景上时将其更改为白色。
如果我无法访问源代码,我可能必须在 css 中为 parent:
.theme-dark widget-box ::ng-deep h1 { color: white; }
但是 :host-context
您可以在 内部 组件中执行此操作。
h1
{
color: black; // default color
:host-context(.theme-dark) &
{
color: white; // color for dark-theme
}
// OR set an attribute 'outside' with [attr.theme]="'dark'"
:host-context([theme='dark']) &
{
color: white; // color for dark-theme
}
}
这将在组件链中的任何位置查找 .theme-dark
,如果找到,则将 css 应用到 h1。这是一个很好的替代方法,可以避免过度依赖 ::ng-deep
,而 ::ng-deep
虽然经常需要,但有点 anti-pattern.
在这种情况下,&
被 h1
替换(这就是 sass/scss 的工作方式),因此您可以定义 'normal' 和 themed/alternative css 紧挨着,非常方便。
注意获取正确的:
个数。 ::ng-deep
有两个,:host-context
只有一个。
只是更新:
您应该使用 ::ng-deep
而不是 /deep/
,后者似乎已被弃用。
根据文档:
The shadow-piercing descendant combinator is deprecated and support is
being removed from major browsers and tools. As such we plan to drop
support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until
then ::ng-deep should be preferred for a broader compatibility with
the tools.
你可以找到它here
我想强调将 ::ng-deep
限制为仅组件的子组件的重要性,方法是要求父组件是封装的 css class.
为了让它工作,重要的是在父级之后使用 ::ng-deep
,而不是之前,否则它会在加载组件时应用到所有具有相同名称的 classes。
在 ::ng-deep
之前使用 :host
关键字将自动处理此问题:
:host ::ng-deep .mat-checkbox-layout
或者,您可以通过在 ::ng-deep
关键字之前添加范围为 CSS class 的组件来实现相同的行为:
.my-component ::ng-deep .mat-checkbox-layout {
background-color: aqua;
}
组件模板:
<h1 class="my-component">
<mat-checkbox ....></mat-checkbox>
</h1>
Resulting (Angular generated) css 将包含唯一生成的名称并仅应用于它自己的组件实例:
.my-component[_ngcontent-c1] .mat-checkbox-layout {
background-color: aqua;
}
谨慎使用 ::ng-deep。我在整个应用程序中都使用它来将 material 设计工具栏颜色设置为整个应用程序中的不同颜色,结果发现当应用程序测试工具栏颜色时,它们会相互叠加。来找出它是因为这些样式成为全局的,请参阅this article这是一个不会渗入其他组件的工作代码解决方案。
<mat-toolbar #subbar>
...
</mat-toolbar>
export class BypartSubBarComponent implements AfterViewInit {
@ViewChild('subbar', { static: false }) subbar: MatToolbar;
constructor(
private renderer: Renderer2) { }
ngAfterViewInit() {
this.renderer.setStyle(
this.subbar._elementRef.nativeElement, 'backgroundColor', 'red');
}
}
我是 Angular 4 的新手,所以谁能解释一下 Angular 4 中如何以及在何处使用 ::ng-deep
?
其实我想从父组件中覆盖子组件的一些CSS属性。另外IE11支持吗?
感谢您的帮助。
通常 /deep/ “shadow-piercing”
组合子可用于将样式强制降低为 child components
。这个选择器有一个别名 >>>,现在有另一个名为 ::ng-deep 的别名。
由于/deep/ combinator
已弃用,建议使用::ng-deep
例如:
<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>
和css
.overview {
::ng-deep {
p {
&:last-child {
margin-bottom: 0;
}
}
}
}
它将应用于子组件
用法
::ng-deep
、>>>
和 /deep/
禁用特定 CSS 规则的视图封装,换句话说,它允许您访问 DOM 元素,它们不在您的组件 HTML 中。例如,如果您正在使用 Angular Material(或任何其他类似的第三方库),一些生成的元素在您的组件区域之外(例如 dialog)并且您无法访问这些元素元素直接或使用常规 CSS 方式。如果你想改变那些元素的样式,你可以使用这三个东西之一,例如:
::ng-deep .mat-dialog {
/* styles here */
}
目前 Angular 团队建议仅使用 EMULATED 视图封装进行 "deep" 操作。
弃用
"deep"操作实际上是deprecated too, BUT it stills working for now, because Angular does pre-processing support (don't rush to refuse ::ng-deep
today, take a look at deprecation practices先)。
无论如何,在采用这种方式之前,我建议您先看看 禁用视图封装 方法(这也不太理想,它允许您的样式泄漏到其他组件中),但在某些情况下,这是更好的方法。如果您决定禁用视图封装,强烈建议使用特定的 类 来避免 CSS 规则交集,最后,避免样式表混乱。在组件的 .ts
文件中禁用它真的很容易:
@Component({
selector: '',
template: '',
styles: [''],
encapsulation: ViewEncapsulation.None // Use to disable CSS Encapsulation for this component
})
您可以在 this 文章中找到有关视图封装的更多信息。
确保不要错过 angular 指南中 ::ng-deep
正上方的 :host-context
的解释:https://angular.io/guide/component-styles。直到现在我都错过了它,希望我能早点看到它。
::ng-deep
在您没有编写组件且无权访问其源代码时通常是必需的,但是 :host-context
在您编写时可能是一个非常有用的选项。
例如,我设计的组件中有一个黑色 <h1>
header,我希望能够在它显示在深色主题背景上时将其更改为白色。
如果我无法访问源代码,我可能必须在 css 中为 parent:
.theme-dark widget-box ::ng-deep h1 { color: white; }
但是 :host-context
您可以在 内部 组件中执行此操作。
h1
{
color: black; // default color
:host-context(.theme-dark) &
{
color: white; // color for dark-theme
}
// OR set an attribute 'outside' with [attr.theme]="'dark'"
:host-context([theme='dark']) &
{
color: white; // color for dark-theme
}
}
这将在组件链中的任何位置查找 .theme-dark
,如果找到,则将 css 应用到 h1。这是一个很好的替代方法,可以避免过度依赖 ::ng-deep
,而 ::ng-deep
虽然经常需要,但有点 anti-pattern.
在这种情况下,&
被 h1
替换(这就是 sass/scss 的工作方式),因此您可以定义 'normal' 和 themed/alternative css 紧挨着,非常方便。
注意获取正确的:
个数。 ::ng-deep
有两个,:host-context
只有一个。
只是更新:
您应该使用 ::ng-deep
而不是 /deep/
,后者似乎已被弃用。
根据文档:
The shadow-piercing descendant combinator is deprecated and support is being removed from major browsers and tools. As such we plan to drop support in Angular (for all 3 of /deep/, >>> and ::ng-deep). Until then ::ng-deep should be preferred for a broader compatibility with the tools.
你可以找到它here
我想强调将 ::ng-deep
限制为仅组件的子组件的重要性,方法是要求父组件是封装的 css class.
为了让它工作,重要的是在父级之后使用 ::ng-deep
,而不是之前,否则它会在加载组件时应用到所有具有相同名称的 classes。
在 ::ng-deep
之前使用 :host
关键字将自动处理此问题:
:host ::ng-deep .mat-checkbox-layout
或者,您可以通过在 ::ng-deep
关键字之前添加范围为 CSS class 的组件来实现相同的行为:
.my-component ::ng-deep .mat-checkbox-layout {
background-color: aqua;
}
组件模板:
<h1 class="my-component">
<mat-checkbox ....></mat-checkbox>
</h1>
Resulting (Angular generated) css 将包含唯一生成的名称并仅应用于它自己的组件实例:
.my-component[_ngcontent-c1] .mat-checkbox-layout {
background-color: aqua;
}
谨慎使用 ::ng-deep。我在整个应用程序中都使用它来将 material 设计工具栏颜色设置为整个应用程序中的不同颜色,结果发现当应用程序测试工具栏颜色时,它们会相互叠加。来找出它是因为这些样式成为全局的,请参阅this article这是一个不会渗入其他组件的工作代码解决方案。
<mat-toolbar #subbar>
...
</mat-toolbar>
export class BypartSubBarComponent implements AfterViewInit {
@ViewChild('subbar', { static: false }) subbar: MatToolbar;
constructor(
private renderer: Renderer2) { }
ngAfterViewInit() {
this.renderer.setStyle(
this.subbar._elementRef.nativeElement, 'backgroundColor', 'red');
}
}