Angular のカプセル化をマネージする

素の Angular で API などから取得したコンテンツを表示する場合には、innerHTML に入れると自動でサニタイズして表示してくれます。
この時 innerHTML の内容は元のコンポーネントのカプセルから出ているため、スタイルシートが適用されません。

@Componentencapsulation を渡す

@Component のオプションに encapsulation というのがあります。

この encapsulationViewEncapsulation の値を渡すことで、テンプレートとスタイルのカプセル化の方法をコントロールできます。

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  encapsulation: ViewEncapsulation.None,  // <-- カプセル化しない
})
export class ArticleComponent implements OnInit {
  ...
}

ViewEncapsulation は以下の 3 つでした。

内容
Emulated デフォルト
None テンプレートやスタイルのカプセル化をしない
ShadowDom Shadow Dom を使用してカプセル化を行う。これを設定すると、ShadowRoot が作成されてその中にテンプレートが入る。

以前は Native というレンダラーネイティブの仕組みを利用するオプションもありましたが、v6.1.0 以降で非推奨となり、v9 で削除されました。

注意点

encapsulation: ViewEncapsulation.None を設定した場合、カプセル化されず Shadow Dom でなくなるため、スタイルシートで :host 疑似クラスが使用できなくなります。 ::slotted 疑似要素も同様です。

:host::slotted を使用していたら、セレクター名に置換したり class を付与するなどの対応が必要です。

非推奨のもの

以前は /deep/ コンビネーターで子孫要素までスタイルをあてることができましたが、主要なブラウザからサポートが削除されたため Angular でもサポートしなくなる予定とのことです。

Angular - Component styles

あとがき

Angular は公式ドキュメントがすごく見やすいと思う。

unimoku

Web サイトの制作、運営とアプリケーションのフロントエンド開発などをやっています。主に使うのはTypeScript、JavaScript、PHP、C/C++。特にTypeScriptが好きです。