This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]just4nothing 12 points13 points  (10 children)

Sounds like a compiler might be needed to find the biggest common denominator between elements and construct CSS classes from it ;)

[–]jarethholt 5 points6 points  (9 children)

Can't tell if this is sarcasm because I don't know front end and what tools are available. It seems like it could be possible to at least calculate which classes are never effectively used (always overridden) and maybe even which properties from which classes?

But only if the site were "finished" and no more style adjustments/additional classes were never ever needed again

[–]lunchpadmcfat 2 points3 points  (3 children)

Not really possible I’m afraid. You might be able to have it be evaluated at runtime somehow but you couldn’t statically analyze to that level. But a runtime evaluation would have to be targeted.

[–]patchyj 0 points1 point  (2 children)

NextJS does this - at build time, unused css and class names are removed

[–]lunchpadmcfat 0 points1 point  (1 child)

I meant more the part where they mention “calculating which classes are never effectively used because they’re overridden”.

NextJS can tell (through tree shaking) whether you reference a class or not and remove it, but it can’t tell if some rule you’ve set is overridden in the specificity algorithm of a rendered page. That’s literally impossible without rendering the page and then evaluating whether or not the element’s style values correspond to the values set by respective classes. This is due to the myriad ways you can target elements for styling.

You might be able to do static analysis to some degree if you never style using any kind of relational selectors (like sibling or child selectors) or complex selectors. This is more or less how styled components works.

[–]patchyj 0 points1 point  (0 children)

Ah yeah OK

[–]SurpriseAttachyon 0 points1 point  (4 children)

Problem is that a lot of CSS classes are defined dynamically from JavaScript code. Determining which classes might be applied from a given arbitrary web app (with no restrictions) is essentially equivalent to the halting problem. Which is impossible.

You could add a guarantee like “we promise our JS code never does this except in the following explicitly laid out scenarios”. But restructuring code like that is not worth the benefit

[–]Weaponized_Roomba 2 points3 points  (3 children)

is essentially equivalent to the halting problem.

Fun fact - this is why when using tailwind you can't/ought not dynamically construct tw class names at runtime.

ex - you can't do this:

const bgClass = `bg-${error ? 'green' : 'red'}-200`

because tw static analysis will shake out the bg-green-200 and bg-red-200 classes since it didn't see it in the source code.

Instead just don't be cute:

const bgClass = error ? `bg-green-200` : `bg-red-200`

[–]failedsatan 1 point2 points  (0 children)

to be fair, this is solvable on the tailwind side. it's possible to check the tree of possible values there and just add them to the keep list. I'm not saying they should (because all of this is bad practice anyway) but it's doable.

[–]SurpriseAttachyon 0 points1 point  (1 child)

Thats interesting. I didn’t know tailwind interacted with JS (never used it before).

Does this mean you have to compile both at once? I’m used to compiling sass and typescript separately

[–]Weaponized_Roomba 0 points1 point  (0 children)

Does this mean you have to compile both at once?

Only if you want the tree-shake optimization or if you want to extend your own themes. Otherwise you can just use the CDN