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

[Bug]: :where(:nth-child(n), :nth-child(n) ~ *) has second :nth-child parentheses removed #1216

Closed
Zr4g0n opened this issue Oct 28, 2021 · 3 comments
Labels

Comments

@Zr4g0n
Copy link

Zr4g0n commented Oct 28, 2021

Describe the bug

The following selector fails when using minifySelectors

:where(:nth-child(7),:nth-child(7) ~ *){
is changed to
:where(:nth-child(7),:nth-child~*){

As long as the content of the second :nth-child() is the same as the first, the second :nth-child() gets the parentheses removed.

disabling minifySelectors fixes this.

this also happens with :is(...) and :not(...)
this also happens with :nth-last-child(), :nth-of-type() and :nth-last-of-type()

Expected behaviour

:where(:nth-child(7),:nth-child(7) ~ *){
gets changed to
:where(:nth-child(7),:nth-child(7)~*){

Steps to reproduce

1: clone https://github.com/Zr4g0n/nth-child-css-bug
2: run npx postcss input.css > output.css
3: output.css has broken selector

Version

4.1.11

Preset

default

Environment

System:
  OS: Windows 10 10.0.19042
  CPU: (24) x64 AMD Ryzen 9 3900X 12-Core Processor
  Memory: 36.40 GB / 63.92 GB
Windows PowerShell

Package details

folder@ C:\Dev Personal\folder
+-- cssnano@5.0.8
| +-- cssnano-preset-default@5.1.4
| | +-- css-declaration-sorter@6.1.3
| | | `-- postcss@8.3.11 deduped
| | +-- cssnano-utils@2.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-calc@8.0.0
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-colormin@5.2.0
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-convert-values@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-discard-comments@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-discard-duplicates@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-discard-empty@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-discard-overridden@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-merge-longhand@5.0.2
| | | +-- postcss@8.3.11 deduped
| | | `-- stylehacks@5.0.1
| | |   `-- postcss@8.3.11 deduped
| | +-- postcss-merge-rules@5.0.2
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-minify-font-values@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-minify-gradients@5.0.2
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-minify-params@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-minify-selectors@5.1.0
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-charset@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-display-values@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-positions@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-repeat-style@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-string@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-timing-functions@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-unicode@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-url@5.0.2
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-normalize-whitespace@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-ordered-values@5.0.2
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-reduce-initial@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-reduce-transforms@5.0.1
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-svgo@5.0.2
| | | `-- postcss@8.3.11 deduped
| | +-- postcss-unique-selectors@5.0.1
| | | `-- postcss@8.3.11 deduped
| | `-- postcss@8.3.11 deduped
| `-- postcss@8.3.11 deduped
+-- postcss-cli@9.0.1
| +-- postcss-reporter@7.0.4
| | `-- postcss@8.3.11 deduped
| `-- postcss@8.3.11 deduped
`-- postcss@8.3.11

Additional context

The following have no issues:
:where(:nth-child(6),:nth-child(7) ~ *){ -> :where(:nth-child(6),:nth-child(7)~*){
:is(:nth-child(foo),:nth-child(bar) ~ *){ -> :is(:nth-child(foo),:nth-child(bar)~*){

The following all results in the second parenthesis getting removed:
:where(:nth-child(7),:nth-child(7) ~ *){ -> :where(:nth-child(7),:nth-child~*){
:where(:nth-child(2),:nth-child(2) ~ *){ -> :where(:nth-child(2),:nth-child~*){
:where(:nth-child(1),:nth-child(1) ~ *){ -> :where(:first-child),:nth-child~*){
:where(:nth-child(foo),:nth-child(foo) ~ *){ -> :where(:nth-child(foo),:nth-child~*){
:is(:nth-child(7),:nth-child(7) ~ *){ -> :is(:nth-child(7),:nth-child~*){
:not(:nth-child(7),:nth-child(7) ~ *){ -> :not(:nth-child(7),:nth-child~*){
:where(:nth-child(7),:nth-child(7) #id){ -> :where(:nth-child(7),:nth-child #id){

I found the bug initially when using a selector looking for a class's direct children when there's exactly 6 of them.

.class>*:where(:first-child:nth-last-child(6), 
               :first-child:nth-last-child(6) ~ *){
@Zr4g0n
Copy link
Author

Zr4g0n commented Oct 28, 2021

For reasons beyond me, this actually works:
:where(:nth-child(7),:nth-child(7 /**/ ) ~ *){ -> :where(:nth-child(7),:nth-child(7)~*){

EDIT: further testing showed that the extra space, not the comment in and of itself, was enough. In other words, this also works:
:where(:nth-child(7),:nth-child(7 ) ~ *){ -> :where(:nth-child(7),:nth-child(7)~*){

EDIT2:
This also fails
:where(:nth-child(6), :nth-last-child(6), :nth-of-type(6), :nth-last-of-type(6)){ -> :where(:nth-child(6),:nth-last-child,:nth-of-type,:nth-last-of-type){

@ludofischer
Copy link
Collaborator

Confirmed in 5.0.12

@ludofischer
Copy link
Collaborator

ludofischer commented Mar 12, 2022

I think there might be a bug in postcss-selector-parser, because the argument of the second :nth-child pseudo selector is not in the AST when it's identical to the argument of the first.

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

No branches or pull requests

2 participants