[css] 부모 구성 요소의 CSS 파일에서 자식 구성 요소의 스타일을 지정하는 방법은 무엇입니까?

부모 구성 요소가 있습니다.

<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>

이후 parentchild두 개의 별도 구성 요소, 자신의 스타일이 자신의 범위에 잠겨 있습니다.

부모 구성 요소에서 다음을 시도했습니다.

.parent .child {
  // Styles for child
}

그러나 .child스타일은 child구성 요소에 적용되지 않습니다 .

범위 문제를 해결하기 위해 의 스타일 시트를 구성 요소 styleUrls에 포함시키는 데 사용하려고했습니다 .parentchild

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

그러나 그것은 도움이되지 않았으며 child스타일 시트를 가져 와서 다른 방법으로 시도했지만 parent도움이되지 못했습니다.

부모 구성 요소에 포함 된 하위 구성 요소를 어떻게 스타일링합니까?



답변

업데이트-최신 방법

피할 수 있다면하지 마십시오. Devon Sans가 의견에서 지적한 것처럼 :이 기능은 더 이상 사용되지 않습니다.

업데이트-최신 방법

Angular 4.3.0 부터는 모든 피어싱 CSS 조합자가 더 이상 사용되지 않습니다. Angular 팀 ::ng-deep 아래와 같이 새로운 결합기를 도입했습니다 (여전히 최종 단계가 아니라 실험 수준에 있음) .

데모 : 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
      <parent>                                //blue
          <child></child>                     //orange
          <child class="class1"></child>      //yellow
          <child class="class2"></child>      //pink
      </parent>
    `


옛날 방식

사용 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
  <parent>                                //blue
      <child></child>                     //orange
      <child class="class1"></child>      //yellow
      <child class="class2"></child>      //pink
  </parent>
`


답변

업데이트 3 :

::ng-deep더 이상 사용하지 않아야 함을 의미합니다. 부모 구성 요소에서 자식 구성 요소의 스타일을 재정의해야하는 항목에 어떤 영향을 미치는지 확실하지 않습니다. 라이브러리 구성 요소에서 스타일을 재정의 해야하는 라이브러리에 영향을 미치기 때문에 이것이 완전히 제거되면 이상하게 보입니다.

이것에 대한 통찰력이 있으면 의견을 말하십시오.

업데이트 2 :

이후 /deep/모든 다른 섀도우 피어싱 선택기는 더 이상 사용되지 않습니다. ::ng-deep더 넓은 호환성을 위해 대신 사용해야하는 앵귤러 드롭 .

최신 정보:

Angular-CLI를 사용 /deep/하는 경우 대신 사용해야 >>>합니다. 그렇지 않으면 작동하지 않습니다.

실물:

Angular2의 Github 페이지로 이동하여 “style”에 대한 임의 검색을 수행 한 후 Angular 2-innerHTML styling

어떤이 추가 된 것을 사용하는 것이 말했다 2.0.0-beta.10>>>::shadow선택기.

(>>>) (및 동등한 / deep /) 및 :: shadow가 2.0.0-beta.10에 추가되었습니다. 이들은 그림자 DOM CSS 결합기 (더 이상 사용되지 않음)와 유사하며 Angular2의 기본값 인 캡슐화 ViewEncapsulation.Emulated에서만 작동합니다. ViewEncapsulation에서도 작동하지만 필요하지 않기 때문에 무시됩니다. 이 컴비 네이터는 교차 컴포넌트 스타일링을위한 고급 기능이 지원 될 때까지 중간 솔루션입니다.

간단히 말해서 :

:host >>> .child {}

에서 parent의 스타일 시트 파일 문제를 해결했다. 위 인용문에 명시된 바와 같이이 솔루션은 고급 교차 컴포넌트 스타일링이 지원 될 때까지 중간 수준입니다.


답변

사용하지 않아야합니다 ::ng-deep. 사용되지 않습니다. Angular에서 부모의 자식 구성 요소 스타일을 변경하는 올바른 방법은 사용하는 것입니다 encapsulation(아래의 경고를 읽고 의미를 이해하십시오).

import { ViewEncapsulation } from '@angular/core';

@Component({
    ....
    encapsulation: ViewEncapsulation.None
})

그런 다음 :: ng-deep 없이도 구성 요소에서 CSS를 수정할 수 있습니다.

.mat-sort-header-container {
  display:flex;
  justify-content:center;
}

경고 : 이렇게하면이 구성 요소에 대해 작성한 모든 CSS 규칙이 전체적으로 적용됩니다.

CSS의 범위를이 컴포넌트로만 제한하려면 CSS 클래스를 컴포넌트의 상단 태그에 추가하고 CSS를이 태그의 “내부”에 넣으십시오.

template:
    <div class='my-component'>
      <child-component class="first">First</child>
    </div>,

Scss 파일 :

.my-component {
  // All your css goes in there in order not to be global
}


답변

슬프게도 / deep / 선택기가 더 이상 사용되지 않는 것으로 보입니다 (적어도 Chrome에서는)
https://www.chromestatus.com/features/6750456638341120

요컨대, 자식 컴포넌트가 동적으로 스타일을 지정하는 것 외에는 (현재) 장기적인 해결책이없는 것으로 보입니다.

자녀에게 스타일 개체를 전달하고 다음을 통해 적용
<div [attr.style]="styleobject">

할 수 있습니다 . 또는 특정 스타일이있는 경우 다음과 같은 것을 사용할 수 있습니다.
<div [style.background-color]="colorvar">

이것과 관련된 추가 토론 :
https://github.com/angular/angular/issues/6511


답변

같은 문제가 있었으므로 scss / sass와 함께 angular2-cli를 사용하는 경우 ‘>>>’대신 ‘/ deep /’을 사용하면 마지막 선택기가 아직 지원되지 않지만 (CSS에서는 훌륭하게 작동합니다).


답변

실제 하위 구성 요소를보다 잘 타겟팅하려면 다음을 수행해야합니다. 이렇게하면 다른 자식 구성 요소가 동일한 클래스 이름을 공유해도 영향을받지 않습니다.

플 런커 :
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 {}

도움이 되었기를 바랍니다!

코드 매트릭스


답변

실제로 한 가지 더 옵션이 있습니다. 어느 것이 안전합니다. ViewEncapsulation을 사용할 수 있습니다.하지만 모든 구성 요소 스타일을 태그 (일명 선택기)에 넣습니다. 그러나 어쨌든 항상 글로벌 스타일과 캡슐화 스타일을 선호합니다.

다음은 Denis Rybalka의 수정 된 예입니다.

import { Component, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'parent',
  styles: [`
    parent {
      .first {
        color:blue;
      }
      .second {
        color:red;
      }
    }
 `],
 template: `
    <div>
      <child class="first">First</child>
      <child class="second">Second</child>
    </div>`,
  encapsulation: ViewEncapsulation.None,
})
export class ParentComponent  {
  constructor() { }
}