tailwindlabs / tailwindcss

A utility-first CSS framework for rapid UI development.
https://tailwindcss.com/
MIT License
86.67k stars 4.44k forks source link

Bug: vite warnings when minifying css - Empty :where() generated #16582

Open Damato opened 1 month ago

Damato commented 1 month ago

The code in question:

  body::-webkit-scrollbar {
        @apply bg-zinc-100 dark:bg-zinc-800;
  }

The error on bundling:

  warnings when minifying css:
  ▲ [WARNING] Unexpected ")" [css-syntax-error]

  <stdin>:14:30:
        14 │ body::-webkit-scrollbar:where(){background-color:var(--color-zinc-...
           ╵                               ^

  ▲ [WARNING] Unexpected ")" [css-syntax-error]

  <stdin>:16:36:
        16 │ ...:-webkit-scrollbar-thumb:where(){border-color:var(--color-zinc-...
           ╵                                   ^

General detail

I am stumped, as I am getting weird behaviours on CSS minification.

In digging deeper it seems that it generates an empty where() when it should generate none. It is only on build, and it is valid CSS that gets altered. Details are added below.

I also found the same recently reported behaviour in the daisyui repo. It seems they are struggling with an empty :is() being generated. It is a consistent pattern, as I do not use daisyui, but both our projects include Tailwind 4, and same type of issue.

Link for reference. https://github.com/saadeghi/daisyui/issues/3453

Happy to provide more data as needed, to make lives easier for devs and anyone else with the issue.


What version of TailwindCSS are you using?

  "tailwindcss": "^4.0.4",

Project detail

  "@sveltejs/kit": "^2.16.0",
  "@sveltejs/vite-plugin-svelte": "^5.0.0",
  "@tailwindcss/vite",
  "vite": "^6.0.0"

Command / IDE

  vite build
  VS Code
wongjn commented 1 month ago

Would you be able to provide a reproduction please?

Edit: was able to replicate it with:

@reference "tailwindcsst/theme.css";

@custom-variant dark (&:where(.dark, .dark *));

body::-webkit-scrollbar {
  @apply bg-zinc-100 dark:bg-zinc-800;
}

Using Vite as well as the CLI:

body::-webkit-scrollbar{background-color:var(--color-zinc-100)}body::-webkit-scrollbar:where(){background-color:var(--color-zinc-800)}

Edit: Seems to work fine in Lightning CSS Playground but it does not have the nonStandard.deepSelectorCombinator available in it which could be the culprit.

Indeed, editing the CLI code to bypass transform() outputs valid CSS:

body::-webkit-scrollbar {
  background-color: var(--color-zinc-100);
  &:where(.dark, .dark *) {
    background-color: var(--color-zinc-800);
  }
}

It seems like it is a Lightning CSS bug.

Sourav9063 commented 1 month ago

Facing the same issue using nuxt 3 when there are any pseudo-element the issue occurs

.p-autocomplete-input-chip input::placeholder {
    @apply text-surface-500 dark:text-surface-400
}

when minified

.p-autocomplete-input-chip input::-moz-placeholder:where(){color:color-mix(in srgb,var(--p-surface-400)100%,transparent)}.p-autocomplete-input-chip input::placeholder:where(){color:color-mix(in srgb,var(--p-surface-400)100%,transparent)}

same issue for other pseudo-element like before after

transforming (254) assets/styles/tailwind.css
 WARN  warnings when minifying css:                                                                                                 11:09:43 PM
▲ [WARNING] Unexpected ")" [css-syntax-error]

    <stdin>:1:38439:
      1 │ ...p input::-moz-placeholder:where(){color:color-mix(in srgb,var(--...
        ╵                                    ^

▲ [WARNING] Unexpected ")" [css-syntax-error]

    <stdin>:1:38555:
      1 │ ...t-chip input::placeholder:where(){color:color-mix(in srgb,var(--...
        ╵                                    ^

▲ [WARNING] Unexpected ")" [css-syntax-error]
    <stdin>:1:159866:
      1 │ ...gglebutton-checked:before:where(){background-color:color-mix(in ...
        ╵                                    ^

▲ [WARNING] Unexpected ")" [css-syntax-error]

    <stdin>:1:263060:
      1 │ ...onfirmpopup-flipped:after:where(){border-top-color:color-mix(in ...
        ╵                                    ^

▲ [WARNING] Unexpected ")" [css-syntax-error]

    <stdin>:1:263302:
      1 │ ...nfirmpopup-flipped:before:where(){border-top-color:color-mix(in ...
        ╵                                    ^

▲ [WARNING] Unexpected ")" [css-syntax-error]

    <stdin>:1:269485:
      1 │ ...r.p-popover-flipped:after:where(){border-top-color:color-mix(in ...
        ╵                                    ^

▲ [WARNING] Unexpected ")" [css-syntax-error]

    <stdin>:1:269737:
      1 │ ....p-popover-flipped:before:where(){border-top-color:color-mix(in ...
        ╵                                    ^
wongjn commented 1 month ago

Upon further digging I believe this happens because the @applys is actually causing invalid CSS and this causes Lightning CSS to trip up a little bit too.

If we were to use ::before as a clearer example,

@reference "tailwindcsst/theme.css";

@custom-variant dark (&:where(.dark, .dark *));

foo::before {
  @apply text-black dark:text-white;
}

Would compile to:

foo::before {
  color: var(--color-black);

  &:where(.dark, .dark *) {
    color: var(--color-white);
  }
}

Which in itself is like:

foo::before {
  color: var(--color-black);
}

foo::before:where(.dark, .dark *) {
  color: var(--color-white);
}

That second rule is invalid - ::before needs to go at the end.


As an aside, Adam Wathan (creator of Tailwind) does seem to advocate avoiding @apply:

So consider trying to leverage your templating system instead of writing any CSS at all.

Otherwise, you could write the above as:

foo {
  &::before {
    color: var(--color-black);
  }

  @variant dark {
    &::before {
      color: var(--color-white);
    }
  }
}
Damato commented 1 month ago

Thanks @wongjn for all the effort!