Html 用什么代替 ::ng-deep
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47024236/
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
What to use in place of ::ng-deep
提问by Jacob Schwartz
I'm trying to style an element placed by the router outlet in angular and want to make sure that the element generated gets a width of 100%
我正在尝试以角度设置由路由器出口放置的元素的样式,并希望确保生成的元素的宽度为 100%
From most of the replies, I'm seeing that I should use the ::ng-deep
selector, but from Angular's docsit is being deprecated. Is there an alternative to ::ng-deep
?
从大多数回复中,我看到我应该使用::ng-deep
选择器,但从 Angular 的文档中它已被弃用。有替代品::ng-deep
吗?
回答by dudewad
FWIW In my research I have not found any replacement for ng-deep or the other applicable alternatives. This is because, I believe, the Angular team is deferring to the W3C spec on the shadow dom, which initially had selectors such as deep
. However, the W3c has since removed the recommendation, but not replaced it with a new one. Until that happens, I imagine that the Angular team will keep ::ng-deep
and it's alternatives available, but in deprecated state due to the pending state of W3C's drafts. I am not able to take the time to find the documentation to back this up right now but I did see it recently.
FWIW 在我的研究中,我没有找到 ng-deep 或其他适用替代品的任何替代品。这是因为,我相信 Angular 团队正在遵循 W3C 关于 shadow dom 的规范,该规范最初具有诸如deep
. 但是,W3c 此后删除了该建议,但并未将其替换为新的建议。在此之前,我想 Angular 团队会保留::ng-deep
它的替代品,但由于 W3C 草案的待定状态,它处于弃用状态。我现在无法花时间找到支持它的文档,但我最近确实看到了它。
Long story short: Keep using ::ng-deep
and its alternatives until a replacement is created - the deprecation is just an early notice so that people aren't blindsided whenever the actual change materializes.
长话短说:继续使用::ng-deep
及其替代品,直到创建替代品 - 弃用只是一个早期通知,以便人们在实际更改实现时不会被忽视。
-- UPDATE--
--更新--
https://drafts.csswg.org/css-scoping-1/Here is the draft proposal if you're interested. It appears that they are working on a robust set of selectors for elements within a shadow dom tree; it is this spec, once approved, that I think will inform the angular clone, if there even is one (i.e. angular may not need to implement their own selectors once this goes live in browsers).
https://drafts.csswg.org/css-scoping-1/如果您有兴趣,这里是提案草案。看起来他们正在为 shadow dom 树中的元素开发一组强大的选择器;正是这个规范,一旦获得批准,我认为会通知 angular 克隆,如果有的话(即,一旦它在浏览器中上线,angular 可能不需要实现自己的选择器)。
回答by AliF50
To bypass the deprecated ::ng-deep
, I usually disable ViewEncapsulation
. Although this is not the best approach, it has served me well.
为了绕过已弃用的::ng-deep
,我通常禁用ViewEncapsulation
. 虽然这不是最好的方法,但它对我很有帮助。
To disable ViewEncapsulation
, do the following in your component:
要禁用ViewEncapsulation
,请在您的组件中执行以下操作:
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class HeaderComponent {
}
This will make the .scss styles in this component global to the whole application. To not allow the styles to go up the chain to parent and sibling components, wrap the whole scss with the selector like so:
这将使该组件中的 .scss 样式对整个应用程序全局化。为了不允许样式沿着链向上传递到父组件和兄弟组件,请使用选择器包装整个 scss,如下所示:
app-header {
// your styles here and any child component styles can go here
}
Now, the styles specified here will go down to children components so you have to be extra specific with your css selectors and mind your p's and q's when adding CSS (maybe add the child selector specified in your Angular app and then its styles).
现在,此处指定的样式将归入子组件,因此您必须对 css 选择器更加具体,并在添加 CSS 时注意 p 和 q(可能添加在 Angular 应用程序中指定的子选择器,然后添加其样式)。
I say it is not the best approach because of the paragraph above, but this has served me well.
由于上面的段落,我说这不是最好的方法,但这对我很有帮助。
回答by J. Lenthe
The simple and easy alternative to a deep style is a common style using the element selector of the parent component. So if you had this in hero-details.component.css:
深层样式的简单易行的替代方法是使用父组件的元素选择器的常见样式。所以如果你在 hero-details.component.css 中有这个:
:host ::ng-deep h3 {
font-style: italic;
}
It would become this in styles.css:
在styles.css中会变成这样:
app-hero-details h3 {
font-style: italic;
}
Basically a deep style is an un-encapsulated style so it conceptually seems more like a common style to me than a component style. Personally I would not use deep styles anymore. Breaking changes are normal in major version updates and deprecated feature removal is fair game.
基本上,深层样式是一种未封装的样式,因此在我看来,它在概念上更像是一种普通样式,而不是组件样式。我个人不会再使用深度样式了。重大版本更新中的重大更改是正常的,不推荐使用的功能删除是公平的游戏。
回答by Jose Guzman
As someone stated before, if you're using a third party library it's virtually impossible to avoid having to use ::ng-deep
once in a while. But what are you going to do about your previous projects when the ::ng-deep
became no longer supported by browsers?
正如之前有人所说,如果您使用第三方库,几乎不可能避免::ng-deep
偶尔使用一次。但是当::ng-deep
浏览器不再支持时,您将如何处理以前的项目?
To be ready for that moment I will suggest the following:
为了为那一刻做好准备,我将提出以下建议:
- Use ViewEncapsulation.Nonewisely. Which translates to only for those components that needs to access deeper components.
- 明智地使用ViewEncapsulation.None。这意味着仅适用于需要访问更深层次组件的那些组件。
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.scss'],
encapsulation: ViewEncapsulation.None
})
- Now, to avoid collisions and CSS weirdness you should (as a rule) alwayswrap your component's template with a class. So, example.component.html should be like:
- 现在,为了避免冲突和 CSS 怪异,您应该(通常)始终使用类包装组件的模板。所以,example.component.html 应该是这样的:
<section class="app-example-container">
<!-- a third party component -->
<mat-tab-group>
<mat-tab label="First"></mat-tab>
<mat-tab label="Second"></mat-tab>
</mat-tab-group>
</section>
- Again, by rule, the first line of every single SCSS file will target the component container. Since there's no Encapsulationyou can modify the third party component by targeting their classes. That say, example.component.scssshould be like:
- 同样,按照规则,每个 SCSS 文件的第一行都将针对组件容器。由于没有封装,您可以通过定位第三方组件的类来修改第三方组件。也就是说,example.component.scss应该是这样的:
.app-example-container {
/* All the CSS code goes here */
.mat-tab-group .mat-tab-label {color: red;}
}
回答by mrm1st3r
This is not a general replacement for ::ng-deep, but for the use case described by the question author:
这不是 ::ng-deep 的一般替代,而是针对问题作者描述的用例:
In the special case where you want to style the element inserted by a router-outlet, there is an elegant solution using the adjacent neighbor selector in CSS:
在特殊情况下,您想要设置由路由器插座插入的元素的样式,使用 CSS 中的相邻邻居选择器有一个优雅的解决方案:
router-outlet+* {
/* styling here... */
}
This will apply to all elements which are direct neighbors of a router-outlet.
这将适用于作为路由器出口直接邻居的所有元素。
Further reading:
https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator
https://angular.io/guide/router#router-outlet
进一步阅读:
https: //developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_combinator
https://angular.io/guide/router#router-outlet
回答by Guilherme Meinlschmiedt Abdo
To avoid changing the default encapsulation, I wrote a helper that append global styles for the component:
为了避免更改默认封装,我编写了一个帮助程序来为组件附加全局样式:
deepStyle.ts
deepStyle.ts
import { ViewContainerRef } from '@angular/core';
export function deepStyle(vcr: ViewContainerRef, csss: string[]){
let id = 'deep-' + vcr.element.nativeElement.tagName;
let styleElement = document.getElementById('pierce-' + vcr.element.nativeElement.name);
if(!styleElement){
styleElement = document.createElement('style');
styleElement.id = id;
styleElement.innerHTML = csss.map(css => vcr.element.nativeElement.tagName + ' ' + css).join('\n');
document.head.append(styleElement);
}
}
my-component.ts
我的component.ts
import { Component, ViewContainerRef } from '@angular/core';
import { deepStyle } from '../deepStyle';
@Component({
selector: 'my-component',
templateUrl: './my-component.html',
styleUrls: ['./my-component.css']
})
export class MyComponent {
constructor(vcr: ViewContainerRef) {
deepStyle(vcr, [`
img {
height: 180px;
}
`]);
}
}
result:
结果:
<head>
...
<style id="deep-MY-COMPONENT">
MY-COMPONENT img {
height: 180px;
}
</style>
...
</head>