Drop shadow SVG menggunakan css3

379

Apakah mungkin untuk mengatur drop shadow untuk elemen svg menggunakan css3, sesuatu seperti

box-shadow: -5px -5px 5px #888;
-webkit-box-shadow: -5px -5px 5px #888;

Saya melihat beberapa komentar tentang membuat bayangan menggunakan efek filter. Apakah ada contoh menggunakan css saja. Di bawah ini adalah kode yang berfungsi di mana gaya cusor diterapkan dengan benar, tetapi tidak ada efek bayangan. Tolong bantu saya untuk mendapatkan efek bayangan dengan sedikit kode.

svg .shadow { 
  cursor:crosshair; 
  -moz-box-shadow: -5px -5px 5px #888;
  -webkit-box-shadow: -5px -5px 5px #888;
  box-shadow: -5px -5px 5px #888; 
}	
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full"  viewBox="0 0 120 70">	
    <rect class="shadow" x="10" y="10" width="100" height="50" fill="#c66" />
</svg>

bsr
sumber

Jawaban:

353

Berikut adalah contoh penerapan dropshadow ke beberapa svg menggunakan properti 'filter'. Jika Anda ingin mengontrol opacity dari dropshadow lihat contoh ini . The slopeatribut mengontrol berapa banyak opacity untuk diberikan kepada dropshadow tersebut.

Bit yang relevan dari contoh:

<filter id="dropshadow" height="130%">
  <feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
  <feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
  <feComponentTransfer>
    <feFuncA type="linear" slope="0.5"/> <!-- slope is the opacity of the shadow -->
  </feComponentTransfer>
  <feMerge> 
    <feMergeNode/> <!-- this contains the offset blurred image -->
    <feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
  </feMerge>
</filter>
<circle r="10" style="filter:url(#dropshadow)"/>

Box-shadow didefinisikan untuk bekerja pada kotak CSS (baca: persegi panjang), sementara svg sedikit lebih ekspresif daripada hanya persegi panjang. Baca SVG Primer untuk belajar lebih banyak tentang apa yang dapat Anda lakukan dengan filter SVG.

Erik Dahlström
sumber
1
Apakah ada cara untuk mengendalikan opacity dari dropshadow?
Hugh Guiney
5
@HughGuiney: ya, tentu saja. Berikut adalah contoh dari salah satu cara untuk melakukan itu, xn--dahlstrm-t4a.net/svg/filters/… . Variasikan saja slopeatribut untuk menyesuaikan berapa banyak opacity yang Anda inginkan.
Erik Dahlström
1
@LorenzoPolidori IE10 dan Safari 5.2 keduanya mendukung filter SVG.
Erik Dahlström
3
Contoh tentang bagaimana menerapkan pendekatan ini di D3.js: bl.ocks.org/cpbotha/5200394
mb21
3
@Costa lihat misalnya stackoverflow.com/questions/7965196/svg-color-of-the-shadow
Erik Dahlström
559

Gunakan properti CSS barufilter .

Didukung oleh browser webkit , Firefox 34+ dan Edge .

Anda dapat menggunakan polyfill ini yang akan mendukung FF <34, IE6 +.

Anda akan menggunakannya seperti ini:

/* Use -webkit- only if supporting: Chrome < 54, iOS < 9.3, Android < 4.4.4 */

.shadow {
  -webkit-filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
  filter: drop-shadow( 3px 3px 2px rgba(0, 0, 0, .7));
  /* Similar syntax to box-shadow */
}
<img src="https://upload.wikimedia.org/wikipedia/commons/c/ce/Star_wars2.svg" alt="" class="shadow" width="200">

<!-- Or -->

<svg class="shadow" ...>
    <rect x="10" y="10" width="200" height="100" fill="#bada55" />
</svg>

Pendekatan ini berbeda dari box-shadowefek karena opacity dan tidak menerapkan efek drop shadow ke kotak tetapi lebih ke sudut-sudut elemen svg itu sendiri.

Harap Dicatat : Pendekatan ini hanya berfungsi ketika kelas ditempatkan pada <svg>elemen saja. Anda TIDAK dapat menggunakan ini pada elemen svg sebaris seperti <rect>.

<!-- This will NOT work! -->
<svg><rect class="shadow" ... /></svg>

Baca lebih lanjut tentang filter css di html5rocks .

hitautodestruct
sumber
47
Ini tampaknya berfungsi untuk gambar, atau untuk seluruh svg, tetapi untuk pilihan di dalam svg. the biola
heneryville
14
Ini tidak berfungsi untuk menerapkan drop-shadows ke elemen svg dengan cara apa pun. jangan gunakan itu. Contoh kegagalan: jsbin.com/bepurahuwa/1/edit?html,css,js,output
Andy Ray
19
@AndyRay bekerja seperti pesona ... jsbin.com/peviso/edit?html,css, js, output . Anda menempatkan kelas pada tag <svg>.
hitautodestruct
4
@hitautodestruct ya, itu berfungsi seperti itu. Masalah sebenarnya muncul saat Anda perlu menerapkan filter ke suatu elemen, tetapi tidak untuk yang lain.
Joum
3
Saya kira kedua @AndyRay dan hitautodestruct benar, karena seperti yang ditunjukkan di sini , ini terlihat seperti masalah rendering Chrome: Firefox melakukan rendering filter dengan benar pada elemen spesifik SVG.
Gruber
72

Anda dapat dengan mudah menambahkan efek drop-shadow ke elemen svg menggunakan fungsi drop-shadow () CSS dan nilai warna rgba. Dengan menggunakan nilai warna rgba Anda dapat mengubah opacity bayangan Anda.

img.light-shadow{
  filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 0.4));
}

img.dark-shadow{
  filter: drop-shadow(0px 3px 3px rgba(0, 0, 0, 1));
}
<img class="light-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />
<img class="dark-shadow" src="https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/so/so-logo.svg" />

Jonny Ekholm
sumber
4
@Foxhoundn Ini jelas merupakan solusi modern, dan harus diterima sebagai jawabannya.
SeedyROM
3
Tetapi itu tidak bekerja untuk sub-elemen dari SVG
mix3d
Internet Explorer 11: Gagal (tidak ada bayangan drop tetapi gambar SVG asli ditampilkan). Firefox (Release & ESR): Oke. Google Chrome: Oke. Edge Legacy: Oke.
Culip
bendungan, apakah ini hanya bekerja pada kelompok dan bentuk di SVG!
OG Sean
25

Cara termudah yang saya temukan adalah dengan feDropShadow. Saya tidak akan pernah kembali menggunakan nama tag filter yang sangat esoteris yang tidak saya mengerti.

<filter id="shadow" x="0" y="0" width="200%" height="200%">
  <feDropShadow dx="40" dy="40" stdDeviation="35" flood-color="#ff0000" flood-opacity="1" />
</filter>
nikk wong
sumber
4
Saya melakukan beberapa bacaan dan sekarang saya mengerti jawaban Anda, Anda pasti mendapatkan upvote itu. Jawaban ini tidak cukup dihargai. Namun, sedikit penjelasan akan lebih baik. Contoh ini misalnya: developer.mozilla.org/en-US/docs/Web/SVG/Element/…
Niklas
Anda sepenuhnya benar. Terima kasih!
nikk wong
Agar ini berfungsi, Anda perlu menambahkan filter:url(#shadow)ke elemen yang Anda ingin memiliki bayangan ( #shadowadalah id dari filtertag). Sebagai contoh <path d="..." style="filter:url(#shadow)"/>. Mungkin Anda harus menambahkannya ke jawaban Anda.
Donald Duck
1

Saya tidak mengetahui solusi khusus CSS.

Seperti yang Anda sebutkan, filter adalah pendekatan kanonik untuk membuat efek drop shadow di SVG. Spesifikasi SVG termasuk contohnya.

jbeard4
sumber
3
-webkit-filter: drop-shadow()adalah cara untuk pergi pasti. Lihat jawabannya oleh @hitautodestruct.
clayzermk1
4
@ clayzermk1 jika Anda hanya ingin bekerja di webkit .... maka ya. Kami mencari solusi yang lebih solid, metinks, dan saya pikir ini juga tidak lagi didukung.
dudewad
@ jbeard4 tautan rusak, lebih baik mungkin kontennya disisipkan di sini.
Ezeewei
1
Tunjukkan tautan yang diajukan ke Removed: Filter Effects This chapter is no longer part of the SVG specification!!
F. Hauri
1
Ini bukan jawaban.
Yay295
1

Teks hitam dengan bayangan putih

Cara lain, saya gunakan untuk bayangan putih (pada teks): membuat klon untuk bayangan:

Catatan : Ini diperlukan xmlns:xlink="http://www.w3.org/1999/xlink"pada deklarasi SVG.

Nilai teks asli terletak di <defs>bagian, dengan posisi dan gaya, tetapi tanpa filldefinisi.

Teks dikloning dua kali: pertama untuk bayangan dan kedua untuk teks itu sendiri.

<svg xmlns="http://www.w3.org/2000/svg" width="640" height="70"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
  <filter id="Blur"><feGaussianBlur stdDeviation="0.8" /></filter>
  <text style="font-family:sans,helvetica;font-weight:bold;font-size:12pt"
      id="Text"><tspan x="12" y="19">
        Black text with white shadow
    </tspan></text>
  </defs>
  <rect style="fill:#8AB" width="640" height="70" />
  <use style="fill:white;" filter="url(#Blur)" xlink:href="#Text"
      transform="translate(1.8,.9)"/>
  <use style="fill:black;" xlink:href="#Text"/>
</svg>

Bayangan yang lebih jauh dengan nilai terbesar sebagai penyimpangan blur :

<svg xmlns="http://www.w3.org/2000/svg" width="640" height="70"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
  <filter id="Blur"><feGaussianBlur stdDeviation="3" /></filter>
  <text style="font-family:sans,helvetica;font-weight:bold;font-size:12pt"
      id="Text"><tspan x="12" y="19">
        Black text with white shadow
    </tspan></text>
  </defs>
  <rect style="fill:#8AB" width="640" height="70" />
  <use style="fill:white;" filter="url(#Blur)" xlink:href="#Text"
      transform="translate(7,5)"/>
  <use style="fill:black;" xlink:href="#Text"/>
</svg>

Anda bisa menggunakan pendekatan yang sama dengan objek SVG biasa.

Dengan persyaratan yang sama: Tidak ada definisi isi di <defs>bagian !

<svg xmlns="http://www.w3.org/2000/svg" width="364" height="172"
    xmlns:xlink="http://www.w3.org/1999/xlink">
  <defs>
    <filter id="Blur"><feGaussianBlur stdDeviation="0.8" /></filter>
    <g transform="matrix(.7,0,0,.7,-117.450795,-335.320895)" id="Img">
        <g transform="matrix(12.997776,0,0,-12.997776,389.30313,662.04015)">
            <path d="m 0,0 -1.107,0 c -0.039,0 -0.067,0.044 -0.067,0.086 0,0.015 0.589,1.914 0.589,1.914 0.021,0.071 0.023,0.073 0.031,0.073 l 0.001,0 c 0.009,0 0.01,-0.002 0.031,-0.073 0,0 0.589,-1.899 0.589,-1.914 C 0.067,0.044 0.037,0 0,0 M 1.493,4.345 C 1.482,4.383 1.448,4.411 1.408,4.414 l -4.065,0 C -2.698,4.41 -2.731,4.383 -2.742,4.346 c 0,0 -2.247,-7.418 -2.247,-7.432 0,-0.037 0.029,-0.067 0.067,-0.067 l 2.687,0 c 0.021,0.008 0.037,0.028 0.042,0.051 l 0.313,1 c 0.01,0.025 0.033,0.042 0.061,0.043 l 2.479,0.002 c 0.027,-0.002 0.051,-0.021 0.061,-0.045 l 0.32,-1 c 0.005,-0.023 0.021,-0.044 0.042,-0.052 0,0 2.642,10e-4 2.644,10e-4 0.037,0 0.068,0.028 0.068,0.065 0,0.013 -2.302,7.433 -2.302,7.433" />
        </g>
        <g transform="matrix(12.997776,0,0,-12.997776,508.27177,644.93113)">
            <path d="m 0,0 -1.651,-0.001 c 0,0 -0.044,0.013 -0.044,0.063 l -10e-4,0.833 c 0,0.05 0.044,0.063 0.044,0.063 l 1.514,0 C 0.038,0.958 0.394,0.87 0.394,0.463 0.394,0.056 0,0 0,0 m 7.916,0.645 3.741,0 0,2.453 -4.81,0 C 6.397,3.098 5.764,2.866 5.401,2.597 5.038,2.328 4.513,1.715 4.513,0.87 c 0,-0.845 0.513,-1.502 0.513,-1.502 0.263,-0.326 0.925,-1.005 0.925,-1.005 0.015,-0.016 0.024,-0.037 0.024,-0.061 0,-0.051 -0.041,-0.092 -0.092,-0.092 l -3.705,0 c -0.451,0.002 -0.482,0.181 -0.482,0.207 0,0.046 0.056,0.075 0.056,0.075 0.169,0.081 0.514,0.35 0.514,0.35 0.732,0.57 0.82,1.352 0.82,1.771 0,0.42 -0.063,1.163 -0.814,1.814 C 1.521,3.078 0.57,3.096 0.57,3.096 l -5.287,0 c 0,0 0,-7.52 0,-7.522 0,-0.024 0.022,-0.043 0.046,-0.043 l 2.943,0 0,2.11 c 0,0.037 0.057,0 0.057,0 l 1.533,-1.54 c 0.545,-0.551 1.446,-0.57 1.446,-0.57 l 5.796,0.001 c 0.989,0 1.539,0.538 1.69,0.688 0.15,0.151 0.651,0.714 0.651,1.647 0,0.932 -0.426,1.409 -0.608,1.628 C 8.675,-0.309 8.029,0.375 7.894,0.517 7.878,0.53 7.868,0.55 7.868,0.572 c 0,0.033 0.019,0.064 0.048,0.073" />
        </g>
        <g transform="matrix(12.997776,0,0,-12.997776,306.99861,703.01559)">
            <path d="m 0,0 c 0.02,0 0.034,0.014 0.04,0.036 0,0 2.277,7.479 2.277,7.486 0,0.02 -0.012,0.042 -0.031,0.044 0,0 -2.805,0 -2.807,0 -0.014,0 -0.023,-0.011 -0.026,-0.026 0,-0.001 -0.581,-1.945 -0.581,-1.946 -0.004,-0.016 -0.012,-0.026 -0.026,-0.026 -0.014,0 -0.026,0.014 -0.028,0.026 L -1.79,7.541 c -0.002,0.013 -0.012,0.025 -0.026,0.025 -10e-4,0 -3.1,0.001 -3.1,0.001 -0.009,-0.002 -0.017,-0.01 -0.02,-0.018 0,0 -0.545,-1.954 -0.545,-1.954 -0.003,-0.017 -0.012,-0.027 -0.027,-0.027 -0.013,0 -0.024,0.01 -0.026,0.023 l -0.578,1.952 c -0.001,0.012 -0.011,0.022 -0.023,0.024 l -2.992,0 c -0.024,0 -0.044,-0.02 -0.044,-0.045 0,-0.004 10e-4,-0.012 10e-4,-0.012 0,0 2.31,-7.471 2.311,-7.474 C -6.853,0.014 -6.839,0 -6.819,0 c 0.003,0 2.485,-0.001 2.485,-0.001 0.015,0.002 0.03,0.019 0.034,0.037 10e-4,0 0.865,2.781 0.865,2.781 0.005,0.017 0.012,0.027 0.026,0.027 0.015,0 0.023,-0.012 0.027,-0.026 L -2.539,0.024 C -2.534,0.01 -2.521,0 -2.505,0 -2.503,0 0,0 0,0" />
        </g>
        <g transform="matrix(12.997776,0,0,-12.997776,278.90126,499.03369)">
            <path d="m 0,0 c -0.451,0 -1.083,-0.232 -1.446,-0.501 -0.363,-0.269 -0.888,-0.882 -0.888,-1.727 0,-0.845 0.513,-1.502 0.513,-1.502 0.263,-0.326 0.925,-1.01 0.925,-1.01 0.015,-0.016 0.024,-0.037 0.024,-0.06 0,-0.051 -0.041,-0.093 -0.092,-0.093 -0.008,0 -6.046,0 -6.046,0 l 0,-2.674 7.267,0 c 0.988,0 1.539,0.538 1.69,0.689 0.15,0.15 0.65,0.713 0.65,1.646 0,0.932 -0.425,1.414 -0.607,1.633 -0.162,0.196 -0.808,0.876 -0.943,1.017 -0.016,0.014 -0.026,0.034 -0.026,0.056 0,0.033 0.019,0.063 0.048,0.073 l 3.5,0 0,-5.114 2.691,0 0,5.101 3.267,0 0,2.466 L 0,0 Z" />
        </g>
        <g transform="matrix(12.997776,0,0,-12.997776,583.96822,539.30215)">
            <path d="m 0,0 -1.651,-0.001 c 0,0 -0.044,0.013 -0.044,0.063 l -10e-4,0.833 c 0,0.05 0.044,0.063 0.044,0.063 l 1.514,0 C 0.038,0.958 0.394,0.87 0.394,0.463 0.394,0.056 0,0 0,0 m 2.178,-1.79 c -0.45,0.002 -0.482,0.181 -0.482,0.207 0,0.046 0.056,0.075 0.056,0.075 0.169,0.081 0.514,0.35 0.514,0.35 0.732,0.57 0.82,1.352 0.82,1.771 0,0.42 -0.063,1.163 -0.814,1.814 C 1.521,3.078 0.57,3.098 0.57,3.098 l -5.287,0 c 0,0 0,-7.522 0,-7.524 0,-0.024 0.022,-0.043 0.046,-0.043 0.005,0 2.943,0 2.943,0 l 0,2.109 c 0,0.038 0.057,0 0.057,0 l 1.533,-1.539 c 0.545,-0.551 1.446,-0.57 1.446,-0.57 l 4.525,0 0,2.679 -3.655,0 z" />
        </g>
        <g transform="matrix(12.997776,0,0,-12.997776,466.86346,556.40203)">
            <path d="m 0,0 -1.107,0 c -0.041,0 -0.067,0.044 -0.067,0.086 0,0.016 0.589,1.914 0.589,1.914 0.021,0.071 0.027,0.073 0.031,0.073 l 0.001,0 c 0.004,0 0.01,-0.002 0.031,-0.073 0,0 0.589,-1.898 0.589,-1.914 C 0.067,0.044 0.04,0 0,0 M 1.49,4.347 C 1.479,4.385 1.446,4.412 1.405,4.414 l -4.065,0 C -2.7,4.412 -2.734,4.385 -2.745,4.348 c 0,0 -2.245,-7.42 -2.245,-7.434 0,-0.037 0.03,-0.067 0.067,-0.067 l 2.687,0 c 0.022,0.007 0.038,0.028 0.043,0.051 l 0.313,1.001 c 0.01,0.024 0.033,0.041 0.061,0.042 l 2.478,0 C 0.687,-2.061 0.71,-2.078 0.721,-2.102 l 0.32,-1 c 0.005,-0.023 0.021,-0.044 0.042,-0.052 0,0 2.642,10e-4 2.644,10e-4 0.037,0 0.067,0.028 0.067,0.066 0,0.012 -2.304,7.434 -2.304,7.434" />
        </g>
    </g>
  </defs>
  <rect style="fill:#8AB" width="364" height="172" />
  <use style="fill:white;" filter="url(#Blur)" xlink:href="#Img"
    transform="translate(1.8,.9)"/>
  <use style="fill:black;" xlink:href="#Img"/>
</svg>

F. Hauri
sumber
Apakah tidak mungkin menggunakan saja flood-color?
Robert Monfera
Blurdigunakan untuk membuat bayangan tampak sedikit kabur. Lihat versi teks kedua saya More distant shadow...(Baru ditambahkan sekarang)
F. Hauri
0

Mungkin sebuah evolusi, tampaknya filter inline css bekerja dengan baik pada elemen, dengan cara tertentu.

Mendeklarasikan drop-shadow css filter, dalam elemen svg, di kelas atau inline TIDAK bekerja, seperti yang ditentukan sebelumnya.

Tapi, setidaknya di Firefox, dengan sihir berikut:

Menambahkan inline deklarasi filter , dengan javascript, setelah memuat DOM .

// Does not works, with regular dynamic css styling:

shadow0.onchange = () => {
  rect1.style.filter = "filter:drop-shadow(0 0 " + shadow0.value + "rem black);"
}

// Okay! Inline styling, appending.

shadow1.onchange = () => {
  rect1.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
  rect2.style += " ;filter:drop-shadow(0 0 " + shadow1.value + "rem black);"
}
<h4>
Does not works! 
<input id="shadow0" type="number" min="0" max="100" step="0.1">

 | Okay!
<input id="shadow1" type="number" min="0" max="100" step="0.1">

<svg viewBox="0 0 120 70">  
    <rect id="rect1" x="10" y="10" width="100" height="50" fill="#c66" />
    
    <!-- Inline style declaration does NOT works at svg level, no shadow at loading: -->
    <rect id="rect2" x="40" y="30" width="10" height="10" fill="#aaa" style="filter:drop-shadow(0 0 20rem black)" />
    
</svg>

masukkan deskripsi gambar di sini

NVRM
sumber