Description
What problem are you trying to solve?
Inconsistent Stacking: Right now, elements in the top layer are added on top of each other based solely on the order they are added. This can cause issues for UI elements that need to stay on top, such as toast notifications or live chat. A new element added later might unintentionally cover them.
What solutions exist today?
Manual Removal and Re-addition: A developer can remove the element they want on top from the top layer temporarily using JavaScript. Then, after adding the new item, they can re-add the desired item back to the top layer. There currently is no way to detect items being added to the top layer stack you must track this yourself as you promote items.
This manual tracking will become impractical as more and more libraries use top layer (via popover and dialog).
How would you solve it?
We'd need a few things added to be able to do this nicely,
- An event that lets us know when a new item has been added to the top layer stack. I'd assume this event would be on the
window
,document
orbody
unless a newwindow.topLayer
property was added. - A way to check what is in the top layer stack and in what order. Again I'm uncertain of how this would look in practice unless it was added to the afore mentioned
window.topLayer
property. - The ability to change the order of an element on the stack. I can't think of a reason to fully reorder the stack so perhaps just being able to move a specific element back to the top would be enough. I would imagine something like
element.sendToTop()
orwindow.topLayer.bringToTop(element)
.
I think the first two points can be solved by making window.topLayer
return an Element
that can be observed with a mutation observer. I'm not sure how practical this approach would be but here is a snippet of how I'd imagine it working.
const el = document.querySelector('#important-element')
const callback = (list) => {
if(list.every(({ type }) => type !== 'childList')) return;
const childArray = Array.from(window.topLayer.children);
const childPosition = childArray.indexOf(el);
// stop if the element is not in the top layer or if the element is already on top
if (childPosition === -1 || childPosition === childArray.length - 1) return;
window.topLayer.bringToFront(el);
}
const observer = new MutationObserver(callback);
observer.observe(window.topLayer, { childList: true });
Anything else?
Whilst this is not a major issue, I'm sure it will start being a thorn in the side of developers as popover
and dialog
become more prevalent.
This issue is on the toastify and shows that it is already becoming something noticed by the community (even if slowly).
Also here is an exchange I had on twitter/x with @bramus looking for an existing solution.