Name: iron-overlay
Owner: PolymerLabs
Description: Overlay element that overcomes the stacking context trap
Created: 2016-09-09 17:58:56.0
Updated: 2018-03-14 16:52:34.0
Pushed: 2017-12-20 12:57:35.0
Size: 149
Language: HTML
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
Overlays should always render on the top layer. This is achieved using the css
properties position: fixed
and z-index
. When an overlay is contained in a node
that creates a new stacking context,
it causes the overlay to be trapped within it (z-index and position will be relative to
the new stacking context), resulting in problems like this one:
le>
ackdrop {
position: fixed;
top: 0; bottom: 0;
left: 0; right: 0;
z-index: 100;
background-color: rgba(0, 0, 0, 0.5);
verlay {
position: fixed;
z-index: 999;
yle>
class="backdrop"></div>
this creates a new stacking context -->
style="transform: translateZ(0);">
iv class="overlay">
<button>click me!</button>
div>
v>
iron-overlay
works around this issue by “teleporting” its content to a
stacking-context-safe node.
this creates a new stacking context -->
style="transform: translateZ(0);">
utton onclick="this.nextElementSibling.opened = true">Open overlay</button>
ron-overlay>
<template>
<!-- overlay content -->
This text will be stamped and appended to the document body.
</template>
iron-overlay>
v>
It delegates rendering of the overlay content to a renderer (iron-overlay-renderer
).
It won't host the renderer, but request another element to host it through the
events iron-overlay-attach
and iron-overlay-detach
, or append it to <body>
.
It requires overlay contents to be contained in a <template>
(since they need
to be hosted in the renderer).
Takes care of the rendering (e.g. center overlay), and handles the switch from opened state to closed state & viceversa.
Hosts the overlay renderers, keeps track of the opened overlays. This element should
be placed in a stacking-context safe node (e.g. document.body
).
style="transform: translateZ(0);">
utton onclick="this.nextElementSibling.opened = true">Open overlay</button>
ron-overlay>
<template>
<!-- overlay content -->
This text will be contained in iron-overlay-content
</template>
iron-overlay>
v>
it will contain all the overlay renderers -->
n-overlay-container></iron-overlay-container>
Styling must be done in the context of where iron-overlay will be hosted.
iron-overlay
sets the renderer's data-overlay
attribute to be its id, so
that styling of the overlay can be done like this:
tom-style><style is="custom-style">
ata-overlay] {
--iron-overlay-background-color: yellow;
ata-overlay="overlay1"] {
--iron-overlay-background-color: orange;
yle></custom-style>
style="transform: translateZ(0);">
ron-overlay>
<template>Overlay Content</template>
iron-overlay>
ron-overlay id="overlay1">
<template>Overlay 1 Content</template>
iron-overlay>
v>
Content can be styled by passing a <style>
element into the template,
but beware of possible conflicts with classes, as selectors will apply to all
matching elements in the styling context where they're hosted:
n-overlay>
emplate>
<style>
.my-content {
background-color: yellow;
}
</style>
<div class="my-content">Content</div>
template>
on-overlay>
n-overlay>
emplate>
<!-- Will have yellow background as well -->
<div class="my-content">Other Content</div>
template>
on-overlay>
The best approach to ensure style encapsulation is to create a custom element for your content.
n-overlay>
emplate>
<my-content>Content</my-content>
template>
on-overlay>
n-overlay>
emplate>
<my-other-content>Other Content</my-other-content>
template>
on-overlay>