Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I override only the second image in a multiple background image declaration?

How can I utilize the cascade to override only the second image in a multiple background image declaration?

I have specified a standard style for lis, with two background images (the kitten, and the fish on the right side). I've also specified a style for li.secondary where I want to change only the second of the two background images:

li { 
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAYAAAA/xX6fAAAA/ElEQVR42q2WYQ3DIBSE5wAJk1AJSKiESpiESakEJCChEpAwCW/vJSw0LPQoHMn3A0q5R7leeIjIFNo2JSm+Zz5DSAy6oLan8lKiIjV5fGu8u+TnrkfIKftpUQGks3Au8qNE6yOx1Sb/xPJYyH3EURW4QsHGZ5NB3K0dDpDwDvEZysAZvvP4znVpwTVcmrAgLsLX/yXhP+xfrOyuza00sbFZ7p5TAGlyYMF/J4axNClOvKKVJnEmTa6gpgkSM0Ca8HdITxOiSwuzLjVoAUAUxIWQBXESMQTpSWQd4r0GuxiJsZPII0F6EnUZg5hES7dZWEkExPj3GiDCv9d8AVEGli2R88rKAAAAAElFTkSuQmCC) repeat-y 90% center,
  #CCC url("http://placekitten.com/275/300") repeat right center;
  margin: 1em;
  padding: 1em;
  color: #FFF;
  font-weight: bold;
 }

li.secondary {
  background: #CCC url("http://placekitten.com/325/300") repeat left 10%;
}

JSFiddle: http://jsfiddle.net/KatieK/9zcnp/1/

But the new declaration for background: blows out the first background image (the fish). How can I address only the second background image in a cascading rule?

like image 462
KatieK Avatar asked Feb 06 '13 22:02

KatieK


2 Answers

Unfortunately, the way the cascade works makes it impossible to override individual background layers without repeating the rest of the layers in each declaration.

In general, the cascade works on a per-declaration basis, where each declaration consists of exactly one property and one value:

/* Declaration */
property: value;

A comma-separated list of background layers counts as a single value for the purposes of the cascade, which is why your second background declaration completely overrides the first.1

While background is a shorthand for several other properties, it is not a shorthand for individual background layers, as they do not have their own properties. Since individual layer properties don't exist, you cannot use the cascade to override only certain layers while keeping the rest.2

This is also why prefixed gradients in layered backgrounds are so verbose and repetitive. Sadly for us, this is a limitation of the CSS syntax, so not much can be done to improve or work around it using CSS alone.


1This is similar to why a shorthand declaration like background: #ccc will delete an image that was previously declared using background-image (examples 1 and 2).

2A notable exception to this is background-color, because for any given box there is only one background color, which is always painted in the bottommost layer beneath the image in that layer. You can set background-color to a single value at a time anywhere in a rule, and it will not affect other layers.

like image 145
BoltClock Avatar answered Nov 01 '22 18:11

BoltClock


I solved it with a :before pseudo-element.

http://codepen.io/lajlev/pen/DAyhn

.tile {
  position:relative;
  display: block;
  float: left;
  width: 100px; 
  height: 100px;
  margin: 30px;
  background: url('http://www.schaik.com/pngsuite/tbbn3p08.png') no-repeat;

  &:before {
    content: '';
    position: absolute;
    width: 100%;
    height: 100%;
    background-color: red;
    z-index: -1;
  }
}

.tile.last:before {
  background-color: green;  
}
like image 23
lajlev Avatar answered Nov 01 '22 19:11

lajlev