Sombra paralela para imagen PNG en CSS

211

Tengo una imagen PNG, que tiene forma libre (no cuadrada).

Necesito aplicar el efecto de sombra paralela a esta imagen.

El enfoque estándar ...

-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;

... muestra sombras para esta imagen, como si fuera un cuadrado. Entonces, veo mi imagen y sombra cuadrada, que no sigue la forma del objeto, que se muestra en la imagen.

¿Hay alguna manera de hacerlo correctamente?

AntonAL
fuente

Respuestas:

261

Un poco tarde para la fiesta, pero sí, es totalmente posible crear sombras de caída dinámicas "verdaderas" alrededor de PNG enmascarados alfa, utilizando una combinación de filtro de sombra (para Webkit), SVG (para Firefox) y filtros DX para IE.

.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>

Algunas comparaciones entre la verdadera sombra paralela y la sombra cuadrada y un artículo sobre la técnica que acabo de describir .

¡Espero que esto ayude!

Dudley Storey
fuente
1
Aún más tarde para la fiesta, pero +1 para la filterpropiedad CSS multiplataforma ... Sin embargo, no creo que se necesiten etiquetas SVG HTML, cualquier PNG con canal alfa hará el truco
guillaume
2
Dudley Storey tiene razón. Sin el SVG, la sombra no aparece en Firefox. @AntonAL podría aceptar esta respuesta.
javsmo
55
Los filtros DX ya no funcionan en IE ... ¿Hay alguna solución nueva para IE? msdn.microsoft.com/en-us/library/hh801215(v=vs.85).aspx
tb11
2
En estos días, Firefox admite, filter: drop-shadow(x y blur color); por lo que el truco SVG ya no debería ser necesario.
Raptor007
11
¿No podemos estar todos de acuerdo en que IE debería haber sido arrojado al montón de basura hace años? Edge es un poco mejor, pero Holy Cow M $ ¿estableciste a propósito el desarrollo de software en la Edad Media con IE? Que abominación.
RyanNerd
217

Sí, es posible usar filter: dropShadow(x y blur? spread? color?), ya sea en CSS o en línea:

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);">

Abdul
fuente
8
No es compatible con IE ... :(
CF
10
IE debería ponerse al día: P
Bryant Jackson
66
-webkit-filter ya no es necesario
Brett Donald
11
2019: ¿qué es IE? : P
evilReiko
36

Si tiene> 100 imágenes para las que desea tener sombras paralelas, sugeriría usar el programa de línea de comandos ImageMagick . Con esto, puede aplicar sombras paralelas con forma a 100 imágenes con solo escribir un comando. Por ejemplo:

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

El comando anterior (shell) toma cada archivo .png en el directorio actual, aplica una sombra paralela y guarda el resultado en el directorio shadow /. Si no le gustan las sombras generadas, puede modificar mucho los parámetros; comience mirando la documentación de sombras , y las instrucciones generales de uso tienen muchos ejemplos geniales de cosas que se pueden hacer con las imágenes.

Si cambia de opinión en el futuro sobre el aspecto de las sombras paralelas, es solo un comando para generar nuevas imágenes con diferentes parámetros :-)

psmears
fuente
22
Si bien es una solución, ¡no responde la pregunta!
leo
66
El autor de la pregunta intenta que el navegador muestre la sombra, no ejecute scripts en el servidor que puedan crear sombras. Esta es información útil pero no es el mismo espacio problemático.
SG1
Un par de notas para que esto funcione: 1. Debe crear el directorio en la sombra antes de ejecutar este comando (como con mkdir shadow) 2. $idebe citarse (como en "$i") o se ahogará si una imagen tiene un espacio en su nombre de archivo: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. Los archivos resultantes serán nombrados filename.png.png. Aquí hay una versión completamente de trabajo: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
@AndrewMacheret: Buenos puntos, aunque tenga en cuenta que esto pretende ser una ilustración de lo que se puede hacer, ¡en lugar de un programa completamente funcional! He arreglado el sufijo .png doble y las comillas; lo del directorio que creo que se interpondría ...
psmears
35
img {
  -webkit-filter: drop-shadow(5px 5px 5px #222222);
  filter: drop-shadow(5px 5px 5px #222222);
}

Eso funcionó muy bien para mí. Una cosa a tener en cuenta es que en IE necesita el color completo (# 222222) tres caracteres no funcionan.

Jaclyn U
fuente
29

Como Dudley mencionó en su respuesta esto es posible con el filtro CSS de sombra paralela para webkit, SVG para Firefox y filtros DirectX para Internet Explorer 9-.

Un paso más es alinear el SVG, eliminando la solicitud adicional:

.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')";
}
Karl Horky
fuente
1
Funciona bien ... mejor que si defino el SVG dentro de las etiquetas HTML. (Firefox)
Oki Erie Rinaldi
18

Agregue borde con radio en su clase si es un bloque. porque, por defecto, la sombra se aplicará en el borde del bloque, incluso si su imagen tiene una esquina redondeada.

border-radius: 4px;

cambie su radio de borde de acuerdo con su esquina de imagen. Espero que esto ayude.

anupal
fuente
12

Solo agrega esto:

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

ejemplo:

<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); 
}
Mahmoud Zalt
fuente
6

Aquí está el fragmento de código de animación de brillo estacionario listo para esto:

http://codepen.io/widhi_allan/pen/ltaCq

-webkit-filter: drop-shadow(0px 0px 0px rgba(255,255,255,0.80));
Dmitry Kaigorodov
fuente
que no sea webkit?
mmm
3

Cuando publiqué esto originalmente no era posible, así que esta es la solución. Ahora simplemente sugiero usar otras respuestas.

No hay forma de obtener el contorno de la imagen exactamente, pero puede simularlo con un div detrás de la imagen en el centro.

Si mi truco no funciona, entonces tienes que cortar la imagen y hacerlo para cada una de las pequeñas imágenes. (cuantas más imágenes, más precisa se verá la sombra) pero para la mayoría de las imágenes se ve bien con solo una imagen.

lo que debes hacer es poner un div de envoltura alrededor de tu img así

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

luego pones un divisor vacío dentro de la envoltura (esto servirá como sombra)

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

y luego debes hacer que la sombra aparezca detrás del img con CSS:

#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;
}

ahora coloque el imgWrap para colocar el img original ... para centrar la sombra del img, puede meterse con los dos primeros valores de la sombra de la caja haciéndolos negativos ... o puede posicionar el img y los divs de sombra absolutamente haciendo img valores superior e izquierdo = 0 y los valores div de sombra = la mitad del ancho y la altura img respectivamente.

Si esto parece horrible, corta tu imagen e inténtalo de nuevo.

(Si no desea que la sombra detrás de la img solo esté en el contorno, debe hacer que su img sea opaca y hacer que actúe como si fuera transparente, lo que no es tan difícil y puede comentar y lo explicaré más adelante)

Xitcod13
fuente
cuando respondí que no era posible, supongo que ahora lo es. ¡El futuro está aquí!
Xitcod13
2

En mi caso, tenía que funcionar en navegadores móviles modernos, con una imagen PNG en diferentes formas y transparencias. Creé sombra paralela usando un duplicado de la imagen. Eso significa que tengo dos imgelementos de la misma imagen, uno encima del otro (usando position: absolute), y el que está detrás tiene aplicadas las siguientes reglas:

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

Esto incluye un filtro de brillo para oscurecer la imagen inferior y un filtro de desenfoque para proyectar el efecto borroso que generalmente tiene la sombra paralela. Luego se aplica una opacidad al 50% para suavizarla.

Esto se puede aplicar a través del navegador usando mozy msflags.

Ejemplo: https://jsfiddle.net/5mLssm7o/

hago
fuente
1

Esto no será posible con css: una imagen es un cuadrado, por lo que la sombra sería la sombra de un cuadrado. La forma más fácil sería usar photoshop / gimp o cualquier otro editor de imágenes para aplicar la sombra como un dibujo central.

oezi
fuente
Gracias por responder. Pero agregar imágenes en el editor tendrá problemas en el futuro, cuando tenga> 100 imágenes y deba ajustar un poco las sombras. La mejor solución de mi problema es agregar una imagen de sombra adicional debajo de cada imagen en cuestión con jQuery.
AntonAL
1

Un truco que uso a menudo cuando solo necesito "un poco" de sombra (léase: el contorno no debe ser súper preciso) es colocar un DIV con un relleno radial 100% negro a 100% transparente debajo de la imagen. El CSS para el DIV se parece a:

.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 */
  }

Esto creará un 'punto' circular negro desvanecido en un DIV de 320x320. Si escala la altura o el ancho del DIV, obtiene un óvalo correspondiente. Muy agradable para crear, por ejemplo, sombras debajo de botellas u otras formas cilíndricas.

Aquí hay una herramienta increíblemente increíble y súper excelente para crear gradientes CSS:

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

ps: haz un clic de cortesía cuando lo uses. (Y, no, no estoy afiliado a él. Pero hacer clic de cortesía debería convertirse en un hábito, especialmente para la herramienta que usas a menudo ... solo digo ... ya que todos estamos trabajando en la red ... )

Ridículo
fuente
Pude ver que esto se veía bastante bien cuando se modificó un poco
BeachInCalifornia.com
1
"Cortesía ad-click"? En serio, ¿de qué manera estafar a los anunciantes es algo bueno para la red? Muchos de nosotros somos anunciantes, o nos pagan por ellos, por lo que desencadenar cargos para los anunciantes por anuncios de productos que nunca va a comprar es algo realmente desagradable. Si está interesado en un anuncio, haga clic en él por todos los medios, ¡pero no haga esto!
alastair
Oh, sal de tu terreno moral, Alastair. El mundo real se ve un poco diferente. "Estafando a los anunciantes"? De Verdad? LOL - Dame un descanso, hombre. He estado en publicidad y marketing durante casi 30 años. Para colocar la extraña cortesía, el clic no tiene influencia más que apoyar los sitios que usa GRATIS. Si le preocupa la inflación de premios, etc., preocúpese por las tendencias cada vez más monopolizadoras en toda la industria. Eso es lo que distorsiona los premios publicitarios, no el extraño clic de cortesía.
Rid Iculous
Esto se ve horrible en FF e IE
barrypicker
1

No puede hacer esto de manera confiable en todos los navegadores. Microsoft ya no admite filtros DX a partir de IE10 +, por lo que ninguna de las soluciones aquí funciona completamente:

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

La única propiedad que funciona de manera confiable en todos los navegadores es box-shadow, y esto solo pone el borde en su elemento (por ejemplo, un div), lo que resulta en un borde cuadrado:

cuadro-sombra: horizontal Offset vertical Offset blurDistance spreadDistance color inset;

p.ej

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

Si tiene una imagen que es 'cuadrada' pero con esquinas redondeadas uniformes, la sombra paralela funciona border-radius, por lo que siempre podría emular las esquinas redondeadas de su imagen en su div.

Aquí está la documentación de Microsoft para box-shadow:

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

Chris Halcrow
fuente
Agradezco la respuesta directa. Ninguno de los ejemplos anteriores funciona para mí.
barrypicker el