Multiple CSS backgrounds, colour over image, ignored
Asked Answered
G

6

7

What's wrong with this multiple background CSS line. Firefox 4 ignores it (as it does when there's a syntax error).

background: rgba(255,0,0,0.2), url("static/menubg.jpg");
Greathouse answered 1/5, 2011 at 21:40 Comment(2)
Do you have any other background related tags in your css?Eri
@Arjan: I had a background-size to scale the image, but I removed it and tested that before posting.Greathouse
M
8

The syntax for background in CSS3 Backgrounds is [ <bg-layer> , ]* <final-bg-layer>, which means zero or more <bg-layer>s and then a single <final-bg-layer>, separated from each other by commas. See http://www.w3.org/TR/css3-background/#the-background

A <final-bg-layer> is defined as:

<final-bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || 
                   <repeat-style> || <attachment> || <box>{1,2} ||
                   <'background-color'>

whereas a <bg-layer> is:

 <bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? ||
              <repeat-style> || <attachment> || <box>{1,2}

(both definitions at http://www.w3.org/TR/css3-background/#ltbg-layergt ).

Or in simple terms, only the lowest background layer can include a background color. So yes, your CSS is in fact a syntax error.

Oh, and looks like https://developer.mozilla.org/en/css/multiple_backgrounds had some errors in it. I've fixed them.

Messy answered 1/5, 2011 at 23:59 Comment(8)
Have a +1 for a great reference; I hadn't thought to look for an authoritative source for my answer.Concerto
The "live demonstration" on that MDC page doesn't seem to be working since your changes.Stanislaus
Indeed. And for extra fun, none of the things I changed should have affected that, and reverting to the working revision doesn't work: the wiki is claiming the text is now the same as the working revision, but the actual markup it produces is clearly different. I mailed the wiki maintainer. I hate wikis. :(Messy
Hmm, so if I want to tint a background image a need to lay a repeated 1x1 transparent pixel image over it? What a bummer, but oh well.Greathouse
Yeah, there's no really good support for that in CSS3 Backgrounds. You could use a data: URI for the 1x1 thing...Messy
How about defining a uniform translucent linear gradient as one of your background images?Duplessis
Yup using a gradient works. You need to put the gradient BEFORE the image though in the multiple-background syntax.Allisan
F*** W3C! I need to make a nice transition on background image load (where bg-color of the first layer would become transparent) and they ruined it. I don't want to mess my code with hard-to-do and ugly javascript walkarounds! Sometimes I think that guys from W3C never tried to make a web.Saval
A
10

The solutions is using:

{-moz-linear-gradient(top, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.5) 100%), url(bg.png) repeat 0 0;}  

instead of:

rgba(0, 0, 0, 0.5)
Aliquot answered 10/11, 2011 at 15:23 Comment(0)
M
8

The syntax for background in CSS3 Backgrounds is [ <bg-layer> , ]* <final-bg-layer>, which means zero or more <bg-layer>s and then a single <final-bg-layer>, separated from each other by commas. See http://www.w3.org/TR/css3-background/#the-background

A <final-bg-layer> is defined as:

<final-bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? || 
                   <repeat-style> || <attachment> || <box>{1,2} ||
                   <'background-color'>

whereas a <bg-layer> is:

 <bg-layer> = <bg-image> || <bg-position> [ / <bg-size> ]? ||
              <repeat-style> || <attachment> || <box>{1,2}

(both definitions at http://www.w3.org/TR/css3-background/#ltbg-layergt ).

Or in simple terms, only the lowest background layer can include a background color. So yes, your CSS is in fact a syntax error.

Oh, and looks like https://developer.mozilla.org/en/css/multiple_backgrounds had some errors in it. I've fixed them.

Messy answered 1/5, 2011 at 23:59 Comment(8)
Have a +1 for a great reference; I hadn't thought to look for an authoritative source for my answer.Concerto
The "live demonstration" on that MDC page doesn't seem to be working since your changes.Stanislaus
Indeed. And for extra fun, none of the things I changed should have affected that, and reverting to the working revision doesn't work: the wiki is claiming the text is now the same as the working revision, but the actual markup it produces is clearly different. I mailed the wiki maintainer. I hate wikis. :(Messy
Hmm, so if I want to tint a background image a need to lay a repeated 1x1 transparent pixel image over it? What a bummer, but oh well.Greathouse
Yeah, there's no really good support for that in CSS3 Backgrounds. You could use a data: URI for the 1x1 thing...Messy
How about defining a uniform translucent linear gradient as one of your background images?Duplessis
Yup using a gradient works. You need to put the gradient BEFORE the image though in the multiple-background syntax.Allisan
F*** W3C! I need to make a nice transition on background image load (where bg-color of the first layer would become transparent) and they ruined it. I don't want to mess my code with hard-to-do and ugly javascript walkarounds! Sometimes I think that guys from W3C never tried to make a web.Saval
R
3

You should note that because gradients are treated as images it is acceptable and works to put in a gradient that has the same top and bottom colour.

Rizzi answered 20/7, 2011 at 16:37 Comment(0)
C
2

It should be background: rgba(255,0,0,0.2) url("static/menubg.jpg"); without the ,

Catechol answered 1/5, 2011 at 21:42 Comment(1)
That's when you use a background image with a colour as fallback. I'm attempting multiple backgrounds: developer.mozilla.org/en/css/multiple_backgroundsGreathouse
C
1

Oddly enough it seems to come down to the order of the parameters; the background-image then background-color:

background: url('http://davidrhysthomas.co.uk/linked/astrid_avatar.png') no-repeat 50% 50%, rgba(255,180,0,0.8);

Works (JS Fiddle demo), while background-color then background-image:

background: rgba(255,180,0,0.8), url('http://davidrhysthomas.co.uk/linked/astrid_avatar.png') no-repeat 50% 50%;

Does not (JS Fiddle).

The above tested on Chromium 11 and Firefox 4, both on Ubuntu 11.04.


Edited to note that this does, indeed, come down to the order; as definitively answered in @Boris' answer.
Concerto answered 1/5, 2011 at 21:59 Comment(0)
E
0

Going off of Oscar's nice solution (thanks!), here is how I implemented it using SASS/Compass to automate browser prefixing

@include background( linear-gradient( color-stops(rgba(255, 66, 78, 0.25), rgba(255, 66, 78, 0.25)) ), image-url('/img/cardboard_flat.png') );

This supports Webkit, Firefox, but not IE9 (because of the gradient). Then I remembered the awesome compass rgbapng Ruby gem for generating PNGs: https://github.com/aaronrussell/compass-rgbapng

@include background( png_base64( rgba(255, 66, 78, 0.25) ), image-url('/img/cardboard_flat.png') );

Now, this supports IE9+ and the rest of the browsers that support multiple backgrounds.

If you still need IE8 support, you could either use a multi-background polyfill, or style an ::after pseudo element and absolutely position it, with a z-index of -1:

html {
  height: 100%;
}

body {
  background: url('/img/cardboard_flat.png');
  position: relative;
  padding: 1px 0;
  min-height: 100%;

  &:after {
    content: "";
    position: absolute;
    background: png_base64( rgba(255, 66, 78, 0.25) );
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    z-index: -1;
  }
}
Elizaelizabet answered 27/8, 2013 at 17:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.