Is there a current or proposed way to set individual layers of multiple backgrounds?
Unfortunately there is no way to do that in regular CSS. You can only change an entire property, not part of it. Which is why we have separate properties like background-image
, background-color
to start with. But nothing more fine-grained than that.
As ScottS suggested, pseudo-elements could be a way to go but you will probably have the same problems as multiple separate div elements.
If your main goal is to avoid typing code over and over, a good solution would be to use a CSS preprocessor like SASS. Your SCSS would then be something like this:
$img-side: url("image/building-side.png");
$img-dark: url("image/shade-dark.png");
$img-mid: url("image/shade-mid.png");
$img-light: url("image/shade-light.png");
.building-texture {
background: transparent, $img-side;
}
.shade-dark {
background: $img-dark, $img-side;
}
.shade-mid {
background: $img-mid, $img-side;
}
.shade-light {
background: $img-light, $img-side;
}
It would compile down to the more bulky CSS (with full URL definitions) but you certainly save a lot on development time. SASS can also help you generate the vendor prefixes using mixins (there is also Compass which adds that to SASS).
In fact, there is an upcoming CSS variables spec which you may be able to use in future, however I don't think any browsers support it yet.
Abstract it with Pseudo Elements
I am not aware of any way to "swap" a single background yet. One workaround is based off the "separate elements" technique, but the inner element is a pseudo-element instead. I have no idea about rendering speed. It also has the drawback that it will not work for IE8, as you cannot apply filter
to pseudo-elements. However, since you are using the idea in conjunction with CSS3 perspective and such, the IE8 caveat is not an issue for you.
This achieves the abstraction of the texture from the shading. It could even add another layer through an :after
pseudo-element, and it still could use multiple backgrounds in each of the three if needed/desired.
Here is the fiddle.
Sample Code:
HTML
<div class="texture"></div>
<div class="texture light"></div>
<div class="texture medium"></div>
<div class="texture dark"></div>
CSS (core)
.texture {
position: relative;
background: url(http://www.dummyimage.com/12x16/ff0000/ffffff.png&text=X++) top left repeat;
}
.light:before,
.medium:before,
.dark:before {
content: '';
position: absolute;
top:0;
right: 0;
bottom:0;
left: 0;
}
.light:before {
background: -moz-linear-gradient(left, rgba(0,0,0,0.3) 0%, rgba(0,0,0,0.1) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(0,0,0,0.3)), color-stop(100%,rgba(0,0,0,0.1)));
background: -webkit-linear-gradient(left, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0.1) 100%);
background: -o-linear-gradient(left, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0.1) 100%);
background: -ms-linear-gradient(left, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0.1) 100%);
background: linear-gradient(to right, rgba(0,0,0,0.3) 0%,rgba(0,0,0,0.1) 100%);
}
.medium:before {
background: -moz-linear-gradient(left, rgba(0,0,0,0.6) 0%, rgba(0,0,0,0.2) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(0,0,0,0.6)), color-stop(100%,rgba(0,0,0,0.2)));
background: -webkit-linear-gradient(left, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.2) 100%);
background: -o-linear-gradient(left, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.2) 100%);
background: -ms-linear-gradient(left, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.2) 100%);
background: linear-gradient(to right, rgba(0,0,0,0.6) 0%,rgba(0,0,0,0.2) 100%);
}
.dark:before {
background: -moz-linear-gradient(left, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.3) 100%);
background: -webkit-gradient(linear, left top, right top, color-stop(0%,rgba(0,0,0,0.8)), color-stop(100%,rgba(0,0,0,0.3)));
background: -webkit-linear-gradient(left, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0.3) 100%);
background: -o-linear-gradient(left, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0.3) 100%);
background: -ms-linear-gradient(left, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0.3) 100%);
background: linear-gradient(to right, rgba(0,0,0,0.8) 0%,rgba(0,0,0,0.3) 100%);
}