One cool thing about CSS custom properties is that they can be a part of a value. Let’s say you’re using multiple backgrounds to pull off a design. Each background will have its own color, image, repeat, position, etc. It can be verbose!
You have four images:
body {
background-position:
top 10px left 10px,
top 10px right 10px,
bottom 10px right 10px,
bottom 10px left 10px;
background-repeat: no-repeat;
background-image:
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg),
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg),
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg),
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
}
You want to add a fifth in a media query:
@media (min-width: 1500px) {
body {
/* REPEAT all existing backgrounds, then add a fifth. */
}
}
That’s going to be super verbose! You’ll have to repeat each of those four images again, then add the fifth. Lots of duplication there.
One possibility is to create a variable for the base set, then add the fifth much more cleanly:
body {
--baseBackgrounds:
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg),
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg),
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg),
url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
background-position:
top 10px left 10px,
top 10px right 10px,
bottom 10px right 10px,
bottom 10px left 10px;
background-repeat: no-repeat;
background-image: var(--baseBackgrounds);
}
@media (min-width: 1500px) {
body {
background-image:
var(--baseBackgrounds),
url(added-fifth-background.svg);
}
}
But, it’s really up to you. It might make more sense and be easier manage if you made each background image into a variable, and then pieced them together as needed.
body {
--bg1: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg);
--bg2: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg);
--bg3: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg);
--bg4: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
--bg5: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg);
background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4);
}
@media (min-width: 1500px) {
body {
background-image: var(--bg1), var(--bg2), var(--bg3), var(--bg4), var(--bg5);
}
}
Here’s a basic version of that, including a supports query:
See the Pen
Multiple BGs with Custom Properties by Chris Coyier (@chriscoyier)
on CodePen.
Dynamically changing just the part of a value is a huge strength of CSS custom properties!
Note, too, that with backgrounds, it might be best to include the entire shorthand as the variable. That way, it’s much easier to piece everything together at once, rather than needing something like…
--bg_1_url: url();
--bg_1_size: 100px;
--bg_1_repeat: no-repeat;
/* etc. */
It’s easier to put all of the properties into shorthand and use as needed:
body {
--bg_1: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-left.svg) top 10px left 10px / 86px no-repeat;
--bg_2: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-top-right.svg) top 10px right 10px / 86px no-repeat;
--bg_3: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-right.svg) bottom 10px right 10px / 86px no-repeat;
--bg_4: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/angles-bottom-left.svg) bottom 10px left 10px / 86px no-repeat;
background:
var(--bg_1), var(--bg_2),var(--bg_3),var(--bg_4);
}
Hi Chris, Nice article to manage multiple backgrounds in CSS. I have one doubt, is creating a variable in CSS is compatible by every browser?
This is why someone made the web site caniuse.
https://caniuse.com/#feat=css-variables
Add it to your toolset!
Cheers.
Alan, receiving a message about rendering. Is there an issue with some browsers?
bigleegeek
This is a great technique to add to my toolset — and a good reminder that parts of values can be updated with Custom Properties.
Question: What does testing for multiple backgrounds with
@supports
achieve in the example pen? Both Custom Properties and@supports
itself have worse browser support than multiple backgrounds ( https://caniuse.com/#feat=multibackgrounds ), which is near-universal.Unfortunately IE doesn’t support CSS variables. Which pretty much defeats the whole purpose of using them.
In one sense I agree, if YOUR project has to support IE, you can’t really use them. I don’t like the idea of polyfilling them because anything you can polyfill defeats a lot of the purpose.
On the other hand, just because YOUR project supports old IE, doesn’t mean mine does, and I can use them all I want. In fact, I do, on literally every single project I work on.
IE doesn’t support anything, therefore I do not support it in my projects.