lukejacksonn / oceanwind

Compiles tailwind shorthand into css at runtime. Succeeded by Twind.
https://twind.dev
264 stars 12 forks source link

Possible Feature: Support `bg-opacity-x` & `border-opacity-x` #34

Closed rschristian closed 3 years ago

rschristian commented 3 years ago

Sorry, back here again to talk about what looks to be an annoying feature. Also not entirely sure what this 'feature' is called, so please excuse the dreadful title.

Tonight I went to use bg-opacity-50 for some element when I noticed it was not included. Certainly not a problem by any means, as there are plenty of ways around this, but it is a nice to have.

Tailwind Docs for class

Not sure if this is a known limitation or not, I didn't see any immediate reference to it though I could've missed something.

It looks like the way Tailwind implements this is by converting any color that's on an element with this class into rgba() format, regardless of what was provided. I'm just going by an old Tailwind site I have running in production though, so that might not be 100% true. Using something like bg-opacity-x will then set a CSS variable to X% as a float and that is used as the alpha argument in the aforementioned rgba().

Now the way I see it is that this is rather impossible to implement without doing some color value processing, which may be a bit heavy and outside the scope of what this library wants to achieve. You'll have to let me know.

I've played around with this a bit tonight and it seems possible to maybe look for keys like bg-opacity in the style object output and then append / inject the right alpha format into the color string. bg-opacity-50 + background-color: '#999' = background-color: '#9998'. Though even in this short example it would mean converting 3 digit hex to 6 in order to capture 75% opacity (BF) accurately. Maybe easier to cheat though and call it C in those cases.

As of now I only have found two usages of CSS variables like this: bg-opacity-x and border-opacity-x. There very well may be more, and this could be opening a huge can of worms, so I'd fully understanding not wanting to implement this sort of stuff. There's certainly enough possible alternatives.

Anyways, thought I'd ask for your thoughts before I messed around with this any further. Cheers for this awesome library you've put out, I've really enjoyed using it.

lukejacksonn commented 3 years ago

Hey Christian, thanks for the time you have taken to explore this. The good news is that you are bang on the money! Tailwind seem to be making more and more use of CSS variables, it is especially noticeable in V2.

So I think we should try take a similar approach. Otion (and so oceanwind) can handle CSS variables so I think we should give it a try here and see how it works.

From what I can figure out, our bg-opacity-x rule should look like this:

case "bg":
  switch (i[1]) {
    case "opacity":
      out["--ow-bg-opacity"] = i[2]
      break;
    ...
  }
  ...
  break;

Then, as you correctly point out.. we will have to change the translations of any rule involving backgrounds to:

out['background-color'] = `rgba(${hexToRBG(colorHelper(i[1]))}, var(--ow-bg-opacity, 1))`

This will convert the provided color into a hex theme color then into its RGB equivalent, then apply any --ow-bg-opacity variable that was set otherwise default to 1.

I wouldn't be too concerned about perf of the HEX/RGB conversion, we should be able to get away with some bit shifting IIRC. Does all of that make sense? 😅

Happy to help so any questions, please do fire away!

rschristian commented 3 years ago

I hadn't yet actually glanced at V2 at all, so I didn't realize how much they expanded usage. Already outdated by the time I wrote this 😅

I didn't actually know that CSS vars had an optional fallback value. Guess I never thought to look at MDN. That makes this much simpler. The more you learn.

I can look at getting something together this evening (US time at least) but the last little thing would be supported colors. Converting 6 digit hex to RGB would be simple enough, but obviously there's a whole bunch of potential color formats in use by users. Not only are there hex, rgb, hsl, and their alpha variants, but there's also keywords. Should it all be supported?

rschristian commented 3 years ago

@lukejacksonn

I've marked the PR as ready for review. All color formats should be supported. I've only added this for bg and border shorthands as those are the only ones that I know of that use this. Certainly let me know if there are others this should be expanded to.