Skip to content
This repository has been archived by the owner on Dec 19, 2024. It is now read-only.

[WIP] overcome stacking context #155

Closed
wants to merge 41 commits into from
Closed

Conversation

valdrinkoshi
Copy link
Member

@valdrinkoshi valdrinkoshi commented Apr 11, 2016

Update

Polymer 2.0-preview will no longer produce type-extension elements (aka is="...") (rationale here), hence we won't merge this PR as it introduces new custom elements extending <template>.

Further work is being done in https://github.com/PolymerLabs/iron-overlay

Further discussion on the issue and how the platform can help users here whatwg/html#2525


The problem

Overlays that are contained into a stacking context that is not the main one (the one of document.body) can have positioning problems, cropping, be non-interactive (see example). This is a known limitation mentioned also in the docs:

You must ensure no element has a stacking context with a higher z-index than its parent stacking context. You should place this element as a child of <body> whenever possible.

These are some stacking-context-related issues from components relying on iron-overlay-behavior:
PolymerElements/paper-dialog#7
Polymer/polymer-starter-kit#154
PolymerElements/paper-dialog#79
PolymerElements/paper-dialog#44
PolymerElements/paper-drawer-panel#122

Proposal

  • Contain overlays in templates so they are attached only once in the document
  • Stamp them and append them into The Right Place™
  • Allow content distribution into the overlays contained in an element's shadowDOM (e.g. paper-menu-button use case)

This is achieved with 4 components:

iron-overlay-template

It is a template that takes care of stamping the overlay and delegating the attach to the listeners of the event iron-overlay-template-attach. Styles can be added into the template, they’ll be appended into the shadowDOM as well. It provides a handy pointer to the overlay instance (myTemplate.overlay).

iron-overlay-container

It is the Right Place™. It listens to the iron-overlay-template-attach event and appends the overlay in its shadowDOM (so that style encapsulating is guaranteed). You can declare multiple instances (e.g. 1 container for toasts and 1 for dialogs).

iron-overlay-content-template

It is a template that stamps and appends its content into contentParent. This is needed by elements that host an overlay into their shadowDOM and want to distribute content in them, e.g. paper-menu-button needs to distribute dropdown content into the iron-dropdown declared in its shadowDOM.

iron-overlay-host-behavior

It searches for the iron-overlay-template in the shadowDOM and sets it as the contentParent of the iron-overlay-content-template in the lightDOM (the distributed one).

This changes the markup of the user of your element like this:

<!-- this div creates a new stacking context -->
<div style="transform: translateZ(0)">
  <!-- it will have stacking context issues -->
  <paper-dialog id="dialog" modal></paper-dialog>
  <button onclick="dialog.open()">open</button> 

  <!-- it will be appended in the iron-overlay-container! -->
  <template id="dialogTemplate" is="overlay-template">
    <paper-dialog modal></paper-dialog>
  </template>
  <button onclick="dialogTemplate.overlay.open()">open</button> 

  <!-- it will have stacking context issues -->
  <paper-menu-button>
    <button class="dropdown-trigger">open</button>
    <div class="dropdown-content">Content</div>
  </paper-menu-button>

  <!-- assuming it implements iron-overlay-host-behavior -->
  <paper-menu-button>
    <button class="dropdown-trigger">open</button>
    <!-- it will be stamped into the overlay -->
    <template is="overlay-content">
      <div class="dropdown-content">Content</div>
    </template>
  </paper-menu-button>
</div>
<!-- this is where I want the overlays to be contained -->
<iron-overlay-container></iron-overlay-container>

Styling

The content of an iron-overlay-template will be added into an iron-overlay-container's root, so one could define styles into the template:

<template is="overlay-template">
  <style> 
    paper-dialog { background-color: yellow; }
  </style>
  <paper-dialog modal></paper-dialog>
</template>

Beware that this applies to all the paper-dialogs that will be contained in an iron-overlay-container.

If you are an element author which hosts an overlay into its shadowDOM, you might want to namespace it, so that its styles won't conflict with other overlays of the same kind:

<dom-module id="my-element">
<template> 
  <content></content>
  <template is="overlay-template">
    <style>
      paper-dialog.my-element-dialog { background-color: orange; }
    </style>
    <paper-dialog class="my-element-dialog" modal></paper-dialog>
  </template>
</template>
...

Note for element authors using iron-host-behavior: Polymer currently removes all style nodes from a template, so as a temporary solution you'll need to use <script type="css"> instead of <style>.

@valdrinkoshi valdrinkoshi force-pushed the stacking-context branch 3 times, most recently from e78b795 to 499faa5 Compare April 12, 2016 00:51
<link rel="import" href="iron-overlay-manager.html">

<!--
`iron-overlay-container` stamps overlays to `document.body` in order to avoid
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'stamps' is a bit of a pedantic term. Can we use something more user friendly? Adds? Creates?

@valdrinkoshi
Copy link
Member Author

@notwaldorf feedback incorporated!

@cdata FYI, here's the PR for overlays 2.0

@valdrinkoshi valdrinkoshi force-pushed the stacking-context branch 2 times, most recently from ae8febf to 8b62268 Compare May 18, 2016 21:57
@zixsma
Copy link

zixsma commented Jan 12, 2017

@valdrinkoshi Any update on this one?

@Tigerino
Copy link

Any update?

@valdrinkoshi
Copy link
Member Author

@Tigerino @zixsma sorry for the late reply. I've updated this PR's description with more info. In short with Polymer 2.0 we'll be able to extend from another custom element but not from the native elements like template, input, a etc, hence the idea is to have a new custom element, iron-overlay, which knows how to handle a <template> child (aka stamp it in a stacking context safe place).

@valdrinkoshi
Copy link
Member Author

Will close this PR but keep the branch 👌

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants