在CSS中为PNG图像添加阴影


210

我有一个PNG图片,该图片具有自由格式(非正方形)。

我需要对此图像应用阴影效果。

标准方法...

-o-box-shadow:      12px 12px 29px #555;
-icab-box-shadow:   12px 12px 29px #555;
-khtml-box-shadow:  12px 12px 29px #555;
-moz-box-shadow:    12px 12px 29px #555;
-webkit-box-shadow: 12px 12px 29px #555;
box-shadow:         12px 12px 29px #555;

...显示该图像的阴影,就像一个正方形。因此,我看到了我的图像和方形阴影,它不遵循对象的形式显示在图像中。

有什么办法可以正确地做到这一点吗?

Answers:


261

聚会晚了一点,但是是的,使用dropshadow-filter(对于Webkit),SVG(对于Firefox)和DX IE过滤器的组合,完全有可能围绕alpha遮罩的PNG创建“真实的”动态阴影。

.shadowed {
    -webkit-filter: drop-shadow(12px 12px 25px rgba(0,0,0,0.5));
    filter: url(#drop-shadow);
    -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
    filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
}
<!-- HTML elements here -->

<svg height="0" xmlns="http://www.w3.org/2000/svg">
    <filter id="drop-shadow">
        <feGaussianBlur in="SourceAlpha" stdDeviation="4"/>
        <feOffset dx="12" dy="12" result="offsetblur"/>
        <feFlood flood-color="rgba(0,0,0,0.5)"/>
        <feComposite in2="offsetblur" operator="in"/>
        <feMerge>
            <feMergeNode/>
            <feMergeNode in="SourceGraphic"/>
        </feMerge>
    </filter>
</svg>

真正的阴影和盒子阴影之间的一些比较,以及有关我刚刚描述的技术的文章

我希望这有帮助!


1
参加聚会的时间更晚了,但是跨平台CSS filter属性的值为+1 ...虽然,我认为不需要HTML SVG标签,但是任何具有alpha通道的PNG都可以解决问题
guillaume

2
Dudley Storey是正确的。如果没有SVG,则Firefox中不会出现阴影。@AntonAL可以接受此答案。
javsmo

5
DX过滤器不再在IE上运行... IE是否有任何新的解决方案?msdn.microsoft.com/zh-CN/library/hh801215(v=vs.85).aspx
tb11 2015年

2
如今,Firefox支持, filter: drop-shadow(x y blur color);因此不再需要SVG技巧。
Raptor007

11
难道我们不都同意IE应该在多年前被扔进垃圾堆吗?Edge稍好一些,但是您有没有用M $来使软件开发回到IE的黑暗时代?真是可恶
RyanNerd

216

是的,filter: dropShadow(x y blur? spread? color?)可以在CSS或内联中使用:

img {
  width: 150px;
  -webkit-filter: drop-shadow(5px 5px 5px #222);
  filter: drop-shadow(5px 5px 5px #222);
}
<img src="https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-com-logo-png-transparent.png">

<img src="https://cdn.freebiesupply.com/logos/large/2x/stackoverflow-com-logo-png-transparent.png" style="-webkit-filter: drop-shadow(5px 5px 5px #222); filter: drop-shadow(5px 5px 5px #222);">


8
没有IE支持... :(
CF

10
IE应该与时俱进:P
科比·杰克逊

6
-webkit-filter不再需要
Brett Donald

11
2019:什么是IE?:P
evilReiko

36

如果您要为阴影添加100张以上的图像,建议使用命令行程序ImageMagick。这样,您只需键入一个命令就可以将定型的阴影应用于100张图像!例如:

for i in "*.png"; do convert $i '(' +clone -background black -shadow 80x3+3+3 ')' +swap -background none -layers merge +repage "shadow/$i"; done

上面的(shell)命令获取当前目录中的每个.png文件,应用下拉阴影,并将结果保存在shadow /目录中。如果您不喜欢生成的阴影,则可以对参数进行大量调整;例如,首先查看有关阴影文档,常规用法说明中有许多很酷的示例,可以对图像进行处理。

如果您以后对投影效果的外观改变主意-这只是生成具有不同参数的新图像的一个命令:-)


22
虽然这是一个解决方案,但不能回答问题!
leo 2012年

6
询问者正在尝试让浏览器渲染阴影,而不是在可以创建阴影的服务器上执行脚本。这是有用的信息,但问题空间不同。
SG1 2013年

为了使它起作用,需要注意以下几点:1.您需要在运行此命令之前创建阴影目录(例如使用mkdir shadow)2. $i应该用引号引起来(如"$i"),否则如果图像的文件名中有空格,它将使内容阻塞:for i in *.png; do convert "$i" '(' +clone -background black -shadow 80x3+3+3 ')' +swap -background none -layers merge +repage shadow/"$i".png; done
Andrew Macheret

2
3.结果文件将命名为filename.png.png。这是一个完全正常的版本:for i in *.png; do convert "$i" '(' +clone -background black -shadow 80x3+3+3 ')' +swap -background none -layers merge +repage shadow/"$i"; done
Andrew Macheret,2015年

@AndrewMacheret:好点-尽管请注意,这只是为了说明可以做什么,而不是一个完整的程序!我已经修复了双.png后缀和引号;我觉得目录的东西只会
挡住

34
img {
  -webkit-filter: drop-shadow(5px 5px 5px #222222);
  filter: drop-shadow(5px 5px 5px #222222);
}

那对我来说很棒。在IE中需要注意的一件事是您需要全色(#222222)三个字符不起作用。


29

正如Dudley在他的回答中提到的那样,这可以通过webkit的阴影CSS过滤器,Firefox的SVG和Internet Explorer 9-的DirectX过滤器来实现。

进一步的步骤是内联SVG,从而消除了额外的请求:

.shadowed {
    -webkit-filter: drop-shadow(12px 12px 25px rgba(0,0,0,0.5));
    filter: url("data:image/svg+xml;utf8,<svg height='0' xmlns='http://www.w3.org/2000/svg'><filter id='drop-shadow'><feGaussianBlur in='SourceAlpha' stdDeviation='4'/><feOffset dx='12' dy='12' result='offsetblur'/><feFlood flood-color='rgba(0,0,0,0.5)'/><feComposite in2='offsetblur' operator='in'/><feMerge><feMergeNode/><feMergeNode in='SourceGraphic'/></feMerge></filter></svg>#drop-shadow");
    -ms-filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
    filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";
}

1
它比我在HTML标记中定义SVG更好。(firefox)
Oki Erie Rinaldi'1

18

如果您的课堂是一个障碍,请在您的课堂中添加带有半径的边框。因为默认情况下,即使图像具有圆角,阴影也会应用于块边界。

border-radius: 4px;

根据您的图像角更改其边界半径。希望能有所帮助。


12

只需添加:

-webkit-filter: drop-shadow(5px 5px 5px #fff);
 filter: drop-shadow(5px 5px 5px #fff); 

例:

<img class="home-tab-item-img" src="img/search.png"> 

.home-tab-item-img{
    -webkit-filter: drop-shadow(5px 5px 5px #fff);
     filter: drop-shadow(5px 5px 5px #fff); 
}


3

当我最初发布此消息时,这是不可能的,所以这是解决方法。现在,我只是建议使用其他答案。

无法准确获取图像的轮廓,但是您可以在图像中心后面的div处伪造它。

如果我的把戏不起作用,那么您必须裁剪图像并为每张小图像都做一下。(越多的图像,阴影看起来越准确),但对于大多数图像来说,仅需一张img就可以了。

您需要做的是将div环绕在img周围,如下所示

<div id="imgWrap">
    <img id="img" scr="imgLocation">
</div>

然后在包装内放入一个空的分隔线(将用作阴影)

<div id="imgWrap">
    <div id="shadow"> </div>
    <img id="img" scr="imgLocation">
</div>

然后必须使用CSS使阴影出现在img的后面:

#img {
    z-index: 1;
}

#shadow {
    z-index: 0; /*make this value negative if doesnt work*/
    box-shadow: 0 -130px 180px 150px rgba(255, 255, 0, 0.6);
    width: 0;
    height: 0;
}

现在放置imgWrap来放置原始img ...以使img的阴影居中,您可以将box-shadow的前两个值弄乱,使其变为负数...。或者您也可以将img和shadow divs放到绝对位置使img的上和左值= 0,阴影div值=分别为img宽度和高度的一半。

如果这看起来很可怕,请切断img,然后重试。

(如果您不希望img后面的阴影仅出现在轮廓上,则需要使img不透明,并使它看起来像透明的一样,这并不难,您可以发表评论,稍后再解释)


当我回答这不可能时,我猜现在是。未来就在这里!
Xitcod13 '18

2

以我为例,它必须在具有不同形状和透明度的PNG图像的现代移动浏览器上工作。我使用图像的副本创建了阴影。这意味着我有img同一张图片的两个元素,一个元素位于另一个图像上方(使用position: absolute),而后面的一个元素对其应用了以下规则:

.image-shadow {
  filter: blur(10px) brightness(-100);
  -webkit-filter: blur(10px) brightness(-100);
  opacity: .5;
}

这包括为了使底部图像变暗的亮度滤镜和为了使阴影效果通常具有阴影的模糊滤镜。然后应用50%的不透明度以使其柔化。

可以使用mozms标志在跨浏览器中应用此功能。

示例:https//jsfiddle.net/5mLssm7o/



1

CSS不可能做到这一点-图像是正方形,因此阴影将是正方形的阴影。最简单的方法是使用photoshop / gimp或任何其他图像编辑器来应用像核心绘制一样的阴影。


谢谢您的回复。但是,将来在编辑器中添加图像时会出现问题,当我将具有> 100张图像并应稍微调整阴影时。我问题的最佳解决方案-使用jQuery在每个有问题的图像下方添加其他阴影图像。
AntonAL 2010年

1

当我只需要“一点”阴影(阅读:轮廓不能太精确)时,我经常使用的一个技巧是在图像下方放置一个径向填充为100%黑色至100%透明的DIV。DIV的CSS如下所示:

.shadow320x320{    
        background: -moz-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%, rgba(0,0,0,0.58) 1%, rgba(0,0,0,0) 43%, rgba(0,0,0,0) 100%); /* FF3.6+ */
        background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%,rgba(0,0,0,0.58)), color-stop(1%,rgba(0,0,0,0.58)), color-stop(43%,rgba(0,0,0,0)), color-stop(100%,rgba(0,0,0,0))); /* Chrome,Safari4+ */
        background: -webkit-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* Chrome10+,Safari5.1+ */
        background: -o-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* Opera 12+ */
        background: -ms-radial-gradient(center, ellipse cover, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* IE10+ */
        background: radial-gradient(ellipse at center, rgba(0,0,0,0.58) 0%,rgba(0,0,0,0.58) 1%,rgba(0,0,0,0) 43%,rgba(0,0,0,0) 100%); /* W3C */
        filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#94000000', endColorstr='#00000000',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
  }

这将在320x320 DIV上创建一个圆形的黑色淡出“点”。如果缩放DIV的高度或宽度,则会得到一个相应的椭圆形。非常适合在瓶子或其他圆柱状形状下创建阴影。

这里有一个绝对令人难以置信,非常出色的工具来创建CSS渐变:

http://www.colorzilla.com/gradient-editor/

ps:使用时请进行有礼貌的广告点击。(而且,不,我不隶属于它。但是礼貌的点击应该成为一种习惯,尤其是对于您经常使用的工具...只是说出来...因为我们都在网络上工作... )


经过一点修改,我可以看到它看起来很不错
BeachInCalifornia.com 2014年

1
“礼貌的广告点击”?认真地说,剥夺广告客户对网络来说是一件好事吗?我们中的许多人本人就是广告商,或者是由他们付费的,因此触发广告商对您永远不会购买的产品进行广告收费是一件非常不愉快的事情。如果您对广告感兴趣,请务必点击它,但不要这样做!
alastair 2014年

哦,走出道德顶峰,Alastair。现实世界看起来有些不同。“剥夺广告客户”?真?大声笑-休息一下,伙计。我从事广告和市场营销已有30年了。除了支持免费使用的网站外,进行奇怪的礼节性点击没有任何影响。如果您担心奖品等的膨胀,请担心整个行业中日益垄断的趋势。就是扭曲的广告奖赏,而不是奇怪的礼貌点击。
Rid Iculous

这在FF和IE上看起来很可怕
barrypicker

1

您不能在所有浏览器上都可靠地做到这一点。从IE10 +开始,Microsoft不再支持DX过滤器,因此此处没有任何解决方案可以完全正常工作:

https://msdn.microsoft.com/zh-CN/library/hh801215(v=vs.85).aspx

可以在所有浏览器上可靠运行的唯一属性是box-shadow,这只会在您的元素(例如div)上加上边框,从而形成正方形边框:

box-shadow:horizo​​ntalOffset verticalOffset blurDistance spreadDistance颜色插入;

例如

box-shadow: -2px 6px 12px 6px #CCCED0;

如果您碰巧的图像是“正方形”但具有均匀的圆角,则阴影与配合使用border-radius,因此您始终可以在div中模拟图像的圆角。

这是Microsoft的文档box-shadow

https://msdn.microsoft.com/zh-CN/library/gg589484(v=vs.85).aspx


我感谢简单的答案。上面的示例都不适合我。
barrypicker

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.