angular - 来自父组件的CSS fi的样式子组件
我有一个父组件:
我想用子组件填充这个组:
父模板:
儿童模板:
由于child和parent是两个独立的组件,它们的风格被锁定在它们自己的范围内。
在我的父组件中,我尝试过:
.parent .child {
// Styles for child
}
但child样式未应用于parent组件。
我尝试使用child将parent的样式表包含到child组件中以解决范围问题:
// child.component.ts
styleUrls: [
'./parent.component.css',
'./child.component.css',
]
但这没有帮助,也尝试了另一种方式将child样式表提取到parent,但这也没有帮助。
那么如何设置包含在父组件中的子组件的样式?
11个解决方案
152 votes
更新 - 最新方式
如果可以避免的话,不要这样做。 正如Devon Sans在评论中指出的那样:这个功能很可能会被弃用。
更新 - 更新的方式
从Angular 4.3.0开始,所有穿孔的css组合器都被弃用了。 Angular团队推出了一个新的组合子encapsulation mode(仍处于实验水平,而不是完整和最终的方式),如下所示,
演示:[https://plnkr.co/edit/RBJIszu14o4svHLQt563?p=preview]
styles: [
`
:host { color: red; }
:host ::ng-deep parent {
color:blue;
}
:host ::ng-deep child{
color:orange;
}
:host ::ng-deep child.class1 {
color:yellow;
}
:host ::ng-deep child.class2{
color:pink;
}
`
],
template: `
Angular2 //red
//blue
//orange
//yellow
//pink
`
老路
您可以使用encapsulation mode和/或piercing CSS combinators >>>, /deep/ and ::shadow
工作实例:[http://plnkr.co/edit/1RBDGQ?p=preview]
styles: [
`
:host { color: red; }
:host >>> parent {
color:blue;
}
:host >>> child{
color:orange;
}
:host >>> child.class1 {
color:yellow;
}
:host >>> child.class2{
color:pink;
}
`
],
template: `
Angular2 //red
//blue
//orange
//yellow
//pink
`
micronyks answered 2019-04-26T02:10:03Z
44 votes
更新3:
parent也已弃用,这意味着您不应该再这样做了。 目前还不清楚这会如何影响您需要从父组件覆盖子组件中的样式的内容。 对我而言,如果完全删除它似乎很奇怪,因为这会影响作为库需要覆盖库组件中的样式的库?
如果您对此有任何见解,请发表评论。
更新2:
自parent以来,所有其他阴影穿孔选择器现已弃用。 Angular下降了>>>,应该使用它来代替更广泛的兼容性。
更新:
如果使用Angular-CLI,您需要使用parent而不是>>>,否则它将无法工作。
原版的:
在转到Angular2的Github页面并随机搜索“样式”后,我发现了这个问题:Angular 2 - innerHTML样式
据说使用了在parent,>>>和::shadow选择器中添加的东西。
(>>>)(和等效/深/)和:: shadow在2.0.0-beta.10中添加。 它们类似于shadow DOM CSS组合器(不推荐使用),仅适用于封装:ViewEncapsulation.Emulated,这是Angular2中的默认值。 它们可能也适用于ViewEncapsulation.None但只是被忽略,因为它们不是必需的。 在支持跨组件样式的更高级功能之前,这些组合器只是一种中间解决方案。
所以简单地做:
:host >>> .child {}
在parent的样式表文件中解决了这个问题。 请注意,如上面引用中所述,此解决方案仅在支持更高级的跨组件样式之前才是中间的。
Chrillewoodz answered 2019-04-26T02:11:30Z
15 votes
有同样的问题,所以如果你使用angular2-cli和scss / sass使用'/ deep /'而不是'>>>',那么最后的选择器还不支持(但是对css很有用)。
SergiySev answered 2019-04-26T02:11:56Z
14 votes
遗憾的是,似乎已弃用/ deep / selector(至少在Chrome中)[https://www.chromestatus.com/features/6750456638341120]
简而言之,似乎(目前)没有长期解决方案,除了以某种方式让您的子组件动态地设置事物。
您可以将样式对象传递给您的孩子并通过以下方式应用它:
或者,如果您有特定的风格,您可以使用以下内容:
更多与此相关的讨论:[https://github.com/angular/angular/issues/6511]
Matthew B. answered 2019-04-26T02:13:03Z
10 votes
如果您希望更多地针对实际的子组件而不是您应该执行的操作。 这样,如果其他子组件共享相同的类名,则不会受到影响。
Plunker:[https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview]
例如:
import {Component, NgModule } from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
@Component({
selector: 'my-app',
template: `
`,
styles: [`
/deep/ child-component.target1 .child-box {
color: red !important;
border: 10px solid red !important;
}
/deep/ child-component.target2 .child-box {
color: purple !important;
border: 10px solid purple !important;
}
/deep/ child-component.target3 .child-box {
color: orange !important;
border: 10px solid orange !important;
}
/* this won't work because the target component is spelled incorrectly */
/deep/ xxxxchild-component.target4 .child-box {
color: orange !important;
border: 10px solid orange !important;
}
/* this will affect any component that has a class name called .child-box */
/deep/ .child-box {
color: blue !important;
border: 10px solid blue !important;
}
`]
})
export class App {
}
@Component({
selector: 'child-component',
template: `
Child: This is some text in a box
`,
styles: [`
.child-box {
color: green;
border: 1px solid green;
}
`]
})
export class ChildComponent {
}
@NgModule({
imports: [ BrowserModule ],
declarations: [ App, ChildComponent ],
bootstrap: [ App ]
})
export class AppModule {}
希望这可以帮助!
codematrix
code5 answered 2019-04-26T02:13:42Z
6 votes
在Angular中有几个选项可以实现:
1)您可以使用深度css选择器
:host >>> .childrens {
color: red;
}
2)你也可以将它设置为Emulated的视图封装更改为默认设置,但可以很容易地更改为使用Shadow DOM本机浏览器实现的Native,在你的情况下你只需要禁用它
例如:`
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'parent',
styles: [`
.first {
color:blue;
}
.second {
color:red;
}
`],
template: `
First
Second
encapsulation: ViewEncapsulation.None,
})
export class ParentComponent {
constructor() {
}
}
Denis Rybalka answered 2019-04-26T02:14:30Z
6 votes
如果你不想使用:: ng-deep,你可以这样做,这似乎是正确的方法:
import { ViewEncapsulation } from '@angular/core';
@Component({
....
encapsulation: ViewEncapsulation.None
})
然后,您将能够在不需要:: ng-deep的情况下修改组件的css
.mat-sort-header-container {
display:flex;
justify-content:center;
}
警告:小心你的组件有很多孩子,你为这个组件编写的CSS可能会影响所有孩子!
Tonio answered 2019-04-26T02:15:12Z
4 votes
如果您有权访问子组件代码,我发现传递@INPUT变量要清晰得多:
这个想法是父母告诉孩子它的外貌应该是什么,孩子决定如何显示状态。 这是一个很好的建筑
SCSS方式:
.active {
::ng-deep md-list-item {
background-color: #eee;
}
}
更好的方法: - 使用selected变量:
*ngFor="let convo of conversations"
routerLink="/conversations/{{convo.id}}/messages"
#rla="routerLinkActive"
routerLinkActive="active">
[selected]="rla.isActive"
[convo]="convo">
robert king answered 2019-04-26T02:16:00Z
1 votes
答案很简单,你根本就不应该这样做。 它打破了组件封装并破坏了从自包含组件中获得的好处。 考虑将prop标志传递给子组件,然后可以根据需要决定自己如何以不同方式呈现或应用不同的CSS。
Angular正在弃用影响父母子女风格的所有方式。
[https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep]
Jed Richards answered 2019-04-26T02:16:40Z
1 votes
您不应该为父组件中的子组件元素编写CSS规则,因为Angular组件是一个自包含的实体,应该明确声明可用于外部世界的内容。 如果子布局将来发生变化,那么分散在其他组件的SCSS文件中的子组件元素的样式很容易破坏,从而使您的样式非常脆弱。 对于CSS来说,这就是:host。 否则,如果您可以在面向对象编程中为任何其他类的某些类的私有字段赋值,那么它将是相同的。
因此,您应该做的是定义一组可以应用于子宿主元素的类,并实现子代对它们的响应方式。
从技术上讲,它可以如下完成:
// child.component.html:
// child.component.scss:
:host.child-color-black {
.label-1 {
color: black;
}
}
:host.child-color-blue {
.label-1 {
color: blue ;
}
}
// parent.component.html:
换句话说,您使用Angular + CSS类集提供的:host伪选择器来定义子组件本身中可能的子样式。 然后,您可以通过将预定义的类应用于主机元素来从外部触发这些样式。
Alexander Abakumov answered 2019-04-26T02:17:28Z
0 votes
我提出了一个更清晰的例子,因为angular.io/guide/component-styles声明:
不推荐使用阴影穿透后代组合器,并且正在从主要浏览器和工具中删除支持。 因此,我们计划放弃Angular中的支持(对于/ deep /,>>>和:: ng-deep的所有3个)。 在此之前:: ng-deep应该是首选,以便与工具更广泛地兼容。
在btn-red,如果需要,请导入您的app-login。 _colors.scss有一些常见的颜色值:
$button_ripple_red: #A41E34;
$button_ripple_white_text: #FFF;
将规则应用于所有组件
所有具有btn-red类的按钮都将被设置样式。
@import `./theme/sass/_colors`;
// red background and white text
:host /deep/ button.red-btn {
color: $button_ripple_white_text;
background: $button_ripple_red;
}
将规则应用于单个组件
app-login组件上的btn-red类的所有按钮都将被设置为样式。
@import `./theme/sass/_colors`;
/deep/ app-login button.red-btn {
color: $button_ripple_white_text;
background: $button_ripple_red;
}
AndreaM16 answered 2019-04-26T02:18:39Z