Transparent Background Image with a Gradient

Today I was designing a transparent PNG background that would only sit in the top left of a div, and the rest of the div would maintain a gradient background for all transparent areas of the PNG, and the rest of the div itself.

It might be better to explain through the code I thought might work:

#mydiv .isawesome { 
    /* Basic color for old browsers, and a small image that sits in the top left corner of the div */
    background: #B1B8BD url('../images/sidebar_angle.png') 0 0 no-repeat;

    /* The gradient I would like to have applied to the whole div, behind the PNG mentioned above */
    background: -moz-linear-gradient(top, #ADB2B6 0%, #ABAEB3 100%);
    background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ADB2B6), color-stop(100%,#ABAEB3));
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ADB2B6', endColorstr='#ABAEB3',GradientType=0 );
}

What I've been finding is that most browsers pick one or the other - most choosing the gradient since its further down the CSS file.

I know some of the guys around here will say "just apply the gradient to the PNG you're making" - but thats not ideal because the div will maintain a dynamic height - sometimes being very short, sometimes being very tall. I know this gradient isn't essential but I thought it might be worth asking y'all what you thought.

Is it possible to have a background image, while keeping the rest of the background as a gradient?


Keep in mind that a CSS gradient is actually an image value, not a color value as some might expect. Therefore, it corresponds to background-image specifically, and not background-color , or the entire background shorthand.

Essentially, what you're really trying to do is layering two background images: a bitmap image over a gradient. To do this, you specify both of them in the same declaration, separating them using a comma. Specify the image first, followed by the gradient. If you specify a background color, that color will always be painted underneath the bottom-most image, which means a gradient will cover it just fine, and it will work even in the case of a fallback.

Because you're including vendor prefixes, you will need to do this once for every prefix, once for prefixless, and once for fallback (without the gradient). To avoid having to repeat the other values, use the longhand properties1 instead of the background shorthand:

#mydiv .isawesome { 
    background-color: #B1B8BD;
    background-position: 0 0;
    background-repeat: no-repeat;

    /* Fallback */
    background-image: url('../images/sidebar_angle.png');

    /* CSS gradients */
    background-image: url('../images/sidebar_angle.png'), 
                      -moz-linear-gradient(top, #ADB2B6 0%, #ABAEB3 100%);
    background-image: url('../images/sidebar_angle.png'), 
                      -webkit-gradient(linear, left top, left bottom, color-stop(0%, #ADB2B6), color-stop(100%, #ABAEB3));
    background-image: url('../images/sidebar_angle.png'), 
                      linear-gradient(to bottom, #ADB2B6, #ABAEB3);

    /* IE */
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ADB2B6', endColorstr='#ABAEB3', GradientType=0);
}

Unfortunately this doesn't work correctly in IE as it uses filter for the gradient, which it always paints over the background.

To work around IE's issue you can place the filter and the background image in separate elements. That would obviate the power of CSS3 multiple backgrounds, though, since you can just do layering for all browsers, but that's a trade-off you'll have to make. If you don't need to support versions of IE that don't implement standardized CSS gradients, you have nothing to worry about.


1 Technically, the background-position and background-repeat declarations apply to both layers here because the gaps are filled in by repeating the values instead of clamped, but since background-position is its initial value and background-repeat doesn't matter for a gradient covering the entire element, it doesn't matter too much. The details of how layered background declarations are handled can be found here.


The order of the image and gradient is very KEY here, i want to make that clear. The gradient/image combo works best like this...

background: -webkit-gradient(linear, top, rgba(0,0,0,0.5), rgba(200,20,200,0.5)), url('../images/plus.png');

background-image will also work...

background-image: -webkit-gradient(linear, top, rgba(0,0,0,0.5), rgba(200,20,200,0.5)), url('../images/plus.png');

the gradient needs to come first... to go on top. The absolute key here though is that the gradient uses at least 1 RGBA color... the color(s) need to be transparent to let the image come through. ( rgba(20,20,20,***0.5***) ). putting the gradient first in you css places the gradient on top of the image, so the lower the alpha setting on you RGBAs the more you see the image.

Now on the other hand if you use the reverse order the PNG needs to have transparent properties, just like the gradient, to let the gradient shine through. The image goes on top so your PNG needs to be saved as a 24 bit in photoshop with alpha areas... or a 32 bit in fireworks with alpha areas (or a gif i guess... barf), so you can see the gradient underneath. In this case the gradient can use HEX RGB or RGBA.

The key difference here is the look. The image will be much more vibrant when on top. When underneath you have the ability to tune the RGBA values in the browser to get the desired effect... instead of editing and saving back and forth from your image editing software.

Hope this helps, excuse my over simplification.


You can use Transparency and gradients. Gradients support transparency. You can use this, for example, when stacking multiple backgrounds, to create fading effects on background images.

background: linear-gradient(to right, rgba(255,255,255,0) 20%,
              rgba(255,255,255,1)), url(http://foo.com/image.jpg);

在这里输入图像描述

链接地址: http://www.djcxy.com/p/89420.html

上一篇: 如何在Android中创建平铺渐变背景

下一篇: 带有渐变的透明背景图像