Как применить фильтр drop-shadow через CSS к конкретному элементу/пути SVG

Я хотел бы применить фильтр тени к определенному элементу / пути внутри встроенного размещенного SVG через CSS, I не нужно, чтобы вся графика была затенена, просто элемент внутри нее.

.shadow {
  fill: red;
  
  -webkit-filter: 
    drop-shadow( 3px 3px 2px rgba(0,0,0,.7) );
          filter: 
    drop-shadow( 3px 3px 2px rgba(0,0,0,.7) );
}
  <svg height="150" width="150">
    <g>
<path d="M0,0 C-72,132 -72,-26 100,100"></path>
    </g>
    <g class="shadow" >
    <circle class="shadow" cx="100" cy="100" r="20"></circle>
    </g>
  </svg>

Как вы можете видеть выше, я пытаюсь применить тень к элементу красного круга SVG, но он не работает.

в поиске я не нашел никакой конкретной информации об этом, только несколько комментариев в других связанных с SVG вопросах просто говорится, что он не работает на отдельных элементах SVG, но без особых объяснений.

обновление

Как указал @azeós в комментариях он отображается правильно с Firefox (V.43.0.2), поэтому это специфическая проблема Chrome. Есть ли в любом случае, чтобы сделать этот кроссбраузер, не возясь с кодом SVG, как предложено в комментариях?

3 ответов


вы можете применить тень выборочно, сделав выбор цвета на объекте, который вы хотите тени, создавая тень, а затем объединить его под оригинальной графикой. Но вы должны сделать это через ловушку фильтра SVG в CSS - фильтрах, которая не работает в IE. (Так. .. hacky, но возможно)

спецификация здесь: w3.org/TR/SVG11/filters.html#feColorMatrixElement

демо игрушка here:
https://beta.observablehq.com/@gitmullany/filter-effects-using-svg-color-matrices

эта матрица удваивает непрозрачность всех красных значений, нули из непрозрачности всего остального, а затем вычитает 1. Эффект состоит в том, чтобы оставить только вещи с непрозрачностью 100%, которые являются rgb (255,0,0)

#mySVG {
   filter: url(#selective-shadow);
}

.shadow {
  fill: red;
}
<svg>
 <defs>
   <filter id="selective-shadow">
     <feColorMatrix type="matrix" values="0 0 0 0 0 
                                          0 0 0 0 0
                                          0 0 0 0 0 
                                          2 0 0 0 -1"/>
     <feGaussianBlur stdDeviation="3"/>
     <feOffset dy="2" dx="2"/>
     <feMerge>
       <feMergeNode/>
       <feMergeNode in="SourceGraphic"/>
     </feMerge>         
   </filter>
 </defs>
</svg>



<svg height="150" width="150" id="mySVG">
    <g>
<path d="M0,0 C-72,132 -72,-26 100,100"></path>
    </g>
    <g class="shadow" >
    <circle class="shadow" cx="100" cy="100" r="20"></circle>
    </g>
  </svg>

Обновлено 2018-03: Я сделал несколько экспериментов по этому вопросу, потому что я тоже не смог найти никакой информации об этом и результаты довольно противоречивы. Версия TL; DR, Если это вы собираюсь использовать polyfill или просто сделайте dropshadow в SVG.

эксперимент Codepen: http://codepen.io/staypuftman/pen/GoNoMq

Chrome 65 + Canary 67:

ни Chrome, ни edge Canary respect filter или -webkit-filter правильно в контексте падающей тени объекта SVG, но работайте над простым div.

enter image description here

Firefox 58 / Quantum + Firefox 53:

выглядит довольно хорошо для SVG и HTML объектов.

enter image description here

Safari 10.1+

Safari исправил эту проблему в серии 10.1 (и, возможно, 10.0).

enter image description here

сафари 9.x

SVG CSS dropshadow не показывает и div dropshadow имеет меньшую прозрачность по какой-то причине

enter image description here

IE11

ничего.

enter image description here


на этой CodePen я добавил разные отбрасывание тени to path и text динамически генерируемые. здесь я нашел кросс-браузерное решение, которое можно применить к class, например, вместо #robbie img (во второй ссылке):

#robbie img { filter: "progid:DXImageTransform.Microsoft.Dropshadow(OffX=12, OffY=12, Color='#444')";   filter: url(#drop-shadow);   -webkit-filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5));   filter: drop-shadow(12px 12px 7px rgba(0,0,0,0.5)); }

на первый CodePen Я прокомментировал другой альтернативный способ, который не использует классы, но он использует #numbers_dropshadows_filter и #strokes_dropshadows_filter определена в <defs></defs>.

Ура