Tailwindcss: Feature Proposal: Function for adding alpha to a color

Created on 11 Nov 2017  路  16Comments  路  Source: tailwindlabs/tailwindcss

Hi,

I would like to submit the following feature proposal: Function for adding alpha to a color.

Main reason is because SASS/LESS functions are useless since this is a postCSS framework but also i believe that a color palette should consist only of opaque colors and not mind about opacity.

Have already added the below function inside evaluateTailwindFunctions.js for my personal use and if you believe that such a function would benefit others then i could open a proper PR

colorWithAlpha: (path, opacity = 1, defaultValue = '#000') => {
  let color = _lodash2.default.get(options, _lodash2.default.trim(path, `'"`), defaultValue);
  if (color.indexOf('rgb(') === 0) {
    let rgb = color.replace(/([^1234567890\,]*)/g, '')
    return `rgba(${rgb},${opacity})`
  } else if (color.indexOf('#') === 0) {
    let hex = color.replace(/([^1234567890abcdefABCDEF]*)/, '')
    if (hex.length !== 3 && hex.length !== 6) return color
    if (hex.length === 3) hex = `${hex}${hex}`
    let rgb = hex.match(/.{1,2}/g).map(val => parseInt(val, 16)).join(',')
    return `rgba(${rgb},${opacity})`
  }
  return color
}

Thank you,
GL

Most helpful comment

Hey @lilisgeorge! So the "Tailwind way" to do this would be to add those rgba colors to your color palette; you don't want to be writing CSS and referencing color values with config if you don't have to, and you especially don't want to be modifying those values in your CSS because that's what leads to a stylesheet full of magic values.

You want to pick your colors from a predefined set, and adding colors with an alpha channel to that predefined set is totally a reasonable thing to do.

That said if you really wanted to do this, a better approach would be to use an existing PostCSS plugin like postcss-color-function which gives you really powerful color manipulation tools and works great with Tailwind.

For example, you can easily write CSS like this:

.text-purple-50 {
  color: color(config('colors.purple') a(50%));
}

...which will generate:

.text-purple-50 {
  color: rgba(149, 97, 226, 0.5);
}

I've created a demo project showing it in action here:

https://github.com/adamwathan/tailwind-color-function-demo

Again all that being said, in my opinion the best approach is to add these colors to your color palette explicitly 馃憤

All 16 comments

Hey @lilisgeorge! So the "Tailwind way" to do this would be to add those rgba colors to your color palette; you don't want to be writing CSS and referencing color values with config if you don't have to, and you especially don't want to be modifying those values in your CSS because that's what leads to a stylesheet full of magic values.

You want to pick your colors from a predefined set, and adding colors with an alpha channel to that predefined set is totally a reasonable thing to do.

That said if you really wanted to do this, a better approach would be to use an existing PostCSS plugin like postcss-color-function which gives you really powerful color manipulation tools and works great with Tailwind.

For example, you can easily write CSS like this:

.text-purple-50 {
  color: color(config('colors.purple') a(50%));
}

...which will generate:

.text-purple-50 {
  color: rgba(149, 97, 226, 0.5);
}

I've created a demo project showing it in action here:

https://github.com/adamwathan/tailwind-color-function-demo

Again all that being said, in my opinion the best approach is to add these colors to your color palette explicitly 馃憤

@adamwathan could we actually use the CSS color function to declare a relationship of swatches within the tailwind config? I am not as big a fan of hardcoded hex values. I know we can probably use HSL as well, but was wondering if we could use postcss-color-function inside tailwind.js, or if that would break parsing.

You definitely can 馃憤 If you give me an example of something you'd like to try, I can give it a whirl quickly and verify it works as you'd expect.

@adamwathan

So my thoughts are, we define a base-gray, and then mix with tints, shades, and saturation to achieve a relational color scale. Maybe this is a function that is applicable to an array of our base colors, or whatever.

  'grey-base': '#9babb4',

// ( I don't know the color function syntax off the top of my head)
'grey-darkest': color(config('colors.grey-base') modifier modifier; 
'grey-darker': color(config('colors.grey-base') different modifier different modifier;
etc.

Then, if I ever change my grey-base hex or HSL value, my color scale is already auto-calculated. If individual modifiers needs to be changed, this is easier for a dev to do than to go and edit every hex value just because the HUE changed.

Yeah so you can definitely do that, the only trick is you have to make sure that it's a string in your config file since those functions don't actually exist until processing time:

var colors = {
  'grey': '#70818a',
  'grey-light': 'color(config(colors.grey) lightness(+ 5%))',
  'grey-dark': 'color(config(colors.grey) lightness(- 5%))',
}

There's probably color manipulation libraries you could use directly in JS too if you wanted; that's the beauty of the Tailwind config file being pure JS, you can import any libraries you want and do whatever madness tickles your fancy 馃槃

Thanks! @adamwathan Another way I've done it with HSL / sass in the past.

$primary: hsl(230, 45%, 56%);

---

$primary-tint: hsl(hue($primary), 70%, 94%);

So declaring $primary as our base color, and then when defining primary-tint, we extract the hue from $primary and then mix it with different saturation and lightness values.

If I were to write that, and let Sass or a postCSS plugin do its thing, would it have any issues?

I've done that a lot too, works really well!

You can't do that with Sass with Tailwind since your color palette is defined in your config file instead of in Sass, but you can totally accomplish the same thing by just writing JavaScript in your config file:

var hues = {
    'primary': 230,
}
var colors = {
  'primary': `hsl(${hues['primary']}, 45%, 56%)`,
  'primary-tint': `hsl(${hues['primary']}, 70%, 34%)`,
}

Makes sense! Thanks so much!

Could write a couple of functions if you wanted to:

function hsl(hue, saturation, lightness) {
    return `hsl(${hue}, ${saturation}, ${lightness})`
}

var hues = {
    'primary': 230,
}
var colors = {
  'primary': hsl(hues['primary'], '45%', '56%'),
  'primary-tint': hsl(hues['primary'], '70%', '34%'),
}

Feel free to get creative in there 馃槃

Yes, I love that approach. I would actually suggest maybe having something like that be the default of the tailwind config, since replacing 4 hue values (with maybe some tweaks to the modifiers) is much faster than editing all the hex values. But I defer to you. I'll go ahead with this method!

However something like background opacity, e.g. bg-black-opacity-50, would be really helpful.

Some ideas for opacity colors recycling the current set of colors (no additional alpha colors)

Without custom properties

@keyframes opacify {
  to { color: transparent; }
}

.opacify-text-50 {
  animation: 1s -0.5s 1 paused opacify; 
}

Source: https://twitter.com/ScottKellum/status/1214273219626057728?s=20

With custom properties

.text-black {
  --opacity: 1;
  color: rgba(0,0,0,var(--opacity));
}

.opacify-text-50 {
  --opacity: 0.5;
}
md5-71b93bfaa1e8869cdb6310ebdd6aa58a


@vricop Love the idea. Seems to look like the new transform way of doing things. I'd love to see this in the core, or as a drop in replacement.

@vricop Love the idea. Seems to look like the new transform way of doing things. I'd love to see this in the core, or as a drop in replacement.

Yeah the composable transform utilities blowed my mind up. What an idea! The animation trick for opacity colors is really awesome too. I want to play more with it to see how colors look compared to rgba + custom properties.

The proposal is closed. But as @adamwathan said a function can be created to achieve something like that.

What about just using the hex transparency feature? Have a variant that adds on the 2 digits like #ffffff50 for 50% transparent white? Has decent browser support, but not perfect... https://caniuse.com/#feat=css-rrggbbaa

Was this page helpful?
0 / 5 - 0 ratings

Related issues

divdax picture divdax  路  3Comments

paulhuisman picture paulhuisman  路  3Comments

afuno picture afuno  路  3Comments

nternetinspired picture nternetinspired  路  3Comments

Tjoosten picture Tjoosten  路  3Comments