29

Is there a way to use CSS variables when specifying gradient colors with transparency, e.g.

:root {
  --accent-color: #dfd0a5;
}

h1{
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(red(var(--accent-color)), green(var(--accent-color)), blue(var(--accent-color)), 1));
}
0

2 Answers 2

45

You can use variables, but you can't sample the individual red, green and blue components from a single hex value in CSS.

If you're simply looking to apply an alpha component to an existing RGB triplet, you can specify the entire triplet as a comma-separated list of decimal values instead of a hex value, and substitute it directly into the rgba() function as a single opaque token:

:root {
  --accent-color: 223, 208, 165;
}

h1 {
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(var(--accent-color), 1));
}

If you want to specify and control individual R, G and B values with rgba(), you will need to specify a variable for each color component as a decimal value, and reference each variable within the rgba() function like so:

:root {
  --accent-red: 223;
  --accent-green: 208;
  --accent-blue: 165;
}

h1 {
  background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(var(--accent-red), var(--accent-green), var(--accent-blue), 1));
}
Sign up to request clarification or add additional context in comments.

8 Comments

I am assuming that browser support is not an issue here, but in case anyone is wondering, only Firefox implements cascading variables at the moment.
I doubt that even this will be possible. You can replace the whole color value but to synthesize color from variable components you will need something like calc() but in color space.
@c-smile: There is no restriction on which part(s) of a value in a style declaration var() may appear in, as long as the value substitutions result in a valid declaration (see w3.org/TR/css-variables-1/#using-variables). And sure enough, it works on the only current implementation.
@c-smile: From the spec link: "If a property contains one or more var() functions, and those functions are syntactically valid, the entire property’s grammar must be assumed to be valid at parse time. It is only syntax-checked at computed-value time, after var() functions have been substituted." So as far as the rgb()/rgba() grammar is concerned, all it sees is rgba(223, 208, 165, 1), after the substitutions have been performed. If one of the variables was either a number outside the 0-255 range, or not a number at all, then the value would become invalid after substituting that value.
@c-smile: (You probably meant inefficient, not ineffective.) True - Mozilla hasn't commented on the performance aspect. Either they're not worried about it yet, or they were able to optimize it.
|
2

@boltclock said it all, but you can save a bit of time if your project has a scss preprocessor.

You can do a little tweak to achieve what you want :

// Scss
@mixin defineColorRGB ($color, $red, $green, $blue) {
    #{$color}: unquote("rgb(#{$red}, #{$green}, #{$blue})");
    #{$color}-r: #{$red};
    #{$color}-g: #{$green};
    #{$color}-b: #{$blue};
}

Then in you css, you can do this:

::root {
    @include defineColorRGB(--accentColor, red(#dfd0a5), green(#dfd0a5), blue(#dfd0a5));
}

You will end up with 4 different css variables, one for your color, and one for each color channel.

Then you can use it almost like you wrote it:

h1{
    background: linear-gradient(
        to right, rgba(255, 255, 255, 0),
        rgba(var(--accent-color-r), var(--accent-color-g), var(--accent-color-b), 1)
    );
}

I find it a very convenient way to initialize my css variables, and use it in most of my projects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.