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:
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%);
}
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>