Skip to content

anything that creates a stacking context should sort in the positioned descendants z-ordering list #2717

Open
@dbaron

Description

CSS 2.1 Appendix E, about painting order has a basic separation between handling of descendants that are positioned (painted in steps 3, 8, and 9) and things that are not positioned (painted in steps 4, 5, 6, and 7). It defines that separation in terms of "positioned descendants". Note that in level 2 of CSS, positioning is the only thing that causes creation of a stacking context (via the interaction of position and z-index).

There are a substantial number of features introduced in CSS since level 2 that create stacking contexts. These include: opacity, transforms (via transform, perspective, transform-style, rotate, scale, or translate), isolation, filter, mix-blend-mode, clip-path, and mask/mask-image, will-change, and contain. (These are the ones implemented in Gecko.)

Some of the specifications of these properties define not only that a stacking context is created, but that elements with the property are painted as though they were a "positioned descendant". For example, the spec for opacity says:

... implementations must create a new stacking context for any element with opacity less than 1. If an element with opacity less than 1 is not positioned, then it is painted on the same layer, within its parent stacking context, as positioned elements with stack level 0. If an element with opacity less than 1 is positioned, the ‘z-index’ property applies as described in [CSS21], except that if the used value is ‘auto’ then the element behaves exactly as if it were ‘0’.

Some of the other specs don't, however, explicitly require this.

I believe that, since the rules for painting descendants in steps 4-7 assume that floats are intended to interleave between the block-level and inline-level descendants of an element, those rules don't make sense for any of the features that create stacking contexts.

I think the current situation of vague specs has led to implementation bugs. In Gecko, for most of these features, we've assumed that they should be painted in the order used for positioned descendants, but we haven't done this for isolation or will-change. I suspect that may produce strange results (the code looks like we paint them at the order of inline content, which means they'll be storted incorrectly relative to later inline content or earlier positioned elements or stacking contexts). We'd like to fix this and might move ahead with doing the same for isolation and will-change in the absence of a clear direction here.

I think that:

  • all of the features that create stacking contexts should lead to an element being painted at the position reserved in CSS 2 for positioned descendants
    • I believe Gecko's Web compatibility shows this is safe for properties other than isolation, contain, and will-change, though it's still worth investigating what other engines do.
  • we should edit CSS 2 to reflect this change, i.e., that everything that creates a stacking context is painted in steps 3, 8 (not using the auto variant!), and 9. This will tie the behavior to the definition of stacking contexts and make it much harder for new specifications to get this wrong.
  • this edit needs to be done carefully since:
    • z-index only applies to elements that are actually positioned
    • when a stacking context is created, z-index: auto becomes z-index: 0 (even when it "doesn't apply")
  • we could consider applying z-index to elements other than positioned elements, although there may be compatibility risk (I haven't tested behavior across engines)

Activity

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

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions