angular: [@angular/animations] ViewEncapsulation.ShadowDom breaks Angular Animations

I’m submitting a…


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

As title mentioned, setting ViewEncapsulation.ShadowDom will cause the Animations not being able to run at all. Use-case: I’m building an Angular Element in conjunction with Angular Animations to see if the two play well together.

Expected behavior

Setting ShadowDom Encapsulation strategy should work with Angular Animations.

Minimal reproduction of the problem with instructions

What is the motivation / use case for changing the behavior?

Environment


Angular version: 6.1.4


Browser:
- [x] Chrome (desktop) version XX
- [ ] Chrome (Android) version XX
- [ ] Chrome (iOS) version XX
- [ ] Firefox version XX
- [ ] Safari (desktop) version XX
- [ ] Safari (iOS) version XX
- [ ] IE version XX
- [ ] Edge version XX
 
For Tooling issues:
- Node version: 10.x  
- Platform:  Mac

Others:

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 22
  • Comments: 21 (2 by maintainers)

Commits related to this issue

Most upvoted comments

@alexeykostevich thx. This monkey-patch fixes it for the web animations case:

import { ɵWebAnimationsDriver } from '@angular/animations/browser';
ɵWebAnimationsDriver.prototype.containsElement = (el1: any, el2: any) => {
  // Travel up the tree to the root node.
  let elem = el2;
  while (elem && elem !== document.documentElement) {
    if (elem === el1)
      return true;
    elem = elem.parentNode || elem.host;
  }
  return false;
};

Our team faced the same issue while building encapsulated Web Components for a browser extension.

Please, let me share some our findings — probably, this could be helpful to get this tricky issue fixed one day.

Angular Animations uses different mechanisms depending on a browser:

  • Web Animations is used for browsers that support Web Animations API.
  • CSS Keyframes is used as a fallback for other browsers.

Web Animations

When Web Animations is used, the issue is caused by the WebAnimationsDriver module. The module does not take into account shadow DOM in the implementation of the containsElement method.

https://github.com/angular/angular/blob/877f9ad7b9151324c4a94d3c80e7d37691bb9fd5/packages/animations/browser/src/render/web_animations/web_animations_driver.ts#L28

As a result, Angular thinks that elements inside shadow DOM are not presented on a page (but just in memory) and skips animation.

https://github.com/angular/angular/blob/877f9ad7b9151324c4a94d3c80e7d37691bb9fd5/packages/animations/browser/src/render/transition_animation_engine.ts#L973

CSS Keyframes

When CSS Keyframes is used, Angular inherits the same issue as with Web Animations (through some shared modules).

In addition to this, Angular adds generated CSS with keyframes to the <head> but not inside shadow DOM. As a result, these styles are not visible for Web Component elements.

https://github.com/angular/angular/blob/877f9ad7b9151324c4a94d3c80e7d37691bb9fd5/packages/animations/browser/src/render/css_keyframes/css_keyframes_driver.ts#L107

Still an issue in Angular 10

Any update on this?

I’m afraid there is no update on fixing this at the moment. I am at full capacity with getting the new linker stuff ready - but I will take a look at the linked PR when I get a chance. Perhaps early next week.

Can confirm this is still an issue in Angular 9