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] Example 4 : selectors starting with an identifier #7980

Closed
romainmenke opened this issue Oct 29, 2022 · 10 comments
Closed

[css-nesting-1] Example 4 : selectors starting with an identifier #7980

romainmenke opened this issue Oct 29, 2022 · 10 comments
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. css-nesting-1 Current Work

Comments

@romainmenke
Copy link
Member

romainmenke commented Oct 29, 2022

https://drafts.csswg.org/css-nesting/

Example 4
However, starting the nested selector with an identifier (a type selector, in other words) is invalid:

Does this only apply to the first selector in a list or to each?

invalid :

div {
  color: red;

  input {
    margin: 1em;
  }
}

valid/invalid? :

div {
  color: red;

  :is(input), textarea {
    margin: 1em;
  }

  & input, textarea {
    margin: 1em;
  }
}

From a parser perspective only the first in the list is important. But from an author perspective this is less obvious.

If you remove :is(input) then you need to modify textarea to make it valid again.

I have no preference here, only need to know what to implement

@bradkemper
Copy link
Contributor

I think that should be valid. No need to have that restriction for anywhere other than the beginning of the rule.

@romainmenke
Copy link
Member Author

romainmenke commented Oct 29, 2022

If authors want to enforce that each selector in the list is unambiguous in case of edits they can use a linter to enforce this :

div {
  color: red;

  & input, & textarea {
    margin: 1em;
  }

  :is(input), :is(textarea) {
    margin: 1em;
  }

  :is(input) &, :is(textarea) & {
    margin: 1em;
  }
}

@cdoublev
Copy link
Collaborator

cdoublev commented Oct 31, 2022

Aside (sorry)

If authors want to enforce that each selector in the list is unambiguous in case of edits they can use a linter to enforce this

As a CSS author, I would prefer that a solution be found to remove the restriction on <identifier>, rather than having to remember it or to use a linter. Remember to start with & or @nest (option 1) seems less constraining. As a non-SASS/SCSS author, I also consider option 1 better because nested compound/descendant selectors are explicit. (never mind: it can also be ambiguous in @nest and option 3 allows to explicitly use &).

@romainmenke
Copy link
Member Author

romainmenke commented Oct 31, 2022

As a CSS author, I would prefer that a solution be found to remove the restriction on <identifier>, rather than having to remember it or to use a linter.

see : #7961

@Loirooriol Loirooriol added the css-nesting-1 Current Work label Nov 2, 2022
@sesse
Copy link
Contributor

sesse commented Nov 4, 2022

Blink currently allows starting the second one in the list with an identifier, but it does run into an issue we've talked about before (in the context around parser switching), where deleting the first rule suddenly makes the other one invalid. I'm fine with changing this if people want to, but we'd need to what happens to the rule (does only that selector go away and the sub-rule stays, or does it poison the entire parse).

@romainmenke
Copy link
Member Author

romainmenke commented Nov 4, 2022

Do you mean this case :

div {
  color: red;

  :is(input), textarea, .something {
    margin: 1em;
  }
}

and then changing :is(input), textarea, .something to textarea, .something via CSSOM?

@sesse
Copy link
Contributor

sesse commented Nov 4, 2022

CSSOM is a separate problem (one that we will need to fix, but probably warrants its own issue). I'm more thinking

div {
  .foo, textarea { … }
}

Now the developer figures out they don't need .foo anymore, and removes it everywhere… without realizing that the remaining rule is now wrong and kills the entire rule. Or that if you just switch the ordering, the rule suddenly becomes illegal.

@romainmenke
Copy link
Member Author

Yes the previous iteration of the nesting spec had @nest which allowed users to guard themselves against any and all issues by always writing @nest.

The linter rules needed to help authors write correct nested CSS have become more numerous and more complex with the new syntax.

I have added this example to the list.

they don't need .foo anymore

Also a "simple" re-ordering of selectors.

div {
  textarea, .foo { … }
}

@tabatkins
Copy link
Member

The spec says "The selector of nested style rules must not start with an identifier or a functional notation." - it does not specify "each complex selector of the selector list of a nested style rule". So, the restriction is applied to the selector (list) as a whole, and only affects the first selector in the list.

(This is because the restriction only exists as a parser-level restriction to allow me to tell where a rule starts. Once we know we're in a selector, it doesn't matter what the rest of the selector does.)

@tabatkins tabatkins added the Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. label Jan 10, 2023
@aleclarson
Copy link

For whoever's bothered by this, I've made a Stylelint rule that auto-inserts any missing & prefixes in your CSS file.

https://gist.github.com/aleclarson/2cb1be7aab5500198c985eaf07119ed2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Closed as Question Answered Used when the issue is more of a question than a problem, and it's been answered. css-nesting-1 Current Work
Projects
None yet
Development

No branches or pull requests

7 participants