goober icon indicating copy to clipboard operation
goober copied to clipboard

Handling specificity when using the css function.

Open jakehamilton opened this issue 4 years ago • 4 comments

Hi there! 👋

I've been using the css function to handle styles but ran into an issue of specificity when trying to combine them. Here's an example sandbox.

The issue here seems to be that goober doesn't provide a mechanism to combine class names while overriding them in the correct order. Emotion supports this through their own helper (linked here). I'm not sure if this is something that goober is able to (or wants to) support, but I figured I'd mention it 😅

I did see #98 which looked similar, but it seemed like the discussion was about using the styled function instead of css which can require a different component architecture. Ideally, a user would be able to combine generated class names such that they override styles based on the order they are specified.


Also wanted to mention that this is a great library that I'm happily using in a few of my projects. Thank you 🙏

jakehamilton avatar Oct 13 '20 18:10 jakehamilton

Hey @jakehamilton!

Thank you so much for your kind words! Much appreciate it!

This looks really curios 😄 . The issue you've linked was indeed touching something else and more based on how to makeshift a custom styled method.

🤔 Thinking about it, css calls are generating at call site the className and in turn the appending/prepending. So, let's call it clx, would have to somehow get the proper order of className and figure out if they would need to be prepended or appended based on their position I suppose.

I'm gonna get back with some answers on how feasible, read small impact on size, this could be.

cristianbote avatar Oct 13 '20 20:10 cristianbote

Hey @cristianbote, thanks for the reply!

I'm sure you'll have a better understanding of how to go about solving this problem that I will, but I figured I'd give my thoughts here.

I wonder if it's possible for us to create a completely new class and inject the styles used from previous ones. This strategy would probably be more intensive since we'll either need to read and parse existing styles or have to keep them around in memory. Probably not ideal unless they are already saved in memory (which I don't think they are).

In terms of size, I wonder if we could cheat a bit and make it a separate package? I've gotten a lot of mileage out of goober as it exists today, so it would be fair to say that this could be a separate enhancement similar to goober-autoprefixer. One of the reasons that I really like goober is that I can pull in just 1kb for most (or all) of what I need. I'd love if we could find a solution to keep that benefit, but would also understand if it's not possible.

jakehamilton avatar Oct 13 '20 21:10 jakehamilton

Oh, I may be wrong about having the styles in memory after reading more of the source: https://github.com/cristianbote/goober/blob/master/src/core/hash.js#L42

jakehamilton avatar Oct 13 '20 21:10 jakehamilton

Hey @cristianbote! Hope you're doing well and were able to have a good holiday season.

I'd put this on the back-burner as my attention was needed on other projects, but I found some time tonight to hack up a simple solution for this problem (see #236). By exposing the cache, we can duplicate and scope styles when requested. This is currently working for one of my projects and solves the issue of css call order determining specificity.

This solution may have some side effects that I'm not aware of. I noticed that cache contains a mapping for class -> styles as well as styles -> class, but my PR only adds pairs for the class -> styles half. I don't think anything will attempt to use these incorrectly, but it's possible if there's a part of the library that attempts to retrieve a class name from these scoped styles.

As well, this solution adds clx as a first-class member of the goober library, increasing bundle size a bit. Because of this, I've had to increase the allowed file size set in the package.json.

file gzip
goober.modern.js 1.27 kb
goober.js 1.25 kb
Filesize results screenshot

jakehamilton avatar Jan 15 '21 10:01 jakehamilton