Search code examples
javascripthtmlcssopacity

How to dim an image keeping transparency untouched with CSS or JS?


Normal approach to dimming an image suggested everywhere is to change it's opacity attribute and display something dark under it. However, my image has transparency and is on white background. So I want to keep the background under transparent parts of image white, only making darker the pixels that have color. Is this possible to do in CSS (preferably) or JS?

Example image:

enter image description here


Solution

  • There is a relatively new CSS property filter which might achieve what you are after.

    The brightness option seems to be what you are after.

    EDIT - Added interim support for FF via URL

    JSFiddle Demo (with brightness and contrast options)

    CSS

    img {
    width:250px;
    }
    #one:hover {
        -webkit-filter:brightness(50%);
        -moz-filter:brightness(50%);
        filter: url(#brightness); /* required for FF */
        filter:brightness(50%);
    }
    #two:hover {
        -webkit-filter:contrast(50%);    
        -moz-filter:contrast(50%);
         filter: url(#contrast);
        filter:contrast(50%);
    }
    

    MDN on Filter

    Support is non-IE see CanIUse.com

    FF support (at the time of writing) requires definition of an SVG filter

    Brightness @ 50%

    <svg height="0" xmlns="http://www.w3.org/2000/svg">
    
        <filter id="brightness">
            <feComponentTransfer>
                <feFuncR type="linear" slope=".5" />
                <feFuncG type="linear" slope=".5" />
                <feFuncB type="linear" slope=".5" />
            </feComponentTransfer>
        </filter>
    
    </svg>
    

    Contrast @ 200%

    <svg height="0" xmlns="http://www.w3.org/2000/svg">
        <filter id="contrast">
            <feComponentTransfer>
                <feFuncR type="linear" slope="2" intercept="-(0.5 * 2) + 0.5" />
                <feFuncG type="linear" slope="2" intercept="-(0.5 * 2) + 0.5" />
                <feFuncB type="linear" slope="2" intercept="-(0.5 * 2) + 0.5" />
            </feComponentTransfer>
        </filter>
    </svg>