Drop shadow untuk gambar PNG di CSS

211

Saya memiliki gambar PNG, yang memiliki bentuk bebas (non persegi).

Saya perlu menerapkan efek drop-shadow pada gambar ini.

Pendekatan standar ...

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

... menampilkan bayangan untuk gambar ini, seperti persegi. Jadi, saya melihat gambar dan bayangan kuadrat, yang tidak mengikuti bentuk objek, ditampilkan dalam gambar.

Apakah ada cara untuk melakukannya dengan benar?

Antonal
sumber

Jawaban:

261

Sedikit terlambat ke pesta, tapi ya, sangat mungkin untuk membuat bayangan drop dinamis "benar" di sekitar PNG bertopeng alfa, menggunakan kombinasi filter dropshadow (untuk Webkit), SVG (untuk Firefox), dan filter DX untuk 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>

Beberapa perbandingan antara true-shadow dan box-shadow dan artikel tentang teknik yang baru saja saya jelaskan .

Saya harap ini membantu!

Dudley Storey
sumber
1
Bahkan lebih terlambat ke pesta, tapi +1 untuk filterproperti CSS cross-plateform ... Meskipun, saya tidak berpikir tag SVG HTML diperlukan, PNG dengan saluran alfa akan melakukan trik
guillaume
2
Dudley Storey benar. Tanpa SVG, bayangan tidak akan muncul di Firefox. @AntonAL dapat menerima jawaban ini.
javsmo
5
Filter DX tidak lagi berfungsi pada IE ... Apakah ada solusi baru untuk IE? msdn.microsoft.com/en-us/library/hh801215(v=vs.85).aspx
tb11
2
Saat ini Firefox mendukung filter: drop-shadow(x y blur color); sehingga trik SVG seharusnya tidak lagi diperlukan.
Raptor007
11
Tidak bisakah kita semua setuju bahwa IE seharusnya dibuang ke tumpukan sampah bertahun-tahun yang lalu? Edge sedikit lebih baik, tetapi Anda harus mengatur pengembangan perangkat lunak kembali ke zaman kegelapan dengan IE? Sungguh suatu kekejian.
RyanNerd
217

Ya, dimungkinkan menggunakan filter: dropShadow(x y blur? spread? color?), baik dalam CSS atau 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);">

Abdul
sumber
8
Tidak ada dukungan IE ... :(
CF
10
IE harus mengerti waktu: P
Bryant Jackson
6
-webkit-filter tidak lagi diperlukan
Brett Donald
11
2019: apa itu IE? : P
evilReiko
36

Jika Anda memiliki> 100 gambar yang ingin Anda buat bayangannya, saya sarankan menggunakan program command-line ImageMagick . Dengan ini, Anda dapat menerapkan drop shadow berbentuk ke 100 gambar hanya dengan mengetik satu perintah! Sebagai contoh:

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

Perintah di atas (shell) mengambil setiap file .png di direktori saat ini, menerapkan drop shadow, dan menyimpan hasilnya di direktori shadow /. Jika Anda tidak suka drop shadow yang dihasilkan, Anda dapat mengubah parameter secara berlebihan; mulai dengan melihat dokumentasi bayangan , dan petunjuk penggunaan umum memiliki banyak contoh keren hal-hal yang dapat dilakukan untuk gambar.

Jika Anda berubah pikiran di masa depan tentang tampilan drop shadow - hanya satu perintah untuk menghasilkan gambar baru dengan parameter berbeda :-)

psmears
sumber
22
Meskipun ini solusi, itu tidak menjawab pertanyaan!
leo
6
Penanya berusaha membuat peramban membuat bayangan, bukan mengeksekusi skrip pada server yang dapat membuat bayangan. Ini adalah informasi yang bermanfaat tetapi bukan ruang masalah yang sama.
SG1
Beberapa catatan agar ini berfungsi: 1. Anda harus membuat direktori bayangan sebelum menjalankan perintah ini (seperti dengan mkdir shadow) 2. $iharus dikutip (seperti pada "$i") atau akan tercekik jika gambar memiliki ruang dalam nama 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. File yang dihasilkan akan dinamai filename.png.png. Ini versi yang sepenuhnya berfungsi: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: Poin bagus - meskipun perhatikan ini dimaksudkan sebagai ilustrasi dari apa yang bisa dilakukan, daripada program yang berfungsi penuh! Saya telah memperbaiki sufiks .png ganda dan tanda kutip; direktori hal yang saya rasa hanya akan menghalangi ...
psmears
34
img {
  -webkit-filter: drop-shadow(5px 5px 5px #222222);
  filter: drop-shadow(5px 5px 5px #222222);
}

Itu bekerja bagus untuk saya. Satu hal yang perlu diperhatikan di IE Anda membutuhkan warna penuh (# 222222) tiga karakter tidak berfungsi.

Jaclyn U
sumber
29

Seperti yang disebutkan Dudley dalam jawabannya, ini dimungkinkan dengan filter CSS drop-shadow untuk webkit, SVG untuk Firefox dan filter DirectX untuk Internet Explorer 9-.

Satu langkah lebih jauh adalah menyejajarkan SVG, menghilangkan permintaan tambahan:

.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
sumber
1
Ini berfungsi dengan baik .. lebih baik daripada jika saya mendefinisikan SVG di dalam tag HTML. (firefox)
Oki Erie Rinaldi
18

Tambahkan batas dengan jari-jari di kelas Anda jika itu adalah sebuah blok. karena secara default shadow akan berlaku pada batas blok, bahkan jika gambar Anda memiliki sudut bulat.

border-radius: 4px;

ubah radius batasnya sesuai dengan sudut gambar Anda. Semoga bantuan ini.

anupal
sumber
12

Cukup tambahkan ini:

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

contoh:

<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
sumber
6

Berikut cuplikan kode animasi glow hover siap pakai untuk ini:

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

-webkit-filter: drop-shadow(0px 0px 0px rgba(255,255,255,0.80));
Dmitry Kaigorodov
sumber
selain webkit?
mmm
3

Ketika saya memposting ini awalnya itu tidak mungkin jadi ini adalah solusinya. Sekarang saya hanya menyarankan menggunakan jawaban lain.

Tidak ada cara untuk mendapatkan garis besar gambar dengan tepat, tetapi Anda dapat memalsunya dengan div di belakang gambar di tengah.

Jika trik saya tidak berhasil, Anda harus memotong gambar dan melakukannya untuk setiap gambar kecil. (semakin banyak gambar semakin akurat bayangan akan terlihat) tetapi untuk sebagian besar gambar itu terlihat baik-baik saja dengan hanya satu img.

apa yang perlu Anda lakukan adalah meletakkan wrap di sekitar img Anda seperti itu

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

lalu Anda meletakkan pembagi kosong di dalam bungkus (ini akan berfungsi sebagai bayangan)

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

dan kemudian Anda harus membuat bayangan muncul di belakang img dengan 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;
}

sekarang posisikan imgWrap ke posisi img asli ... untuk memusatkan bayangan img Anda dapat mengacaukan dengan dua nilai pertama dari kotak-bayangan membuat mereka negatif .... atau Anda dapat memposisikan img dan bayangan bayangan benar-benar membuat img nilai atas dan kiri = 0 dan nilai shadow shadow = setengah dari lebar dan tinggi img masing-masing.

Jika ini terlihat mengerikan, potong img Anda dan coba lagi.

(Jika Anda tidak ingin bayangan di belakang img hanya pada garis besar maka Anda perlu membuat img Anda buram dan membuatnya bertindak seolah-olah transparan yang tidak sulit dan Anda dapat berkomentar dan saya akan jelaskan nanti)

Xitcod13
sumber
ketika saya menjawab itu tidak mungkin saya kira sekarang. Masa depan ada di sini!
Xitcod13
2

Dalam kasus saya ini harus bekerja pada browser seluler modern, dengan gambar PNG dalam berbagai bentuk dan transparansi. Saya membuat drop shadow menggunakan duplikat gambar. Itu berarti saya memiliki dua imgelemen gambar yang sama, satu di atas yang lain (menggunakan position: absolute), dan satu di belakang memiliki aturan berikut yang diterapkan padanya:

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

Ini termasuk filter kecerahan untuk menggelapkan gambar bawah, dan filter blur untuk membuat efek drop shadow yang biasa terjadi. Opacity pada 50% kemudian diterapkan untuk melunakkannya.

Ini dapat diterapkan lintas browser menggunakan mozdan msbendera.

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

ido
sumber
1

Ini tidak akan mungkin dilakukan dengan css - gambar berbentuk bujur sangkar, jadi bayangannya adalah bayangan bujur sangkar. Cara termudah adalah dengan menggunakan photoshop / gimp atau editor gambar lainnya untuk menerapkan bayangan seperti gambar inti.

oezi
sumber
Terima kasih atas balasannya Tapi, menambahkan gambar di editor akan memiliki masalah di masa depan, ketika saya akan memiliki> 100 gambar dan harus mengubah sedikit bayangan. Solusi terbaik untuk masalah saya - adalah menambahkan gambar bayangan tambahan di bawah setiap gambar yang dipertanyakan dengan jQuery.
Antonal
1

Trik yang sering saya gunakan ketika saya hanya membutuhkan bayangan "sedikit" (baca: kontur tidak boleh super tepat) adalah menempatkan DIV dengan radial fill 100% -black-to-100% -transparan di bawah gambar. CSS untuk DIV terlihat seperti:

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

Ini akan membuat 'titik' hitam pudar melingkar pada 320x320 DIV. Jika Anda menskalakan tinggi atau lebar DIV Anda mendapatkan oval yang sesuai. Sangat bagus untuk membuat misalnya bayangan di bawah botol atau bentuk seperti silinder lainnya.

Ada alat yang luar biasa, sangat luar biasa untuk membuat gradien CSS di sini:

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

ps: Lakukan klik iklan kesopanan saat Anda menggunakannya. (Dan, tidak, saya tidak berafiliasi dengan itu. Tapi mengklik sopan santun harus menjadi sedikit kebiasaan, terutama untuk alat yang sering Anda gunakan ... katakan saja ... karena kita semua bekerja di internet ... )

Singkirkan Iculous
sumber
Saya bisa melihat ini terlihat cukup bagus ketika dimodifikasi sedikit
BeachInCalifornia.com
1
“Klik iklan kehormatan”? Serius, bagaimana merobek pengiklan adalah hal yang baik untuk 'Net? Banyak dari kita adalah pengiklan sendiri, atau dibayar oleh mereka, sehingga memicu biaya bagi pengiklan untuk iklan untuk produk yang tidak akan Anda beli adalah hal yang sangat tidak menyenangkan untuk dilakukan. Jika Anda tertarik pada iklan, klik dengan segala cara, tapi jangan lakukan ini!
alastair
Oh, turunkan moral Anda, Alastair. Dunia nyata terlihat sedikit berbeda. "Merobek pengiklan"? Betulkah? LOL - Beri aku istirahat, teman. Saya sudah berkecimpung di bidang periklanan dan pemasaran selama hampir 30 tahun. Untuk memasang tanda terima kasih aneh klik tidak memiliki pengaruh apa pun selain mendukung situs yang Anda gunakan GRATIS. Jika Anda khawatir tentang inflasi hadiah dll, khawatir tentang tren semakin memonopoli seluruh industri. Itulah hadiah iklan yang menyimpang, bukan klik sopan santun.
Singkirkan Iculous
Ini terlihat mengerikan pada FF dan IE
barrypicker
1

Anda tidak dapat melakukan ini dengan andal di semua browser. Microsoft tidak lagi mendukung filter DX pada IE10 +, jadi tidak ada solusi di sini yang berfungsi sepenuhnya:

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

Satu-satunya properti yang bekerja dengan andal di semua browser adalah box-shadow, dan ini hanya menempatkan perbatasan pada elemen Anda (misalnya div), menghasilkan perbatasan persegi:

box-shadow: horizontalOffset verticalOffset blurDistance spreadDistance warna inset;

misalnya

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

Jika Anda memiliki gambar yang 'persegi' tetapi dengan sudut bulat yang seragam, drop shadow bekerja dengan baik border-radius, sehingga Anda selalu bisa meniru sudut bulat gambar Anda di div Anda.

Berikut dokumentasi Microsoft untuk box-shadow:

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

Chris Halcrow
sumber
Saya menghargai jawaban yang jujur. Tidak ada contoh di atas yang berfungsi untuk saya.
barrypicker