Skip to content
This repository was archived by the owner on May 28, 2024. It is now read-only.
This repository was archived by the owner on May 28, 2024. It is now read-only.

Implement :matches() #48

@SimonSapin

Description

@SimonSapin

Relevant spec: https://drafts.csswg.org/selectors-4/#matches

What makes this non-trivial is the handling of specificity: https://drafts.csswg.org/selectors-4/#specificity-rules

For example, div :matches(.foo, #bar) is equivalent div .foo, div #bar. The latter is a selector list that contains two selectors. (See terminology.) In Selectors level 3, selectors have an intrinsic specificity (here (0, 1, 1) and (1, 0, 1), respectively) but selector lists don’t. This is a consequence of the principle that these two bits of CSS are equivalent:

div .foo, div #bar { color: blue }
div .foo { color: blue }
div #bar { color: blue }

Going back to div :matches(.foo, #bar), preserving the equivalence means that, in Selectors level 4, the specificity is not intrinsic to (all) selectors anymore: the specificity of :matches() depends on which of its arguments actually matches for a given element.

I know of two ways to implement this:

  1. Expand at parse time a selector list that contains :matches() to the equivalent, longer selector list that doesn’t. This works without changing much code, but it cause a combinatorial explosion of the size of selectors with more than one :matches() pseudo-class. For example (from the user-agent stylesheet)

    :matches(dir, menu, ol, ul) :matches(dir, menu, ol, ul) :matches(dir, menu, ul) {
      list-style-type: square;
    }

    … this expands to 64 alternatives. The run-time cost of matching this may be prohibitive

  2. Change our matching code so that specificity is not determined at parse-time but is a result of matching. (A return value of Option<Specificity> instead of bool for a given (element, selector) set of arguments.) This might make more difficult plans to JIT-compile selectors or match them on the GPU

CC @pcwalton, @nox

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions