부모 구성 요소의 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>
이후 parent
및 child
두 개의 별도 구성 요소, 자신의 스타일이 자신의 범위에 잠겨 있습니다.
부모 구성 요소에서 다음을 시도했습니다.
.parent .child {
// Styles for child
}
그러나 .child
스타일은 child
구성 요소에 적용되지 않습니다 .
범위 문제를 해결하기 위해 의 스타일 시트를 구성 요소 styleUrls
에 포함시키는 데 사용하려고했습니다 .parent
child
// 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
의 스타일 시트 파일 문제를 해결했다. 위 인용문에 명시된 바와 같이이 솔루션은 고급 교차 컴포넌트 스타일링이 지원 될 때까지 중간 수준입니다.
같은 문제가 있었으므로 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
:: ng-deep을 사용하지 않으려면 올바른 방법으로 보일 수 있습니다.
import { ViewEncapsulation } from '@angular/core';
@Component({
....
encapsulation: ViewEncapsulation.None
})
그런 다음 :: ng-deep 없이도 구성 요소에서 CSS를 수정할 수 있습니다.
.mat-sort-header-container {
display:flex;
justify-content:center;
}
경고 : 구성 요소에 많은 자식이있는 경우이 구성 요소에 대해 작성한 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 {}
도움이 되었기를 바랍니다!
코드 매트릭스
Angular에서는이를 수행 할 수있는 몇 가지 옵션이 있습니다.
1) 깊은 CSS 선택기를 사용할 수 있습니다
:host >>> .childrens {
color: red;
}
2) 뷰 캡슐화를 기본값으로 에뮬레이트로 설정했지만 Shadow DOM 기본 브라우저 구현을 사용하는 네이티브로 쉽게 변경할 수 있습니다.이 경우 비활성화해야합니다.
예를 들면 :
import { Component, ViewEncapsulation } from '@angular/core';
@Component({
selector: 'parent',
styles: [`
.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() {
}
}
Angular 구성 요소는 외부 세계에서 사용할 수있는 항목을 명시 적으로 선언해야하는 독립적 인 엔터티이므로 부모 구성 요소의 자식 구성 요소에 대한 CSS 규칙을 작성해서는 안됩니다. 나중에 자식 레이아웃이 변경되면 다른 구성 요소의 SCSS 파일에 흩어져있는 해당 자식 구성 요소의 스타일이 쉽게 깨져서 스타일이 매우 약해질 수 있습니다. 이것이 ViewEncapsulation
CSS의 경우입니다. 그렇지 않으면 객체 지향 프로그래밍의 다른 클래스에서 일부 클래스의 개인 필드에 값을 할당 할 수 있다면 동일합니다.
따라서해야 할 일은 자식 호스트 요소에 적용 할 수있는 클래스 집합을 정의하고 자식이 이에 응답하는 방식을 구현하는 것입니다.
기술적으로 다음과 같이 수행 할 수 있습니다.
// child.component.html:
<span class="label-1"></span>
// child.component.scss:
:host.child-color-black {
.label-1 {
color: black;
}
}
:host.child-color-blue {
.label-1 {
color: blue ;
}
}
// parent.component.html:
<child class="child-color-black"></child>
<child class="child-color-blue"></child>
In other words, you use :host
pseudo-selector provided by Angular + set of CSS classes to define possible child styles in child component itself. You then have the ability to trigger those styles from outside by applying pre-defined classes to the <child>
host element.
I find it a lot cleaner to pass an @INPUT variable if you have access to the child component code:
The idea is that the parent tells the child what its state of appearance should be, and the child decides how to display the state. It's a nice architecture
SCSS Way:
.active {
::ng-deep md-list-item {
background-color: #eee;
}
}
Better way: - use selected
variable:
<md-list>
<a
*ngFor="let convo of conversations"
routerLink="/conversations/{{convo.id}}/messages"
#rla="routerLinkActive"
routerLinkActive="active">
<app-conversation
[selected]="rla.isActive"
[convo]="convo"></app-conversation>
</a>
</md-list>
Actually there is one more option. Which is rather safe. You can use ViewEncapsulation.None BUT put all your component styles into its tag (aka selector). But anyway always prefer some global style plus encapsulated styles.
Here is modified Denis Rybalka example:
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() { }
}
The quick answer is you shouldn't be doing this, at all. It breaks component encapsulation and undermines the benefit you're getting from self-contained components. Consider passing a prop flag to the child component, it can then decide itself how to render differently or apply different CSS, if necessary.
<parent>
<child [foo]="bar"></child>
</parent>
Angular is deprecating all ways of affecting child styles from parents.
https://angular.io/guide/component-styles#deprecated-deep--and-ng-deep
i also had this problem and didnt wanted to use deprecated solution so i ended up with:
in parrent
<dynamic-table
ContainerCustomStyle='width: 400px;'
>
</dynamic-Table>
child component
@Input() ContainerCustomStyle: string;
in child in html div
<div class="container mat-elevation-z8"
[style]='GetStyle(ContainerCustomStyle)' >
and in code
constructor(private sanitizer: DomSanitizer) { }
GetStyle(c) {
if (isNullOrUndefined(c)) { return null; }
return this.sanitizer.bypassSecurityTrustStyle(c);
}
works like expected and should not be deprecated ;)
I propose an example to make it more clear, since angular.io/guide/component-styles states:
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.
On app.component.scss
, import your *.scss
if needed. _colors.scss
has some common color values:
$button_ripple_red: #A41E34;
$button_ripple_white_text: #FFF;
Apply a rule to all components
All the buttons having btn-red
class will be styled.
@import `./theme/sass/_colors`;
// red background and white text
:host /deep/ button.red-btn {
color: $button_ripple_white_text;
background: $button_ripple_red;
}
Apply a rule to a single component
All the buttons having btn-red
class on app-login
component will be styled.
@import `./theme/sass/_colors`;
/deep/ app-login button.red-btn {
color: $button_ripple_white_text;
background: $button_ripple_red;
}
I have solved it outside Angular. I have defined a shared scss that I'm importing to my children.
shared.scss
%cell {
color: #333333;
background: #eee;
font-size: 13px;
font-weight: 600;
}
child.scss
@import 'styles.scss';
.cell {
@extend %cell;
}
My proposed approach is a way how to solve the problem the OP has asked about. As mentioned at multiple occasions, ::ng-deep, :ng-host will get depreciated and disabling encapsulation is just too much of a code leakage, in my view.
'IT story' 카테고리의 다른 글
ASP.NET MVC에서 요청 조절을 구현하는 가장 좋은 방법은 무엇입니까? (0) | 2020.05.05 |
---|---|
속성 탐색기처럼 작동하는 GUI 기반 또는 웹 기반 JSON 편집기 (0) | 2020.05.05 |
href 표현은 무엇입니까 (0) | 2020.05.05 |
자식 프로젝트는 하위 프로젝트가 더럽다고 말합니다. (0) | 2020.05.05 |
ViewBag, ViewData 및 TempData (0) | 2020.05.05 |