Ombra esterna per l'immagine PNG nei CSS


211

Ho un'immagine PNG, che ha forma libera (non quadrata).

Devo applicare l'effetto di ombra esterna a questa immagine.

L'approccio standard ...

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

... visualizza le ombre per questa immagine, come se fosse un quadrato. Quindi vedo la mia immagine e l'ombra quadrata, che non segue la forma dell'oggetto, mostrata nell'immagine.

C'è un modo per farlo correttamente?

Risposte:


261

Un po 'tardi alla festa, ma sì, è totalmente possibile creare ombre "dinamiche" dinamiche attorno a PNG mascherati alfa, usando una combinazione di filtri dropshadow (per Webkit), SVG (per Firefox) e DX per 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>

Alcuni paragoni tra la vera ombra e box-shadow e un articolo sulla tecnica che ho appena descritto .

Spero che aiuti!


1
Ancora più tardi per la festa, ma +1 per il CSS cross-plateform filter proprietà ... Anche se non credo che siano necessari tag HTML SVG, qualsiasi PNG con canale alfa farà il trucco
guillaume

2
Dudley Storey ha ragione. Senza SVG, l'ombra non appare in Firefox. @AntonAL potrebbe accettare questa risposta.
javsmo,

5
I filtri DX non funzionano più su IE ... Esistono nuove soluzioni per IE? msdn.microsoft.com/en-us/library/hh801215(v=vs.85).aspx
TB11

2
Oggigiorno Firefox supporta filter: drop-shadow(x y blur color); quindi il trucco SVG non dovrebbe più essere necessario.
Raptor007,

11
Non possiamo tutti essere d'accordo sul fatto che IE avrebbe dovuto essere gettato nella spazzatura anni fa? Edge è leggermente migliore, ma Holy Cow M $ ha intenzionalmente riportato lo sviluppo del software ai tempi bui con IE? Che abominio.
RyanNerd,

217

Sì, è possibile utilizzare filter: dropShadow(x y blur? spread? color?), sia in CSS che inline:

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
Nessun supporto IE ... :(
CF,

10
IE dovrebbe andare con i tempi: P
Bryant Jackson

6
-webkit-filter non è più necessario
Brett Donald

11
2019: cos'è IE? : P
evilReiko,

36

Se hai> 100 immagini per cui vuoi avere ombreggiature, ti suggerirei di usare il programma da riga di comando ImageMagick . Con questo, puoi applicare ombre discendenti sagomate a 100 immagini semplicemente digitando un comando! Per esempio:

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

Il comando sopra (shell) prende ogni file .png nella directory corrente, applica un'ombra discendente e salva il risultato nella directory shadow /. Se non ti piacciono le ombre discendenti generate, puoi modificare molto i parametri; iniziare guardando la documentazione per le ombre e le istruzioni generali per l' uso molti esempi interessanti di cose che possono essere fatte alle immagini.

Se in futuro cambi idea sull'aspetto delle ombre: è solo un comando per generare nuove immagini con parametri diversi :-)


22
Sebbene sia una soluzione, non risponde alla domanda!
Leo,

6
Il richiedente sta tentando di fare in modo che il browser visualizzi l'ombra, non esegua script sul server in grado di creare ombre. Si tratta di informazioni utili ma non dello stesso spazio problematico.
SG1

Un paio di note per farlo funzionare: 1. È necessario creare la directory shadow prima di eseguire questo comando (come con mkdir shadow) 2. $ideve essere citato (come in "$i") o si strozzerà se un'immagine ha uno spazio nel suo nome file: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. I file risultanti verranno nominati filename.png.png. Ecco una versione completamente funzionante: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: Aspetti positivi, sebbene si noti che questo vuole essere un esempio di ciò che può essere fatto, piuttosto che un programma pienamente funzionante! Ho corretto il doppio suffisso .png e le virgolette; la cosa della directory che sento mi farebbe solo intralciare ...
psmears,

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

Per me ha funzionato alla grande. Una cosa da notare anche se in IE hai bisogno del colore pieno (# 222222) tre personaggi non funzionano.


29

Come ha detto Dudley nella sua risposta ciò è possibile con il filtro CSS ombra per webkit, i filtri SVG per Firefox e DirectX per Internet Explorer 9-.

Un ulteriore passo è quello di incorporare l'SVG, eliminando la richiesta aggiuntiva:

.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
Funziona bene .. meglio che se definissi lo SVG all'interno dei tag HTML. (firefox)
Oki Erie Rinaldi

18

Aggiungi bordo con raggio nella tua classe se è un blocco. perché di default l'ombra si applicherà sul bordo del blocco, anche se l'immagine ha un angolo arrotondato.

border-radius: 4px;

cambia il raggio del bordo in base all'angolo dell'immagine. Spero che questo aiuto.


12

Aggiungi questo:

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

esempio:

<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

Quando l'ho pubblicato inizialmente non era possibile, quindi questa è la soluzione alternativa. Ora suggerisco semplicemente di usare altre risposte.

Non è possibile ottenere esattamente il contorno dell'immagine ma è possibile simularlo con un div dietro l'immagine al centro.

Se il mio trucco non funziona, devi tagliare l'immagine e farlo per ogni singola piccola immagine. (più immagini più precisa sarà l'ombra) ma per la maggior parte delle immagini sembra a posto con un solo img.

quello che devi fare è mettere un div avvolgente attorno al tuo img in questo modo

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

poi metti un divisore vuoto all'interno dell'involucro (questo fungerà da ombra)

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

e poi devi far apparire l'ombra dietro l'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;
}

ora posiziona imgWrap per posizionare l'img originale ... per centrare l'ombra dell'img puoi pasticciare con i primi due valori del box-shadow rendendoli negativi .... oppure puoi posizionare l'img e l'ombra div assolutamente rendendo i valori top e left di img = 0 e i valori div di shadow = metà rispettivamente di larghezza e altezza di img.

Se questo sembra orribile, taglia il tuo img e riprova.

(Se non vuoi l'ombra dietro l'img solo sul contorno, allora devi rendere il tuo img opaco e farlo agire come se fosse trasparente che non è così difficile e puoi commentare e spiegherò più avanti)


quando ho risposto che non era possibile, immagino che sia così. Il futuro è qui!
Xitcod13

2

Nel mio caso, ha dovuto funzionare su moderni browser mobili, con un'immagine PNG in diverse forme e trasparenze. Ho creato l'ombra discendente usando un duplicato dell'immagine. Ciò significa che ho due imgelementi della stessa immagine, uno sopra l'altro (usando position: absolute), e uno dietro ha le seguenti regole applicate:

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

Ciò include un filtro di luminosità per scurire l'immagine in basso e un filtro di sfocatura per proiettare l'effetto sfumato che solitamente ha l'ombra esterna. Viene quindi applicata un'opacità al 50% per ammorbidirla.

Questo può essere applicato tra browser usando moze msflag.

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



1

Questo non sarà possibile con CSS: un'immagine è un quadrato e quindi l'ombra sarebbe l'ombra di un quadrato. Il modo più semplice sarebbe usare photoshop / gimp o qualsiasi altro editor di immagini per applicare l'ombra come core draw.


Grazie per la risposta. Ma l'aggiunta di immagini nell'editor avrà problemi in futuro, quando avrò> 100 immagini e dovrei modificare un po 'le ombre. La migliore soluzione al mio problema è aggiungere ulteriore immagine d'ombra sotto ogni immagine in questione con jQuery.
AntonAL,

1

Un trucco che uso spesso quando ho solo bisogno di "un po '" di ombra (leggi: il contorno non deve essere super preciso) è posizionare un DIV con un riempimento radiale 100% da nero a 100% trasparente sotto l'immagine. Il CSS per il DIV è simile al seguente:

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

Questo creerà un 'punto' nero sbiadito circolare su un DIV 320x320. Se ridimensionate l'altezza o la larghezza del DIV, otterrete un ovale corrispondente. Molto bello creare ad esempio ombre sotto bottiglie o altre forme cilindriche.

C'è uno strumento assolutamente incredibile, super eccellente per creare gradienti CSS qui:

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

ps: fai un annuncio di cortesia quando lo usi. (E, no, non sono affiliato ad esso. Ma il clic di cortesia dovrebbe diventare un po 'un'abitudine, specialmente per lo strumento che usi spesso ... solo dicendo ... dal momento che stiamo tutti lavorando in rete ... )


L'ho visto piuttosto bello se modificato un po '
BeachInCalifornia.com

1
"Annuncio di cortesia-clic"? Seriamente, in che modo derubare gli inserzionisti è una buona cosa per la "Rete? Molti di noi sono noi stessi inserzionisti o sono pagati da loro, quindi innescare addebiti per gli inserzionisti per le pubblicità di prodotti che non comprerai mai è una cosa davvero spiacevole da fare. Se sei interessato a un annuncio, fai clic su di esso in ogni modo, ma non farlo!
alastair,

Oh, esci dalla tua altura morale, Alastair. Il mondo reale sembra un po 'diverso. "Strappare gli inserzionisti"? Veramente? LOL - Dammi una pausa, amico. Sono stato nella pubblicità e nel marketing per quasi 30 anni. Posizionare il clic di cortesia dispari non ha alcuna influenza se non quella di supportare i siti che usi GRATUITAMENTE. Se sei preoccupato per l'inflazione dei premi, ecc., Preoccupati per le tendenze sempre più monopolistiche in tutto il settore. Questo è ciò che distorce i premi pubblicitari, non lo strano clic di cortesia.
Elimina Iculous il

Sembra orribile su FF e IE
barrypicker l'

1

Non puoi farlo in modo affidabile su tutti i browser. Microsoft non supporta più i filtri DX a partire da IE10 +, quindi nessuna delle soluzioni qui funziona pienamente:

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

L'unica proprietà che funziona in modo affidabile su tutti i browser è box-shadow , e questo mette semplicemente il bordo sul tuo elemento (ad esempio un div), risultando in un bordo quadrato:

box-shadow: orizzontaleOffset verticaleOffset blurDistance spreadDistance color inset;

per esempio

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

Se ti capita di avere un'immagine "quadrata" ma con angoli arrotondati uniformi, l'ombra discendente funziona con border-radius , in modo da poter sempre emulare gli angoli arrotondati dell'immagine nel div.

Ecco la documentazione di Microsoft per box-shadow :

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


Apprezzo la risposta diretta. Nessuno degli esempi sopra funziona per me.
barrypicker

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.