Skip to content

[css-animations-2, css-transitions-2] Entry and exit animations for top-layer elements #8189

@chrishtr

Description

@chrishtr

Animating an element into and out of the top layer provides context to the user for a more useful and pleasant interaction. Currently, developers have no way to do so in a way that preserves top-layer status during the animation, and as a result, demos like this one won’t work in cases where exiting the top layer causes a visible change of positioning or z-index. Let's fix that.

TL;DR of proposal

Introduce a new CSS property called top-layer that can be targeted by web developers in their CSS transitions and animations.

This CSS property is not generally available to web developers and will always be set with an !important UA style sheet rule. It’s defined as a CSS property for the purpose of a layered definition that fits within existing animations APIs and concepts, and as a result is easy for developers to use with existing animation APIs.

Example: a <dialog> remaining in the top layer during a 200ms opacity animation during close. The part marked as "New!" is the only addition needed for the developer to delay top-layer removal until the end of the animation.

@keyframes open {
  from { opacity: 0; }
  /* Ending at opacity: 1 is implicit, per existing CSS animations spec */
}
dialog:closed {
  opacity: 1; /* UA default */
  animation: open 200ms;
  transition: top-layer 200ms; /* New! */
}
@keyframes close {
  from { display: block; }
 /* Starting from opacity 1 is implicit, per existing CSS animations spec */ 
  to { opacity: 0; }
}
dialog {
  animation: close 200ms;
}

(full demo except for top-layer here)

Details

Use case

This feature enables support for animation when entering or leaving the top layer. Such animations often wish to preserve top-layer rendering during the course of an “exit” or "entry" animation. Without this feature, it is impossible to perform such an animation.

Top-layer APIs: <dialog>, fullscreen, and popover.

Note: The demo in the TL;DR uses CSS animations, but a CSS transition would additionally require this issue to be resolved to be usable for entry transition animations. We also need to support animating display:none for top layer animations that need it, such as <dialog> (tracked here).

Background on the top layer

The top layer is defined here. It is currently accessed only via the Fullscreen API (here) and the <dialog> element’s showModal method (here). When opening a fullscreen element, the fullscreen spec says “add it to its node document’s top layer”. When closing fullscreen, it says “remove it from its node document’s top layer”.

When calling showModal, the <dialog> spec says “add subject [the dialog element] to subject's node document's top layer”. When closing a dialog, it says “If subject is in its Document's top layer, then remove it”. If an element is already in the top layer, re-adding it to the top layer moves it to the top of the top layer.

Proposed Definition of the top-layer CSS property

The top-layer CSS property determines whether an element is in the top layer. It has two values:

top-layer: browser; /* element is in the top layer */
top-layer: none; /* element is not in the top layer */
  • Default: none
  • Animatable: yes
  • Discrete: yes
  • Accessible to developers: only via transition CSS property values

When an element is “added to the top layer” (see previous section), it is placed in the ordered set of top-layer elements, but the rendering effect of the top layer (putting it in the top-layer stacking context and obeying the rendering order of the ordered set) only applies when top-layer is set.

The element is only removed from the ordered set once top-layer’s computed style has evaluated to none (at the end of the transition, if any). However, the “moved to the top of the top layer” behavior still occurs if the element is “added to the top layer” while animating out (see previous section).

The following UA style rules are added:

dialog {
 top-layer: none !important;
}

dialog:modal:open {
  top-layer: browser !important;
}

:fullscreen {
  top-layer: browser !important;
}

Why shouldn't developers be able to change top-layer outside of transitions?

It’s important to restrict direct developer access because the top layer is a UA-managed resource. Not giving developers direct access guarantees that the UA is able to show top layer content on top of other content, and control eviction from the top layer when needed. This point has been discussed in #6965. If in the future a "developer" top layer is added below the browser one, we could potentially add a third value to top-layer.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions