tailwindlabs / tailwindcss-jit

MIT License
2.19k stars 40 forks source link

Arbitrary values using calc() with whitespace #192

Closed wagerfield closed 3 years ago

wagerfield commented 3 years ago

What version of @tailwindcss/jit are you using?

0.1.17

What version of Node.js are you using?

14.15.4

What build tool (or framework if it abstracts the build tool) are you using?

next@10.1.2

What browser are you using?

Chrome Version 89.0.4389.90 (Official Build) (x86_64)

What operating system are you using?

Mac OSX Big Sur v11.2.3

Reproduction repository

https://github.com/wagerfield/tailwind-jit-calc

When using calc() within the new arbitrary value class syntax, classes are not generated when the body of the calc function contains spaces:

<div class="h-[calc(100px + 50px * 2)]">This does not work</div>
<div class="h-[calc(100px+50px*2)]">This does work</div>

I expect the solution might be as simple as removing whitespace from the contents of arbitrary class names eg.

.h-[calc(100px + 50px * 2)] --> .h-[calc(100px+50px*2)]

...but not sure if that's possible or not?

fedeci commented 3 years ago

I can work on this.

adamwathan commented 3 years ago

Yeah this isn't possible I'm afraid, you can't have spaces in class names because spaces are what the browser uses to delimit class names.

It's no different than how "font-bold bg-black" can never be treated as a single class, you know?

I suppose you could technically generate a selector containing multiple classes like:

.h-\[calc\(100px.\+.50px.\*.\2\]

But then technically this would work too:

<div class="2] * + 50px h-[calc(100px">

Since the order of class names doesn't matter. You'd run into collisions with other classes containing spaces as well I think.

So our solution is just to remove spaces, again since whitespace is not allowed within a CSS class.

fedeci commented 3 years ago

Isn't it what @wagerfield asked for?

adamwathan commented 3 years ago

I'm not sure what you mean, this is impossible:

<div class="h-[calc(100px + 50px * 2)]">This does not work</div>

Classes can't have spaces, the browser will not read that as one class. The browser sees 5 different classes there, h-[calc(100px, +, 50px, *, and 2)].

This isn't something we can change in Tailwind, the browser will never treat that as a single class. Generating a selector that includes 5 classes means you can then use those classes in any order which also doesn't make sense.

We also can't process/rewrite your HTML to update your class attributes if that's what you mean.

OP said:

I expect the solution might be as simple as removing whitespace from the contents of arbitrary class names eg.

We can't remove the whitespace from your HTML, you'd have to remove it yourself. And when you remove it, everything already works like OP mentioned 👍🏻

wagerfield commented 3 years ago

@adamwathan clearly I was having a bit of a brain fart when I reported this issue—my apologies!

For whatever reason my head went into "I can just whack whatever CSS values I want into the square brackets" and naturally I wanted format the calc() body with spaces between operators since that's what I'd do in CSS.

Totally understand why this is not possible and why it's not and shouldn't be within TW's remit to update/rewrite your classes.

Perhaps it's worth considering adding an error/callout to the VSCode plugin in future to callout misuse of the square bracket notation ie.

/\[\s\]$/.test(class) ---> Error: whitespace found in square brackets

...just an idea to save people like myself form themselves.

Thanks for the detailed explanation 😄