CSS 如何以及在何处使用 ::ng-deep?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/46786986/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 12:46:00  来源:igfitidea点击:

How and where to use ::ng-deep?

cssangularangular-template

提问by Jeyabalan Thavamani

I'm new to Angular 4, so could anyone please explain how and where to use ::ng-deepin Angular 4?

我是 Angular 4 的新手,所以有人可以解释一下::ng-deep在 Angular 4 中如何以及在哪里使用吗?

Actually I want to overwrite some of the CSS properties of the child components from the parent components. Moreover is it supported on IE11?

实际上我想从父组件覆盖子组件的一些 CSS 属性。此外,它是否支持 IE11?

回答by Sajeetharan

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.

通常 /deep/ “shadow-piercing”组合器可用于将样式强制降为child components. 这个选择器有一个别名 >>> 并且现在有另一个名为 ::ng-deep 的选择器。

since /deep/ combinatorhas been deprecated, it is recommended to use ::ng-deep

由于/deep/ combinator已被弃用,建议使用::ng-deep

For example:

例如:

<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>

<div class="overview tab-pane" id="overview" role="tabpanel" [innerHTML]="project?.getContent( 'DETAILS')"></div>

and css

css

.overview {
    ::ng-deep {
        p {
            &:last-child {
                margin-bottom: 0;
            }
        }
    }
}

it will be applied to child components

它将应用于子组件

回答by Commercial Suicide

USAGE

用法

::ng-deep, >>>and /deep/disable view encapsulation for specific CSS rules, in other words, it gives you access to DOM elements, which are not in your component's HTML. For example, if you're using Angular Material (or any other third-party library like this), some generated elements are outside of your component's area (such as dialog) and you can't access those elements directly or using a regular CSS way. If you want to change the styles of those elements, you can use one of those three things, for example:

::ng-deep>>>/deep/禁用特定 CSS 规则的视图封装,换句话说,它使您可以访问 DOM 元素,而这些元素不在您的组件的 HTML 中。例如,如果您使用 Angular Material(或任何其他类似的第三方库),则某些生成的元素在组件区域之外(例如dialog),并且您无法直接访问这些元素或使用常规 CSS道路。如果你想改变这些元素的样式,你可以使用这三样东西之一,例如:

::ng-deep .mat-dialog {
  /* styles here */
}

For now Angular team recommends making "deep"manipulations only with EMULATEDview encapsulation.

目前,Angular 团队建议仅使用EMULATED视图封装进行“深度”操作。

DEPRECATION

弃用

"deep"manipulations are actually deprecatedtoo, BUTit stills working for now, because Angular does pre-processing support (don't rush to refuse ::ng-deeptoday, take a look at deprecation practicesfirst).

“深度”操作实际上也被弃用了,它现在仍然有效,因为 Angular 确实支持预处理(::ng-deep今天不要急于拒绝,先看看弃用实践)。

Anyway, before following this way, I recommend you to take a look at disabling view encapsulationapproach (which is not ideal too, it allows your styles to leak into other components), but in some cases, it's a better way. If you decided to disable view encapsulation, it's strongly recommended to use specific classes to avoid CSS rules intersection, and finally, avoid a mess in your stylesheets. It's really easy to disable right in the component's .tsfile:

无论如何,在遵循这种方式之前,我建议您查看禁用视图封装的方法(这也不理想,它允许您的样式泄漏到其他组件中),但在某些情况下,这是一种更好的方法。如果你决定禁用视图封装,强烈建议使用特定的类来避免 CSS 规则交叉,最后,避免样式表混乱。在组件的.ts文件中禁用它真的很容易:

@Component({
  selector: '',
  template: '',
  styles: [''],
  encapsulation: ViewEncapsulation.None  // Use to disable CSS Encapsulation for this component
})

You can find more info about the view encapsulation in thisarticle.

您可以找到有关在视图中封装更多信息文章。

回答by Simon_Weaver

Make sure not to miss the explanation of :host-contextwhich is directly above ::ng-deepin the angular guide : https://angular.io/guide/component-styles. Disclaimer: I missed it up until now and wish I'd seen it sooner.

确保不要错过角度指南:host-context正上方的解释::ng-deephttps: //angular.io/guide/component-styles。免责声明:直到现在我都错过了它,希望我早点看到它。

::ng-deepis often necessary when you didn't write the component and don't have access to its source, but :host-contextcan be a very useful option when you do.

::ng-deep当您没有编写组件并且无法访问其源代码时,这通常是必要的,但在您编写时:host-context可能是一个非常有用的选项。

For example I have a black <h1>header inside a component I designed, and I want the ability to change it to white when it's displayed on a dark themed background.

例如,我<h1>设计的组件中有一个黑色标题,我希望能够在它显示在深色主题背景上时将其更改为白色。

If I didn't have access to the source I may have to do this in the css for the parent:

如果我无权访问源代码,我可能必须在父级的 css 中执行此操作:

.theme-dark widget-box ::ng-deep h1 { color: white; }

But instead with :host-contextyou can do this insidethe component.

但是,: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
     }
 }

This will look anywhere in the component chain for .theme-darkand apply the css to the h1 if found. This is a good alternative to relying too much on ::ng-deepwhich while often necessary is somewhat of an anti-pattern.

这将在组件链中的任何位置查找.theme-dark并将 css 应用到 h1(如果找到)。这是一个很好的替代方案,可以避免过度依赖::ng-deep,而这种依赖虽然经常是必要的,但在某种程度上是一种反模式。

In this case the &is replaced by the h1(that's how sass/scss works) so you can define your 'normal' and themed/alternative css right next to each other which is very handy.

在这种情况下,&被替换为h1(这就是 sass/scss 的工作方式),因此您可以将“普通”和主题/替代 css 定义在彼此相邻的位置,这非常方便。

Be careful to get the correct number of :. For ::ng-deepthere are two and for :host-contextonly one.

小心获取正确的:. 因为::ng-deep有两个,而且:host-context只有一个。

回答by Vedran

I would emphasize the importance of limiting the ::ng-deepto only children of a component by requiring the parent to be an encapsulated css class.

我会强调::ng-deep通过要求父组件是一个封装的 css 类来限制组件的唯一子组件的重要性。

For this to work it's important to use the ::ng-deepafter the parent, not before otherwise it would apply to all the classes with the same name the moment the component is loaded.

为此,重要的是::ng-deep在父级之后使用,而不是之前,否则它将应用于加载组件时具有相同名称的所有类。

Component css:

组件css:

.my-component ::ng-deep .mat-checkbox-layout {
    background-color: aqua;
}

Component template:

组件模板:

<h1 class="my-component">
    <mat-checkbox ....></mat-checkbox>
</h1>


Resulting (Angular generated) css:

结果(角度生成)css:

.my-component[_ngcontent-c1] .mat-checkbox-layout {
    background-color: aqua;
}

回答by Balázs Takács

Just an update:

只是一个更新:

You should use ::ng-deepinstead of /deep/which seems to be deprecated.

您应该使用::ng-deep而不是/deep/which 似乎已被弃用。

Per documentation:

根据文档:

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.

不推荐使用阴影穿透后代组合器,并且正在从主要浏览器和工具中删除支持。因此,我们计划放弃对 Angular 的支持(对于 /deep/、>>> 和 ::ng-deep 中的所有 3 个)。在那之前 ::ng-deep 应该是首选,因为它与工具更广泛地兼容。

You can find it here

你可以在这里找到

回答by Helzgate

Use ::ng-deep with caution. I used it throughout my app to set the material design toolbar color to different colors throughout my app only to find that when the app was in testing the toolbar colors step on each other. Best to use javascript instead (not fun I know).

谨慎使用 ::ng-deep。我在整个应用程序中使用它来将 Material Design 工具栏颜色设置为整个应用程序中的不同颜色,结果发现当应用程序在测试工具栏颜色时,工具栏颜色会相互叠加。最好改用 javascript(我知道这不好玩)。

<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');
  }

}