A few days ago I wrote about Angular 2 ViewEncapsulation over here. The sample I’ve created for that post only works if you’re using Google Chrome. In this article I’ll explain why the sample only works in Google Chrome and how you can take the example one step further to work and behave as expected in all modern browsers.

Angular 2 is using ViewEncapsulation.Emulated by default, to render components. Emulated means you’re not using native ShadowDOM features, instead Angular 2 does some refactoring to both, your template and your styles, to encapsulate those from the rest of your app and render everything as expected. (see the linked article above for more details).

This emulation mode will also be used if the browser (Google Chrome) has built-in support for ShadowDOM. If you force Angular 2 to use Native view encapsulation for your components, the component decorators have to look like this

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

@Component({
  selector: 'todo-item',
  templateUrl: 'todoitem.html',
  styleUrls: ['styles/todoitem.css']
  encapsulation: ViewEncapsulation.Native
})
export class TodoItemComponent {
    
}

Angular 2 will rely on official ShadowDOM specs and let browsers decide how to deal with your components. Everything works fine in Google Chrome and Opera, but unfortunately there are more browsers in the wild.

Both, Chrome and Opera are supporting ShadowDOM without using any kind of polyfills. But when users visit your app with browsers like Microsoft Edge or Mozialla Firefox or Apple’s Safari, they will see just nothing because those browsers neither have any native implementation for ShadowDOM nor are they shipping any kind of polyfill out of the box. Angular 2 tries to render your app and it will crash as soon as the ShadowDOM API will be called by the Angular 2 core framework.

In order to get ViewEncapsulation.Native working across all browsers, you’ve to put another JavaScript dependency in your website by adding a script reference to WebComponentsJs (see https://github.com/webcomponents/webcomponentsjs). WebComponentsJs will add the required polyfills at runtime (only if the browser doesn’t provide some), so Angular 2 is able to call into ShadowDOM APIs. Some of you may also know project polymer which was targeting also the same issue. Polymer is now part of WebComponentsJs, so you don’t have to make a decision here.