skeletonlabs / skeleton

A complete design system and component solution, built on Tailwind.
https://skeleton.dev
MIT License
4.94k stars 314 forks source link

Mismatch in Theme Generator's color #739

Closed risalfajar closed 1 year ago

risalfajar commented 1 year ago

Current Behavior

image

When I put a hex value in one of the inputs, I expect the value to appear in the 500 variant of the color. But it don't. For example, when I put #6366f1 in the primary field, the primary 500 should be #6366f1, but in reality it is #1A16D8. I also can't find #6366f1 in any of the generated colors.

Steps To Reproduce

  1. Open Theme Generator
  2. Put a Hex value in one of the field
  3. Check the generated colors hex value

Anything else?

This Pallete Generator recommended by Skeleton works as intended: image

endigo9740 commented 1 year ago

There's a major overhaul to the theme system coming in the next release. I'd recommend reading through this post if you're curious to see what's coming: https://github.com/skeletonlabs/skeleton/issues/598

Likewise you can test the new generator here: https://dev.skeleton.dev/guides/themes/generator

risalfajar commented 1 year ago

Thanks, the new generator is amazing!

Just want to add that there are still a bit of mismatch on some random colors, it isn't much, but maybe you want to take a look. image image

endigo9740 commented 1 year ago

@risalfajar Good catch, but this may be an unfortunate side effect of Tailwind needing RGB colors instead of hex to support alpha transparency. I don't know that they'll always translate 1:1.

Here's roughly how the script works:

  1. The hex color is pass through to shade 500 right away, while the RGB and "on" (text/fill) color generated:

https://github.com/skeletonlabs/skeleton/blob/dev/src/docs/DocsThemer/colors.ts#L96

  1. You can see how the RGB color is generated here:

https://github.com/skeletonlabs/skeleton/blob/dev/src/docs/DocsThemer/colors.ts#L36

This space-separated RGB value is the format Tailwind recommends in their docs for the CSS properties, so that Tailwind can implement the Alpha transparency:

https://tailwindcss.com/docs/customizing-colors#using-css-variables

  1. We then generate the theme CSS, which is a set of CSS properties. Each color looks like this:
--color-primary-500: 15 186 129; 
  1. Tailwind process that as part of our plugin here, again, following the Tailwind docs linked above:

https://github.com/skeletonlabs/skeleton/blob/dev/src/lib/tailwind/theme.cjs#L8

  1. We then apply this stylesheet to the document head, which applies the styles for the live preview:

https://github.com/skeletonlabs/skeleton/blob/dev/src/docs/DocsThemer/DocsThemer.svelte#L106

  1. Finally, the swatch component then displays the generated Tailwind utility color per color cell:

https://github.com/skeletonlabs/skeleton/blob/dev/src/docs/DocsThemer/Swatch.svelte#L18

If an issue is present, it's occurring on step 2 of this process. If you know of any solution for more accurate RGB conversion please let me know. To put it another way, this may just be the nature of hex -> RGB conversation. Even if you generated the hex -> RGB in another tool it may be subject to the same results.

Make sense?

endigo9740 commented 1 year ago

@risalfajar I've done a bit of research on this today. Here are a couple posts that provide some useful insights to this topic.

Essentially hex colors are hexadecimal representations of values. They don't inherently have anything to do with color. It's just a compact format to store these values. Whereas RGB and RGBA are more purpose-built to describe specific colors. So the problem seems to lie in the conversion process, and more specifically, the potential for rounding errors.

Take this for example:

Hex: #00E06C

R: 00 = 0
G: E0 = 224
B: 6C = 108

Here the three sets of hex pairs must be translated to a scale of 0-255 for RGB. These don't always map out 1:1. Rounding errors can occur, which explains why this only occurs sometimes. BUT, here's the important part. The rounding error doesn't really impact the final display by an amount that most users should be able to perceive.

For comparison, here's the two values from your provided screenshots above:

image

And here's the values visually compared in Sketch, a UI/design focused Mac tool (I'd expect similar results in Photoshop):

Screen Shot 2022-12-26 at 11 54 52 AM

Can you tell the difference between the two? Because I can't, and I've worked for nearly 20 years as a professional designer. In fact I handled color calibration between screen and print for a photography studio in the past. My eyes and my equipment are well tuned for this sort of thing.

I'm not saying they ARE the same, and I am annoyed as well that they are not 1:1. But this is so approximate that I don't think anyone will notice the issue without pulling out a color picker like you and your designer.

What I will do is look into implementing a warning message about this issue, and encourage folks to manually hand curate their palettes if the results of our generator are not to their liking. Web-based tooling may not be the best solution to to this though, given the widely know issues with floating point precision errors in Javascript in general.

That said, if you (or anyone seeing this), can provide a more accurate method for conversion, then I'll gladly accept an PR. The logic for this resides here: https://github.com/skeletonlabs/skeleton/blob/dev/src/docs/DocsThemer/colors.ts#L36

risalfajar commented 1 year ago

Thanks for giving a very detail explanation. I just found that tints.dev also suffer the same issue on some colors. And using different color picker (Chrome Extension and Linux app) results in different mismatch values.

I agree with you, the difference is not much for eyes to see. I think this is a very low priority problem. You can even close the issue if you want. I've decided to just go with the generator. 😅

I myself not very experienced in this. So sorry I can't help. And thanks once again!

endigo9740 commented 1 year ago

No worries, glad to help. Thank you for making me aware of the issue, it's was easy to miss! But yeah, unfortunately I'm not sure there's a solution with automated conversion using Javascript.

One of our core team members @ryceg mentioned last night that he's interested in exploring Hex -> HSL as it appears Tailwind now supports this (it's a recent addition). It will most likely be subject to the same issue, but it's at least another avenue to explore. So fingers crossed!

For now I'll go ahead and close this out as, like you, I feel our current solution is good enough. Hopefully others will agree :)