Skip to content

Add support for Shadow DOM V1 #23636

Closed
Closed

Description

@robwormald

Centralizing discussion on Shadow DOM V1 changeover.

Good explainer documentation on what's changed between v0 -> v1: https://hayato.io/2016/shadowdomv1/

Shadow Root Changes:

element.createShadowRoot() => .attachShadow({ mode: 'open' | 'closed' })

This is the big change, currently breaking people using Edge (unexpectedly), as it supports the new Shadow DOM API but not the old.

Proposed Fix:

  • Add two new ViewEncapsulation enum options: ShadowDom and ClosedShadowDom (name to be bikeshedded) - doing this rather than changing the behavior of ViewEncapsulation.Native means we can do this as a feature release rather than a breaking change. ViewEncapsulation.Native should be deprecated.

Shadow DOM emulation / ViewEncapsulation.Emulated:

Currently the Emulated view encapsulation is based on the V0 semantics.

Proposed Fix:

We should update the emulation of Shadow DOM via Shadow CSS to match the V1 semantics - we currently use an (old) version of the ShadowCSS polyfill from @webcomponents - https://github.com/angular/angular/blob/c8a1a14b87e5907458e8e87021e47f9796cb3257/packages/compiler/src/shadow_css.ts.

Additionally, we should consider allowing developers to polyfill Shadow DOM at runtime via the Shadow DOM polyfill at https://www.webcomponents.org/polyfills. This would allow developers to author with the expectation of Shadow DOM being available, and fall back via the polyfill, rather than having to author two components etc to support modern and legacy browsers. This polyfill has a non-trivial runtime overhead, but as all major browsers (except Edge ) support it, this may be desirable for some developers.

::content selector => ::slotted (compound-selector)

V1 introduces a new psuedo-selector for styling slotted nodes. This is of course supported natively, but we should work out the correct way to (maybe) emulate this in encapsulated mode, what to do about ng-deep, etc.

Content Projection Changes

<content> elements are deprecated, in favor of the new <slot> API. <slot> has already been added to the schema, so developers are able to use native slot functionality (this is generally only useful in Angular Elements, for now).

Proposed Fix:

@pkozlowski-opensource has proposed a new <ng-slot> API that would supersede <ng-content> - this means aligning with the distribution semantics of the V1 API. This may mean introducing something like @SlotChild()/@SlotChildren() decorators and deprecating @ContentChild()/@ContentChildren().

Additionally, we should align the semantics of how our emulated distribution of nodes works against the V1 spec, including default content: #12530

Longer term, we should consider if the part/theme proposal covers our developers' use cases, and potentially emulate it at build time for theming? See #22515

Related Issues:
#11595
#2567
#7856
#19059
#3882
#12530

Activity

  1. added
    featureLabel used to distinguish feature request from other issues
    area: coreIssues related to the framework runtime
    on May 1, 2018
  2. added this to the Backlog milestone on May 1, 2018
  3. robwormald commented on May 1, 2018

    @robwormald
    ContributorAuthor

    The Shadow DOM fix is the most time-critical, as it's confusing for developers - many browsers never supported the V0 API, but now support the V1, which Angular doesn't support.

    Chrome has also deprecated v0 - https://www.chromestatus.com/feature/4507242028072960

  4. cyrilletuzi commented on May 2, 2018

    @cyrilletuzi
    Contributor

    Does this mean even Angular Elements still use the ShadowDOM v0? If so, it's a serious issue: as one the goal of Elements is to produce standard web components, it needs to have proper ShadowDOM support.

  5. sarunint commented on May 2, 2018

    @sarunint
    Contributor

    Is this issue going to be pre-v6 or post-v6 thing?

  6. robwormald commented on May 2, 2018

    @robwormald
    ContributorAuthor

    @cyrilletuzi yes, that's why I opened the issue.

    @sarunint not likely to land in 6.0, but we can probably do the initial work as additive for a 6.x release

  7. DanielNetzer commented on May 2, 2018

    @DanielNetzer

    is there any workaround that we can use to support angular/elements for Edge/IE11 till this fix will be released?

  8. robwormald commented on May 2, 2018

    @robwormald
    ContributorAuthor

    @DanielNetzer as of this writing, neither Edge nor IE11 support Shadow DOM, so its a non-issue there. Use ViewEncapsulation.Emulated.

  9. sandangel commented on May 3, 2018

    @sandangel

    @robwormald Hi, may I ask 2 questions?
    1/ does this means we should not use Angular Element in production yet until Angular team release a version that compatible with Shadow DOM v1?
    2/ The proposed fix with Content Projection seems like a big breaking change, is that all we have to do is replace all ng-content, ContentChild, ContentChildren with ng-slot, SlotChild, SlotChildren to update? If so hopefully ng update command could do that job.

  10. trotyl commented on May 3, 2018

    @trotyl
    Contributor

    @sandangel Angular Element is just a wrapper for normal Angular Dynamic Component, without any special runtime behavior, all Angular Components are using ViewEncapsulation.Emulated by default, so are Angular Elements.

    To be more clear, Angular Elements do care about Custom Elements, but not Shadow DOM, Template Tag nor HTML Import.

  11. sandangel commented on May 3, 2018

    @sandangel

    @trotyl hi, thanks for your answer.
    I think different: angular element use Emulated by default, but since we can put it anywhere, is that safer to use ViewEncapsulation.Native instead? In that situation does moving to Shadow V1 introduce some breaking change? (like we have to change to ViewEncapsulation.ShadowDom / ClosedShadowDom).

  12. trotyl commented on May 3, 2018

    @trotyl
    Contributor

    @sandangel I won't suggest ViewEncapsulation.Native for now, given:

    • The emulation process in Angular is mainly compiler-based rather than using runtime polyfills, which has little effect on final size;
    • There're still many browsers supports none of Shadow DOM V0 or V1, eg. IE and Edge;
    • Mixing Emulated and Native components may sometimes break encapsulation like ViewEncapsulation.Emulated/ViewEncapsulation.Native behave differently on child components #20449, also bad for performance as copying styles everywhere (to make interop work), and 3rd-party libs are not likely to use Native;

    I'm not sure about the migration path, but all breaking changes for valid API usage should follow the Angular Deprecation Policy, providing at least two-major-version deprecation stage.

    @robwormald This should also cover #12530 which is supported by Shadow DOM V1.

  13. 1 remaining item

  14. benoitjchevalier commented on Jun 14, 2018

    @benoitjchevalier

    Can we hope this makes it into Angular 7? We're building a library of Web Components using Angular Elements and possibly including other Web Components built with other libraries (Polymer), which will be using Shadow Dom. Having v1 Shadow Dom support [and polyfilling Shadow Dom (v1), but that can be done on our side] will probably be a need for us as we won't be able to mix V0 component with V1 components.

    Aligning content projection to use slots would also help standardizing the use of our components. I'm also hoping it will make it easier grabbing a ref to another web component that has been projected into an angular element (I'm having a hard time finding a clean way of doing it with @ContentChild right now)

  15. akanass commented on Jun 20, 2018

    @akanass

    Hope we can have a solution soon because ViewEncapsulation.Native is broken on Safari and my customElement doesn’t work on it.

    Thanks for your collaboration and your time on this problem.

  16. Thilo84 commented on Jun 21, 2018

    @Thilo84

    I'm also waiting for a working solution for the ViewEncapsulation.Native. There is currently no working polyfill for IE.
    I would be very happy if this pull request https://github.com/angular/angular/pull/19059 could be merged soon.
    Thank you very much for your effort.

  17. robwormald commented on Jun 30, 2018

    @robwormald
    ContributorAuthor

    Update on this - #24718 should fix the root issue (the renderer using the old Shadow DOM API) - it's an opt-in as ViewEncapsulation.ShadowDom - note that using the new Shadow DOM API will likely impact styles if you are relying on the old API (that's why it's a new option).

    Note that this API (like the existing Native option) requires Shadow DOM to be available in the browser, and provides no polyfills or benefits for browsers that do not support Shadow DOM (At this writing, Chrome and Safari support v1, Firefox support is imminent and Edge's status is unknown. IE will never support Shadow DOM.

  18. schnrap commented on Jul 15, 2018

    @schnrap

    Does this new ViewEncapsulation.ShadowDom offer a way to access the host children other than @ContentChildren? Or do we need to wait for a new option like a @SlotChildren for this (like suggested above)?

  19. robwormald commented on Jul 16, 2018

    @robwormald
    ContributorAuthor

    @schnrap it does not add anything additional for @ContentChildren - we'll look at something for this post-ivy. For the moment, you can use the (slotchange) event, slot.assignedNodes() and node.assignedSlot(), as well as just vanilla shadowRoot.querySelector or MutationObserver

  20. schnrap commented on Jul 20, 2018

    @schnrap

    I got it working this way, perfect!
    Thank you very much for your time and help.

  21. robwormald commented on Sep 25, 2018

    @robwormald
    ContributorAuthor

    implemented in c9844a2

  22. benoitjchevalier commented on Sep 25, 2018

    @benoitjchevalier

    @robwormald with this closed is there any plan to support shadow dom polyfills and in particular css variables in Angular Elements?

  23. evanjmg commented on Aug 12, 2019

    @evanjmg

    Any update on shadow DOM polyfills?

  24. angular-automatic-lock-bot commented on Sep 15, 2019

    @angular-automatic-lock-bot

    This issue has been automatically locked due to inactivity.
    Please file a new issue if you are encountering a similar or related problem.

    Read more about our automatic conversation locking policy.

    This action has been performed automatically by a bot.

  25. locked and limited conversation to collaborators on Sep 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area: coreIssues related to the framework runtimefeatureLabel used to distinguish feature request from other issuesfreq1: lowhotlist: devrel

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions