[csswg-drafts] Proposal: Presentation Layers (#13591)

IanBellomy has just created a new issue for https://github.com/w3c/csswg-drafts:

== Proposal: Presentation Layers ==
Proposal for a 'generic' form of `top-layer` that preserves the absolute top-ness of `top-layer`.

### Motivations / Use cases

- Managing alert/popover priorities:
 - ex. A CRUD-action-completed alert should not appear on top of an already displayed non-modal you-will-be-logged-out-soon alert; A tool tip for an item in the partially obscured CRUD alert may or may not need to show on top of both.
 - ex. During a drag-and-drop operation using a bespoke drag-and-drop implementation, a drag-preview should always show on top of any items that might normally appear above all else.
 - ex. Action in a popover that transforms data in the background might be well accompanied by a 'change' indicator that sits above the affected content but below the popover controls.

- Switching between in-flow and 'on-top' presentation contingent on space / screen size while maintaining desired ordering.

- Separate 'where' in a stack an element is displayed (e.g. top-layer) from how (e.g. `display:...`) / ensure an element transitioning to or from `display:none` stays above the document.

- Improved ergonomics for organizing complex UIs with persistent divisions between e.g. artboard, selection-indicators, tool pallets, etc.

- Styling visual focus/emphasis/decoration to be outside a clipped element, visually above its neighboring elements, and potentially within a further removed cropped ancestor.


### Overview

Elements with a `presentation-layer:<name>` rule would be displayed in an ad-hoc container ***behind*** top-layer but above the document.  

The reserved name `Top` would refer to what is now top-layer and be the default value for popovers such that current popover/top-layer behavior would persist as is.

The ordering of named presentation layers would be controllable via an at-rule `@presentation-layer <name>,...`.  Occurrences of `Top` in the declaration would be ignored.

e.g.

````css
@presentation-layer toasts, modals, emphasis;
````
...
````css

button.BookStay{
 anchor-name:stay-button;
  
 .focus-ring{
  presentation-layer:emphasis;  
  anchor-name:stay-button;
  anchor-position:center;
  inset:-8px;
  border:1px solid blue;
 }

} 

.Confirmation[popover]{
 presentation-layer:modals;
}

@media (min-width:5000px){
 .Confirmation[popover]:open{
  presentation-layer:Document;
 }
}

.HostMessageToast{
 presentation-layer:toasts;

 CustomSelect CustomDropdown{
  presentation-layer:Top;
 }
}

````

Elements with a presentation-layer name not included in an `@presentation-layer` declaration would be inserted into a new named presentation-layer just below `Top` , in the order encountered in the document. 

The names `Bottom` and `Document` would also be reserved for a 'back-most' presentation-layer, behind the document, and for default / normal display in the document, respectively.   `Document` could be used in the @-rule to specify presentation-layers below `Document`. `Bottom` is ignored in the @-rule.

eg.
````css
@presentation-layer modals, Document, ambience;

.ReservationConfirmation[popover]{
 presentation-layer:modals;
 
 .destination-preview{
  presentation-layer:ambience;
  position:fixed;
  inset:0;
  background-image: url(skyline.jpg);
  filter:blur(72px);
 }
}

````

### container : presentation

`presentation-layer` behavior would be mimicked at an element-container level via `container-type: presentation; presentation-layers: <name>...` in order to allow elements to 'bust out' of their container's overflow and into an author-controlled level rather than all the way to the top-layer. 

For example, in the a scrollable article below, our button focus ring would sit atop other content but still be cropped to the scrolling container.  

eg.
````css
.ScrollableArticle{
 container: presentation;
 presentation-layers:emphasis;
 overflow:scroll;
 ...
 button .focus-ring{
  presentation-layer:emphasis;
 }
}
````

Similar to `@presentation-layer`, the reserved names `Top`, `Document`, and `Bottom` would be ignored in a presentation-layers rule, and as such, elements will never capture popovers destined for `Top`.

Additional names like `Container-Top`,`Container`,`Container-Bottom` might be reserved for referencing a _relative_ equivalent of `Top`, normal, and `Bottom` in the nearest container, which may be the root document's `Top`, `Document`, `Bottom` if the element is in no other container. 

For presentation containers the container box would determine the bounds of the presentation-layer.

### Nesting 

With the exception of `Top` and `Bottom`, @presentation-layer declarations could be nested.

````css

/* Ok */
@presentation-layer activity{
 @presentation-layer emphasis;
}

/* No effect; 'Top' ignored */
@presentation-layer Top{
 @presentation-layer tipy-top
}

.PeekView{
 container: activity 
 /** No effect; 'Top' ignored */
 presentation-layers: Top, emphasis;
}

/** Equivalent to document{container:presentation; presentation-layers:high-up;} */
@presentation-layer Document{
 @presentation-layer high-up
}

````


Nesting with element / container-based presentation-layers may need to rely on nested element-containers. 

### Ordering within presentation layers

The ordering of elements within a `presentation-layer:<name>` rule follows document order with the following exception: elements for which showModal(), showPopover(), togglePopover() etc. has been invoked always display on top of elements that are only in the same presentation-layer by virtue of their presentation-layer rule. 

The order of such 'imperatively promoted elements' amongst themselves should follow the current behaviors for top layer. In this way current popover / top-layer behavior persists while additional elements may be promoted into the top layer through, e.g. media queries, as necessary. (If an author decides they need imperatively promoted elements *below* rule-promoted elements, they'll likely benefit from organizing around their own named presentation-layers.)


### Hypotheticals / Opportunities:

- Potential basis for granular modal control -- maybe it's the case that an element promoted to a presentation-layer via showModal() should make inert any element in the same or lower presentation layer.
- Improved ability to isolate elements for screen-capture. 
- Possible base for semantics for referring to future specialty presentation destinations, even 'beyond-top-layer' ones, e.g. a window title bar in a PWA, custom cursor, custom drag preview, scroll bars, off-screen, etc.
- Possible mechanism for granular control over view-transition presentation / layering.
- User-controlled ordering of alternatively-rendered content either by providing the renderer a presentation-layer name?
- Semantics for refer to presentation layers in front or behind of the client window? (In only the most secure contexts of course 😉.)


### Conclusion

The hope is that the above would allow authors to clearly express granular visual sorting structures above the document without interfering with the utility of an 'absolute' top layer while mitigating possible foot-guns by gating expressiveness behind a clear opt-in that builds on and resembles existing behaviors.

Please view or discuss this issue at https://github.com/w3c/csswg-drafts/issues/13591 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Tuesday, 3 March 2026 20:12:45 UTC