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