Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[css-nesting-1] Ambiguity of specificity when no nesting selector is used #9069

Open
keithjgrant opened this issue Jul 14, 2023 · 3 comments

Comments

@keithjgrant
Copy link
Contributor

keithjgrant commented Jul 14, 2023

The specification discusses specificity under the section on the nesting selector (&):

The specificity of the nesting selector is equal to the largest specificity among the complex selectors in the parent style rule’s selector list (identical to the behavior of :is()).

However, it doesn't seem to directly address specificity for nested selectors that have multiple parent selectors but do not use &.

.foo,
#foo {
  .bar { ... }
}

Is the nested selector here also equivalent to :is(.foo, #foo) .bar? (or, in other words, is a leading & implicit in this example?)

The current implementations in both Chrome and Safari seem to interpret it that way (demo), and I think this probably makes sense from an implementation standpoint, but I'm having trouble finding something concrete in the spec that states this one way or the other.

@plinss
Copy link
Member

plinss commented Jul 14, 2023

As an author, I’d expect that to be equivalent to two rules that cascade independently with different specificity.

.foo .bar { … }
#foo .bar { … }

@tabatkins
Copy link
Member

Yeah, if the nesting selector is implied, it should still have an effect on specificity, same as if it was written explicitly. I'll fix the spec. (This matches the serialization behavior we decided on last week.)

@plinss We decided against that behavior in :is() because it drastically complicates the implementation - you have to track which virtual selector was matched (where the number of virtual selectors are multiplicative in the number of :is() selectors. The effect with Nesting is identical, so we went with identical behavior. (This does differ from preprocessors that decompose nested selectors directly, but we fundamentally can't match that without running into this explosion/complexity issue.)

@plinss
Copy link
Member

plinss commented Jul 18, 2023

Yeah, but if an author writes:

.foo .bar,
#foo .bar { ... }

They get the equivalent behavior of:

.foo .bar { ... }
#foo .bar { ... }

right? e.g. two rules with different specificity that cascade independently

If

.foo,
#bar {
  .bar { ... }
}

behaves like one rule with a single specificity, then this is an author foot-gun and will cause all sorts of cascading bugs, especially when people refactor existing stylesheets in to nested ones.

I understand it complicates the implementation, but the behavior is not identical and author needs win over implementer needs.

Discuss this at the F2F? (and maybe this needs to get moved into a new issue)

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

No branches or pull requests

3 participants