MightyMeta

background-opacity-b

A CSS Proposal: Background-Opacity

| 15 Comments

In my fantasy CSS3 world, a background-opacity property would exist, and this is why I think it would be a good thing to have.


background-opacity

What Would it Do?

Currently, we have a background property, that can take a number of arguments, which can be chained together using a shorthand syntax, or declared as separate properties. Some of these include:

  • background-color (set background as a flat colour, which can contain alpha-transparent values)
  • background-image (set background as single or multiple images)
  • background-position (set position of background image/s within element)
  • background-repeat (specify tiling of background images along x and y axes)

We also have an opacity property that allows us to specify a value from 0 to 1 to control an element’s transparency.

background-opacity would take an approach similar to opacity, and allow us to specify a 0 to 1 value for background images. It would be able to work with single or multiple backgrounds.

The Current Situation

At present, if you want to make background-images semi-transparent, you have two options, either create a semi-transparent PNG in an image editor, or use the opacity property. Both approaches have significant shortcomings.

There is a ‘third way’ using RGBa, but this only works with CSS generated colours or gradients, not images.

The PNG Problem

Semi-transparent PNGs are great, but to include them requires a string value for the url declaration. This means they can’t be animated using JavaScript or CSS transitions, other than by using other properties that contain numeric values. Therefore, it is possible to animate the position of a background image (like in this set of examples by Jonathan Snook), but not it’s opacity.

The Opacity Property Problem

opacity has been around for a while, but works in a singularly frustrating way. The opacity value is applied to the entire element and any corresponding child elements. There are some workarounds for this, but they have drawbacks. The bottom line is that you can’t override opacity inheritance, and if you want to make an element’s background image transparent, but keep it’s content opaque, you’re out of luck.

Proposed Syntax

myElement {
background-image: url(image1.png), url(image2.png) url(image3.png);
background-opacity: 0.25, 0.5, 1;
}

Using a comma separated array to target multiple images within a single rule is a convention already present within the CSS3 spec that can be used with the existing background properties. You can do a similar thing to this using background-position as is demonstrated here

Why Would This Be Amazing?

Because those opacity values could then be incremented/decremented over time using JavaScript or the CSS3 transition property. This would allow for a background image to fade in and out on mouse-over or hover event, and could work in varying amounts with multiple images applied to a single element. This in turn would enable some very neat visual effects and event-based transitions and animations.

Here is a link to the W3C Background and Borders Module Level 3 specification. Unfortunately, the last call on this was back in June 2010, but it may be worth contacting the editors to see what they think.

http://www.w3.org/TR/css3-background/

If you like the sound of background-opacity, please feel free to put forward your views in the comments.

15 Comments

  1. I just got stuck on the background image opacity problem. I thought this would be allowed in CSS3 for sure but your post has confirmed that it’s not a possibility yet. Your syntax for background image opacity has my vote 100%

  2. I am completely behind you!

    I ran full tilt into the non-standard opacity inheritance problem and when I use one suggested way to fix it, I ran just as quickly, and just as hard, into the IE 6 z-index order problem.

    Many “people”, including MDC (Color and Background) recommend breaking the parent/child relationship and manually positioning the divisions to achieve the look you want. With no parent/child relationship, you can set the opacity to whatever you want on the psuedo-child division. The problem is, when you do that, you run into the IE 6 z-order bug and it can be quite difficult to get the z-order of the divisions the way you want them.

    Go sign up for Adobe BrowserLab (free until April 12, 2012) and run this page http://therealcrisp.xs4all.nl/meuk/IE-zindexbug.html through the version of IE they support. IE 8 and 9 correctly handle the z-order but IE 6 and 7 don’t.

    It seems, however, that the bug might be a bit different between IE 6 and 7 — I can get things to work with IE 7 but not IE 6 without causing other problems.

    So — using the fix, most recommened, for the CSS opacity BUG, causes other problems/

    Let’s get back to the basics:

    One of the main features in CSS is inheritance — ask any fanatical supporter of CSS. To many, inheritance, of and of itself, was the greatest feature in CSS (I’m not agreeing with that, simply stating what some of the fanatics of CSS preach)

    God wrote, when chiseling CSS rules into stone: “Children shall inherit styles from parents — unless the style is specifically set for the child.”

    Hey, I have no problem with that, even with my mere 39+ years of programming, I can understand that concept and how to apply it.

    Want a whole bunch of things to use the Arial font type? Just define it on the parent. If you want a particular child to be different, fine, define the different font on that child.

    Want a parent to a specific degree of opacity? No problem, define it with the degree opacity you want (except that, for now, you’ll actually have to set two styles — opacity:0.4 and filter:alpha(opacity=40)” because MS did it differently — wow, do they do that often?).

    Okay, set the opacity on the parent and the children inherit it. Have a child who wants to go his or her way on opacity, no problem, inheritance can be override — right?

    Well, not for opacity!

    For God also spoke “The child shall not inherit the sins of the parent but they shall be forced to inherit the parent’s opacity.”

    What idiot thought that one up? Seriously, how can you refer to the person, or persons, who broke the inheritance override rule for opacity other than to call them idiotic?

    I would like to track down person or person who decided that opacity would not be implemented, as regards inheritance overriding, like everything else in CSS, and hear their explanation for the design and then I would make them justify it — which they would never be able to do, at least in a rational world of data processing.

    At MDC (https://developer.mozilla.org/en/Useful_CSS_tips/Color_and_Background) they say that “According to the spec, opacity can be thought of conceptually as a postprocessing[sic] operation, so the selected grade of transparency is applied to all its content.”

    That sounds to me to be an attempt to justify a mistake “… can be thought of …” — either something is or it is not, we don’t have room in the programming of computers to have things which are “thought of” in some manner.

    It does not matter how you try to justify this mess, it goes against the vary basis of CSS, to wit, styles specified on a “parent” level are inherited by “children” unless overridden by specifying the style on the child.

    This was trumpeted as the absolutely best thing since sliced bread and something that was such a grand and noble idea that it would never be surpassed in its magnitude of elegance by anything, in any field, that in the future appears in the universe.

    Then we find out — well, folks, it doesn’t work for opacity.

    Now, I am relatively new at CSS and there may be other bugs (yes, I consider it a BUG) like this but a multiplicity of bugs does not make a single bug more acceptable. I’m for getting an industrial sized can of insecticide and killing the opacity bug!

    MightyMeta — (whatever your real name is — I prefer people to have people names — I usually sign up for forums and and such as BobN (with whatever additions might be necessary if BobN is already taken). So, how about we all “sign” with out names, at least our first names?

    Regardless of your label — MightyMeta, I fully support your proposal.

    AND, I want an additional change to CSS:

    style = “what-ever-style: no-inheritance;”

    This would stop ALL inheritance in its tracks — period! The style would revert to whatever value it would have had if the parent had not specified it.

    I define anyone to provide a solid, dependable argument as to why no-inheritance could not be added to CSS. Hey, if you don’t like it? Don’t use it!

    Okay, now to whom do we start sending proposals like this so that they can actually be implemented???

    Seriously, who can we start beating about the heads and shoulders until someone corrects this nonsense with opacity?

    BobN (my name is Bob Novell, I live in Missouri — if you want to find me, you can do so very easily with that information)

    • Whew! Just coming up for air there Bob…

      I’m not sure the way opacity is implemented is a ‘bug’ as such, since it isn’t mentioned in the CSS2.1 spec, or at least I can’t find any mention of it, meaning that up until recently it has been a proprietary non-standard property that browser vendors have chosen to conjure up themselves (I think). I know that the syntax for older browsers varies quite a lot. The CSS3 color module declares an opacity property, outlines how it should behave, and states that it shouldn’t be inherited. Yet the module is still a working draft and liable to change, so my guess is that browser vendors are waiting until it is better defined in the spec before implementing this particular feature properly?

      Good news is that browser vendors move much quicker than the W3C, so we can file a request with each to ask for the non-inheritance of opacity to be included.

      Still would have been nice to have a background-opacity property though, which would allow the separation of opacity for a background image and content on a single element, such as an anchor, guess we’ll have to wait until CSS4 for that…

      Oh, and if you look on the top or bottom right of the page you’ll see that my name is James Brocklehurst. MightyMeta is the name of the business I am a part of, plus my username on this site.

  3. I’ve solved using a separate DIV like a Lens:

    <div class=content
    Things that you don’t want opaque

  4. I’ve solved using a separate DIV like a Len between divs…You don’t need Inheritance in this case. Copy and try

    html code
    ———————————

    —-css—-
    .wrapper {
    background:url(“picture.jpg”);
    }
    .opaquelen {
    ” i create a len with the same dimension of father div
    left:225px;
    right:290px;
    position:fixed;
    top:130px;
    bottom:100px;
    padding:10px;
    background:green; //Len color
    overflow:hidden;
    opacity:0.8;
    filter:alpha(opacity=80);}
    .father {
    left:225px;
    right:290px;
    position:fixed;
    top:130px;
    bottom:100px;
    padding:10px;
    overflow:hidden;
    }
    .child {
    //it wont be opaque
    background:#E9D4B5;
    margin:10px;
    padding:2px;
    overflow:hidden;
    }

    • Hey djkac could you wrap your code in <code> tags and use html entities for the brackets, as your html isn’t showing…Thanks.

  5. I think that is a wonderful idea.

    I was just poking around Google to see if, maybe, that property existed in CSS3… perhaps we need a petition page. If the good folks at the W3C could see how many of us want to be able to specify the opacity of the background image as an attribute of the background image, maybe it has a chance.

    I have another change I’d like to see, having to do with colors.

    In CSS, you can already specify a color by a predefined keyword. For example, ‘silver’.

    I’d like to see that go a step further, and be allowed to define a custom color keyword that can then be used throughout the CSS.

    Then, instead of using the RGB value or predefined keyword, I can create and assign my own custom color keywords.

    With the color attribute of various CSS elements using a custom keyword, I need only redefine the custom keyword, and all the elements using that color will have the new color, automagically!

    Now that would be a great time saver!

    What do you think? Can you get behind that as a new spec for CSS4?

    –Anita

    • Sounds like a great idea Anita. That sort of thing is kind of possible using CSS preprocessors like LESS and SASS which give you the possibility of defining variables within your CSS. The W3C to date have not shown any interest in adding this kind of functionality to CSS, I think the general sense is that they want it to stay a declarative language, distinct from fully-fledged logic-based programming.

  6. A couple of hours before I saw this post I ran into the problem of images showing up with the opacity setting for the parent, and I actually tried “background-opacity” just to see if it would work. So, needless to say, you have my vote!

  7. Interesting post, I wonder, however, if there any idea when opacity elements will pass W3C validation?

  8. While I have to agree with your recommendation for background-opacity and even find myself wondering how it is we don’t have it yet, I thought I’d share my solution for this:

    http://jsfiddle.net/eVDR5/4/

    I’m using generated content and absolute positioning (with negative z-indexing) to pull it off. Since pseudo-elements share a closer connection than separate elements, it mitigates *some* of the parent/child issues BoBN mentioned (though not all). It’s a hack, I guess, but it’s worked for me when I’m in a pinch.

    Anyway, hope it helps.
    Bill

    • Hi Bill,

      your technique there certainly works, the problem being that no browsers except Firefox support CSS transitions on generated content (even though its included within the W3C spec), and JavaScript can’t do it either since pseudo elements aren’t part of the DOM.

      So if you want opacity to jump from one value to another on hover, fine, but if you want a smooth fade in/out, it won’t work under anything except FF.

      Here’s a demo to show want I mean:

      http://www.mightymeta.co.uk/demos/background-fader-4/background-fading4.html

      Didn’t use to work in WebKit at all, but more recent versions of Chrome go completely weird and seem to apply transitions targeted at generated content to the parent element!

      Time to file a bug request perhaps?

  9. This is a bit of a necro-comment, but this is the first, best discussion of this I’ve tripped over. The idea is great — but just in case you send it off to the dutiful folks at the W3C, might I offer a small suggest to modify it?

    As it stands, this doesn’t entirely take into account the shorthand of ‘background’ — which can contain both a background color and a background image.

    Your example:
    background-image: url(image1.png), url(image2.png) url(image3.png);
    background-opacity: 0.25, 0.5, 1;

    Following the seeming logic of CSS, ‘background-opacity’ would affect both the color and the image (since neither is specified). Given that, the comma-delimited series of numbers intended to apply to background images would become yet another ‘order’ to memorize, which is less than ideal.

    So, here’s my proposed small revision:

    background-opacity — a single value only, affects both background color and background image. If multiple backgrounds are used, it applies this number to all of them equally.

    background-image-opacity — single value or comma delimited set of values to coincide with multiple background images, applied in the same order as the images (first number applied to first image, etc.) If a single number is present here but multiple background images are used, the single opacity is applied to all. If more backgrounds are specified than opacity levels, the last number in the series is used for all following. (So if you have specify opacity1 and opacity2 but have 3 images, opacity2 value is applied to images 2 and 3.

    background-color-opacity — single value only, to apply an opacity to the background color

    Annnd now that we’re into having opacities for both background images and background colors, it seems to me it would offer significant design possibilities if we also included the ability to specify whether the background image or the background color was ‘on top’ (like, z-index ordering for background elements).

    background-image-z: 1;
    background-color-z: 2;

    (background-z would be pointless, as that would be the default the way it is now — color on the bottom, images on top of that)

    So, that would put the background color OVER the background images.
    on the other hand…

    background-image-z: 1,2, 4;
    background-color-z: 3;

    On the other hand, that would stack the background so the first background image was on the bottom, second background image next, then the background color, and the third background image on top of that.

    It seems to me it would offer some much shorter code for things we already do. :)

    • Hi Jean,

      thanks for your insightful comments. You are correct in pointing out that background-opacity doesn’t (but needs to) identify that it is being applied to an image rather than a colour.

      Colour opacity is already accommodated for in RGBa however, so we may be duplicating something that already exists.

      So maybe we just need to rename the property background-image-opacity?

      I agree that being able to specify stacking order is also useful, and implementing shorthand methods is desirable, but your proposal seems to break with current methods of dealing with multiple declarations (I’m thinking of gradients here, where you list the declarations in the order you want them stacked). Or does it? I’m not sure. Just feels like it might be a hard sell to the W3C bods.

      In the meantime I guess we’ll just stick with fudging it with pseudo elements and the like.

      Thanks also for your email, if you get a response from them, let me know!

Leave a Reply

Required fields are marked *.


MightyMeta, 8 St Lawrence Lane, Ashburton, Devon, UK, TQ13 7DD

Powered by WordPress | Theme Derived From "Yoko" by by Elmastudio

Scroll To Top