Skip to content

Add CSS :has() selector performance tips #40280

@jryans

Description

@jryans

Proposal

I recently learned from Firefox developers that certain forms of CSS :has() selectors can have vastly different performance characteristics when I reported a Firefox bug.

They shared the following tips:

anchoring :has() to an element (or to all elements) slow all DOM mutations inside that subtree (more the more complex the selector inside :has() is). So stuff like body:has() or :root:has() or *:has() are just a recipe for bad performance

  1. :has(...) with an under-constrained compound may trigger many subtree-traversals: e.g. With :has(.foo), every DOM mutation will cause subtree traversals to see if that element does have .foo in the subtree.
  2. :has(...) with an under-constrained inner selector compound may trigger many ancestor-traversals: e.g. With .ancestor:has(.foo > *), any DOM mutation will cause ancestor traversals to see if there's a :has() anchor to be invalidated. i.e. We need to check if the mutated DOM element has a .foo parent, and if we do, need to check for .ancestor to restyle.
  3. Any occurrence of above can affect invalidation performance of otherwise well-constrained :has() selectors.

I would like to add this somewhere on MDN so these performance implications can become more widely known, but I wasn't sure where to put it.

Potential pages that occurred to me include:

I wasn't sure if the :has() page itself was okay or not, as it might be required to match a very specific format like other CSS pages.

Browser support

No response

Tasks

  • [ ]

Dependencies

  • [ ]

Additional information

No response

Are you willing to support this work?

Yes, I can help write content once the contect place for it to live is decided.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Content:CSSCascading Style Sheets docsaccepting PRFeel free to open a PR to resolve this issuegoal: best practices(Experimental label) Issues about content displaying unusual approaches.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions