親コンポーネントがあります。
<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
は2つの別々のコンポーネントなので、それらのスタイルはそれぞれ独自の範囲に固定されています。
私の親コンポーネントで私がやってみました:
.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/
と他のすべてのシャドーピアスセレクターは現在非推奨です。 Angularは::ng-deep
を削除しました。これはより広い互換性のために代わりに使用されるべきです。
更新:
Angular-CLIを使用している場合、/deep/
の代わりに>>>
を使用する必要があります。そうしないと機能しません。
オリジナル:
Angular 2のGithubページに行き、 "style"をランダムに検索したところ、この質問が見つかりました。 Angular 2 - innerHTMLスタイル
これは2.0.0-beta.10
、>>>
および::shadow
セレクターに追加されたものを使用すると言っています。
(>>>)(と同等の/ deep /)と:: shadowが2.0.0-beta.10で追加されました。これらはshadow DOM CSSコンビネータ(非推奨)に似ており、カプセル化でのみ動作します:ViewEncapsulation.EmulatedこれはAngular 2のデフォルトです。それらはおそらくViewEncapsulation.Noneでも動作しますが、必要ないので無視されるだけです。クロスコンポーネントスタイリングのためのより高度な機能がサポートされるまで、これらのコンビネータは中間的な解決策にすぎません。
だから単純に:
:Host >>> .child {}
parent
のスタイルシートファイルで問題を解決しました。上記の引用で述べたように、この解決策はより高度なクロスコンポーネントスタイリングがサポートされるまでの中間にすぎません。
同じ問題を抱えていて、あなたがscss/sassでangular2-cliを使っているのであれば、 '>>>'の代わりに '/ deep /'を使ってください。
残念ながら、/ 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
:: ng-deepを使用したくない場合は、これを実行できますが、これは正しい方法のようです。
import { ViewEncapsulation } from '@angular/core';
@Component({
....
encapsulation: ViewEncapsulation.None
})
そして、あなたは:: ng-deepから必要とせずにあなたのコンポーネントのCSSフォームを修正することができるでしょう。
.mat-sort-header-container {
display:flex;
justify-content:center;
}
警告:あなたのコンポーネントがたくさんの子を持っているかのように注意してください、あなたがこのコンポーネントのために書いたcssはすべての子供に影響を与えるかもしれません!
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: `
<div>
<child class="first">First</child>
<child class="second">Second</child>
</div>`,
encapsulation: ViewEncapsulation.None,
})
export class ParentComponent {
constructor() {
}
}
Angularコンポーネントは、外部の世界で利用可能なものを明示的に宣言する必要がある自己完結型のエンティティなので、親コンポーネント内の子コンポーネント要素に対するCSSルールを記述しないでください。子レイアウトが将来変更されると、その子コンポーネント要素のスタイルが他のコンポーネントのSCSSファイルに散らばって壊れやすくなり、スタイルが非常に壊れやすくなります。それがCSSの場合のViewEncapsulation
の目的です。それ以外の場合は、オブジェクト指向プログラミングで他のクラスから特定のクラスのプライベートフィールドに値を代入できれば同じです。
したがって、やるべきことは、子Host要素に適用できるクラスのセットを定義し、子がそれらにどのように応答するかを実装することです。
技術的には、次のようにすることができます。
// 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>
つまり、Angular + CSSクラスのセットによって提供される:Host
疑似セレクタを使用して、子コンポーネント自体で可能な子スタイルを定義します。そうすれば、事前定義されたクラスを<child>
Host要素に適用することによって、これらのスタイルを外部から起動することができます。
@INPUT変数を渡すほうがきれいです あなたが子コンポーネントコードにアクセスできるのなら:
アイデアは、親が子供にその外観の状態がどうあるべきかを伝え、子供がその状態をどのように表示するかを決定するというものです。それはいい建築です
SCSS方法:
.active {
::ng-deep md-list-item {
background-color: #eee;
}
}
より良い方法: - selected
変数を使う:
<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>
実際にはもう1つ選択肢があります。どちらかといえば安全です。 ViewEncapsulation.Noneを使用できますが、すべてのコンポーネントスタイルをそのタグ(別名セレクタ)に配置できます。しかしとにかく、常に何らかのグローバルスタイルとカプセル化されたスタイルを好むのです。
これが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() { }
}
私はまた、この問題を抱えていたので、廃止予定のソリューションを使用したくなかったので、次のようになりました。
親権で
<dynamic-table
ContainerCustomStyle='width: 400px;'
>
</dynamic-Table>
子コンポーネント
@Input() ContainerCustomStyle: string;
hTML divの子に
<div class="container mat-elevation-z8"
[style]='GetStyle(ContainerCustomStyle)' >
そしてコードで
constructor(private sanitizer: DomSanitizer) { }
GetStyle(c) {
if (isNullOrUndefined(c)) { return null; }
return this.sanitizer.bypassSecurityTrustStyle(c);
}
期待どおりに動作し、推奨されません。
簡単な答えは、あなたがこれをするべきではないということです、まったく。それはコンポーネントのカプセル化を破り、自己完結型コンポーネントから得ている利益を損ないます。子コンポーネントにpropフラグを渡すことを検討してください。そうすれば、必要に応じて、レンダリング方法やCSSの適用方法を自分で決めることができます。
<parent>
<child [foo]="bar"></child>
</parent>
Angularは、親から子供のスタイルに影響を与えるあらゆる方法を非推奨にしています。
https://angular.io/guide/component-styles#deprecated-deep-- and-ng-deep
angular.io/guide/component-styles と述べているので、私はそれをより明確にするための例を提案する。
シャドーピアスの子孫コンビネータは廃止予定で、主要なブラウザやツールからサポートは削除されています。そのため、Angular(/ deep /、>>>、および:: ng-deepの3つすべて)のサポートを終了する予定です。それまでは:: ng-deepがツールとのより広い互換性のために好まれるべきです。
必要に応じてapp.component.scss
に*.scss
をインポートしてください。 _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;
}
単一のコンポーネントにルールを適用する
btn-red
コンポーネントのapp-login
クラスを持つすべてのボタンはスタイル設定されます。
@import `./theme/sass/_colors`;
/deep/ app-login button.red-btn {
color: $button_ripple_white_text;
background: $button_ripple_red;
}