如何在Angular 4中使用::ng-deep
?它可以用于哪里呢?
实际上,我想从父组件覆盖某些子组件的CSS属性。此外,在IE11上支持吗?
如何在Angular 4中使用::ng-deep
?它可以用于哪里呢?
实际上,我想从父组件覆盖某些子组件的CSS属性。此外,在IE11上支持吗?
通常可以使用/deep/ "穿透"
组合器将样式强制运用到子组件
。这个选择器有一个别名 >>> ,现在还有另一个称为::ng-deep
的别名。
由于/deep/ 组合器
已被弃用,建议使用::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
只应用于组件的子元素,需要在父元素中要求使用封装的CSS类。
为了使其生效,重要的是在父元素之后使用::ng-deep
而不是在之前,否则它将在组件加载时立即应用于所有具有相同名称的类。
在::ng-deep
之前使用:host
关键字会自动处理这个问题:
:host ::ng-deep .mat-checkbox-layout
或者,您可以在::ng-deep
关键字之前添加组件范围的CSS类来实现相同的行为:
.my-component ::ng-deep .mat-checkbox-layout {
background-color: aqua;
}
组件模板:
<h1 class="my-component">
<mat-checkbox ....></mat-checkbox>
</h1>
生成的(Angular 生成的)CSS 将包括唯一生成的名称,并仅应用于其自身的组件实例:
.my-component[_ngcontent-c1] .mat-checkbox-layout {
background-color: aqua;
}
my-component ::ng-deep...
简直就是救了我的一天。我整天都在尝试使用 ng-deep 给我的组件应用样式,但是我却把所有的组件,甚至整个应用程序的样式都覆盖掉了。 - Cristiano Bombazar::ng-deep
、>>>
和/deep/
可以禁用特定CSS规则的视图封装,换句话说,它可以让你访问不在组件HTML中的DOM元素。例如,如果你正在使用Angular Material(或任何其他类似的第三方库),一些生成的元素位于组件区域之外(比如dialog),你不能直接访问这些元素或使用常规的CSS方法访问它们。如果你想要改变这些元素的样式,你可以使用其中的一个,例如:
::ng-deep .mat-dialog {
/* styles here */
}
目前Angular团队建议只使用模拟视图封装来进行"deep"操作。
"deep"操作实际上也已经被弃用,但是它仍然可以使用,因为Angular提供了预处理支持(不要急于拒绝今天的::ng-deep
,先看一下弃用做法)。
无论如何,在使用这种方式之前,我建议您先看一下禁用视图封装方法(这也不是理想的选择,它允许样式泄漏到其他组件中),但在某些情况下,它是更好的方法。 如果您决定禁用视图封装,则强烈建议使用特定的类来避免CSS规则交叉,并最终避免在样式表中造成混乱。 禁用视图封装非常容易,只需在组件的.ts
文件中进行即可:
@Component({
selector: '',
template: '',
styles: [''],
encapsulation: ViewEncapsulation.None // Use to disable CSS Encapsulation for this component
})
你可以在这篇文章中找到有关视图封装的更多信息。
ViewEncapsulation.None
!这会使样式可以泄露到其他组件中,从而造成很大的损坏。 - Alex Klaus::ng-deep
正上方的 :host-context
的解释: https://angular.io/guide/component-styles。我之前就错过了这个解释,真希望早点看到它。::ng-deep
,但是当你可以访问组件源代码时,:host-context
可能是一个非常有用的选项。<h1>
标题,如果显示在深色主题背景上,我想要将其更改为白色。.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虽然经常必要,但有点反模式。theme-dark
,则可以使用:host(.theme-dark)
。这完全取决于您的站点CSS设计。此外,属性在CSS中可以非常有用,并且可以以复杂的方式组合,例如:host([theme='dark']:not([dayofweek='tuesday']))
。 - Simon_Weaver.theme-light
类的容器内,而该容器又嵌套在具有.theme-dark
的容器内,则仍将选择theme-dark
并应用CSS。但是,这是“modernizr”类型类的绝佳解决方案,或者如果您全局设置了主题并且只设置一次。 - Simon_Weaver更新:
应该使用::ng-deep
而不是已经过时的/deep/
。
根据文档:
穿透影子DOM的后代组合器已被弃用,并且正在从主要浏览器和工具中删除支持。因此,我们计划在Angular中放弃对所有3个选择器(即/deep/,>>>和::ng-deep)的支持。在那之前,应优先考虑使用::ng-deep以获得更广泛的工具兼容性。
您可以在此处找到它。
我查看了所有的答案,发现没有人提到子组件可以从其父组件中传递样式CSS。
在组件的ts文件中,您可以使用以下代码:
@Input() styles: any = {};
[ngStyle]="styles"
在父级中,您可以使用以下代码:
<yourComponent [styles]="{backgroundColor: 'blue', 'font-size': '16px'}">
谨慎使用 ::ng-deep。我在整个应用程序中使用它来将材料设计工具栏颜色设置为不同的颜色,结果发现当应用程序在测试中时,工具栏颜色会相互干扰。后来发现这是因为这些样式变成了全局的,请参见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');
}
}
/deep/
和::ng-deep
都已被弃用,我建议您查看此答案https://dev59.com/8VYN5IYBdhLWcg3wuKC5#49308475以获取更多详细信息和解决方案的评论。 - Ferie