我有一个父组件:

<parent></parent>

我想用子组件填充这个组:

<parent>
  <child></child>
  <child></child>
  <child></child>
</parent>

父模板:

<div class="parent">
  <!-- Children goes here -->
  <ng-content></ng-content>
</div>

子模板:

<div class="child">Test</div>

由于父组件和子组件是两个独立的组件,它们的样式被锁定在自己的范围内。

在我的父组件中,我尝试这样做:

.parent .child {
  // Styles for child
}

但是.child样式没有应用到子组件。

我尝试使用styleUrls将父组件的样式表包含到子组件中,以解决范围问题:

// child.component.ts
styleUrls: [
  './parent.component.css',
  './child.component.css',
]

但这并没有帮助,我还尝试了另一种方法,将子样式表取到父样式表中,但这也没有帮助。

那么,如何样式包含在父组件中的子组件呢?


当前回答

也有同样的问题,所以如果你在scss/sass中使用angular2-cli,使用'/deep/'而不是'>>>',最后的选择器还不支持(但适用于css)。

其他回答

我已经在Angular之外解决了这个问题。我已经定义了一个共享的scss,并将其导入到我的子程序中。

shared.scss

%cell {
  color: #333333;
  background: #eee;
  font-size: 13px;
  font-weight: 600;
}

child.scss

@import 'styles.scss';
.cell {
  @extend %cell;
}

我提出的方法是如何解决OP提出的问题。正如在多个场合提到的,::ng-deep,:ng-host将被贬低,在我看来,禁用封装只是太多的代码泄漏。

这是一个只有香草css的解决方案,没有什么花哨的,你甚至不需要!重要。我假设你不能修改子结点,否则答案就更简单了,我把答案放在最后以防万一。

当使用库中预先制作的组件时,有时需要覆盖子CSS,并且开发人员没有提供任何类输入变量。::ng-deep已弃用,encapsulation: ViewEncapsulation. jpgNone将使组件的所有CSS全局化。这里有一个简单的解决方案,这两个都不用。

事实上,我们确实需要一个全局样式,以便CSS到达子节点。我们可以把样式放到styles。CSS中或者我们可以创建一个新的CSS文件并把它添加到angular。json中的样式数组中。唯一的问题是我们需要一个特定的选择器,这样就不会针对其他元素。这是一个非常简单的解决方案-只需在html中添加一个唯一的类名,我建议在类名中使用父组件的名称,以确保它是唯一的。

父组件

<child class="child-in-parent-component"></child>

让我们假设我们想要改变child中所有按钮的背景颜色,我们确实需要实现正确的专一性以确保我们的样式优先。我们可以将!important放在所有属性的旁边,但更好的方法是重复类名,直到我们的选择器足够特定,这可能需要尝试几次。这样,其他人可以在必要时再次重写此css。

全局样式文件

.child-in-parent-component.child-in-parent-component.child-in-parent-component
  button {
  background-color: red;
}

或者用!important(不推荐)

.child-in-parent-component button {
  background-color: red !important;
}

如果子组件可以修改

只需向组件中添加一个输入变量,并使用Angular的ngStyle指令。您可以添加多个变量来为组件的多个区域设置样式。

子组件

type klass = { [prop: string]: any } | null;

@Component({...})
export class ChildComponent {
  @Input() containerClass: klass = null;
  @Input() pClass: klass = null;
...
}
<div [ngStyle]="containerClass">
  <p [ngStyle]="pClass">What color will I be?</p>
</div>

父组件

<child
  [containerClass]="{ padding: '20px', 'background-color': 'black' }"
  [pClass]="{ color: 'red' }"
>
</child>

这是创建具有动态样式的组件的预期方法。许多预制组件都有类似的输入变量。

也有同样的问题,所以如果你在scss/sass中使用angular2-cli,使用'/deep/'而不是'>>>',最后的选择器还不支持(但适用于css)。

可悲的是/deep/选择器已弃用(至少在Chrome中) https://www.chromestatus.com/features/6750456638341120

简而言之,(目前)似乎没有长期的解决方案,除了以某种方式让你的子组件动态地设置样式。 你可以传递一个样式对象给你的孩子,并通过以下方式应用它: < div [attr.style] = " styleobject " > 或者如果你有一个特定的风格,你可以使用像这样的东西: < div [style.background-color] = " colorvar " >

更多与此相关的讨论: https://github.com/angular/angular/issues/6511

如果您希望更针对实际的子组件,则应该执行以下操作。这样,如果其他子组件共享相同的类名,它们也不会受到影响。

砰砰作响: https://plnkr.co/edit/ooBRp3ROk6fbWPuToytO?p=preview

例如:

import {Component, NgModule } from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>I'm the host parent</h2>
      <child-component class="target1"></child-component><br/>
      <child-component class="target2"></child-component><br/>
      <child-component class="target3"></child-component><br/>
      <child-component class="target4"></child-component><br/>
      <child-component></child-component><br/>
    </div>
  `,
  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: `
    <div class="child-box">
      Child: This is some text in a box
    </div>
  `,
  styles: [`
    .child-box {
      color: green;    
      border: 1px solid green;
    }
  `]
})
export class ChildComponent {
}


@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App, ChildComponent ],
  bootstrap: [ App ]
})
export class AppModule {}

希望这能有所帮助!

codematrix