Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document "layers" for single-use components #806

Closed
andyearnshaw opened this issue Apr 12, 2019 · 7 comments
Closed

Document "layers" for single-use components #806

andyearnshaw opened this issue Apr 12, 2019 · 7 comments

Comments

@andyearnshaw
Copy link

There are times when you want to render a component at a specific position in the window. It might be positioned relative to an element, such as a fancy tooltip or popup/context menu, or it might be a modal in the middle of the screen. At the moment, there's no way to render this transparently if you are a third-party on the web page.

Web components give a way to clearly define ownership between page author and component author:

<!-- owned by the page author -->
<my-component foo="bar" baz="qux">
  #shadow-root
    <!-- owned by the component author -->
    <div> ... </div>
</my-component>
// Owned by the component author
class MyComponent extends HTMLElement {
   // ...
}

However, if you want to render something at that arbitrary position, you have to do it in the page author's territory, and you have no encapsulation for the tree you want to add (even a custom element is susceptible to * selectors). With the original spec for ShadowRoot, you could solve this by adding a shadow tree to the document body for your component. If other components also needed a shadow tree they could just add theirs, and the shadow trees stacked. This is no longer planned, there's no interest in it right now, and may never be from some vendors due to complexity.

I wondered if there might be interest in something like a simple layer on top of the viewport with its own stacking context, which is pretty much just a shadow tree. It would have show/hide methods, so you could do something like this:

import template from './component.html';
class FancyToolTip {
  #root = window.createShadowLayer();

  constructor() {
    this.#root.appendChild(template.cloneNode());
  }

  show(text = '') {
    this.#root.querySelector('.tooltip-text').textContent = text;
    this.#root.show();
  }

  hide() {
    this.#root.hide();
  }
}

Whichever layer is shown most recently would have the highest z-order. The layer itself would have no pointer events, but elements in it would.

@rniwa
Copy link
Collaborator

rniwa commented Apr 13, 2019

That's an interesting idea. We do want to keep in mind that this should have some kind of an opt-in from the users of component as well. We don't want to make it possible for a random component in the page to start putting anything where in the page since that kind of invasion of encapsulation from components is just as harmful as pages invading components' implementations.

Toolip might be an interesting case study here because it DOES need to get out out of containing block in some cases. Maybe @smfr or @dbaron have some ideas.

@smfr
Copy link

smfr commented Apr 13, 2019

like a simple layer on top of the viewport with its own stacking context

That sounds like the "top layer" https://fullscreen.spec.whatwg.org/#top-layer

@domenic
Copy link
Collaborator

domenic commented Apr 25, 2019

The proposal sounds similar to whatwg/html#897 , although I'm not sure I understand its connection to the opening few paragraphs of the post.

@andyearnshaw
Copy link
Author

That sounds like the "top layer" https://fullscreen.spec.whatwg.org/#top-layer

The proposal sounds similar to whatwg/html#897 , although I'm not sure I understand its connection to the opening few paragraphs of the post.

Yes, there are definitely similarities. I'm having trouble understanding from the linked discussions, though: when elements are in the top layer, does the rest of the document become inert?

@domenic
Copy link
Collaborator

domenic commented Apr 26, 2019

Not when they're in the top layer, but yes when they're in the blocking elements stack. A decent bit of 897 was discussing how connected those two should be; see e.g. whatwg/html#897 (comment) and the following comments (before we get sidetracked with scope expansion).

@andyearnshaw
Copy link
Author

So something like a tooltip would need to be in the top layer but not in the blocking elements stack. You generally want it on top of everything else but to keep focus on whatever you had it on, or for it to disappear when the mouse is no longer interacting with the bound element, for example. A context menu might go on the blocking elements stack, however, so that users can click away from it to dismiss it without interacting with another element on the page.

Does the proposal for blocking elements stack allow you to add a previously unconnected element to the stack? I think this would be particularly handy for third-party scripts.

@mfreed7
Copy link

mfreed7 commented Apr 20, 2023

So we discussed this in the Web Components F2F, and it appears to be "solved" by a combination of Popover and Anchor Positioning. We'd like to close it.

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

No branches or pull requests

5 participants