517 votes

Ombre portée SVG avec css3

Est-il possible de définir une ombre portée pour un élément svg à l'aide de css3, comme suit

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

J'ai vu quelques remarques sur la création d'ombres à l'aide d'effets de filtre. Y a-t-il un exemple d'utilisation de css seul ? Ci-dessous un code de travail où le style cusor est correctement appliqué, mais sans effet d'ombre. Veuillez m'aider à obtenir l'effet d'ombre avec un minimum de code.

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>

825voto

hitautodestruct Points 3220

Utilisez le nouveau CSS [filter](https://developer.mozilla.org/en-US/docs/Web/CSS/filter#drop-shadow()_2) propriété.

Prise en charge par les navigateurs webkit Firefox 34+ et Bordure .

Vous pouvez utiliser ce polyfill qui supportera FF < 34, IE6+.

Vous l'utiliseriez comme ça :

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

Cette approche diffère de l'approche box-shadow en ce sens qu'il tient compte de l'opacité et n'applique pas l'effet d'ombre portée à la boîte mais plutôt aux coins de l'élément svg lui-même.

Veuillez noter : Cette approche ne fonctionne que lorsque la classe est placée sur l'onglet <svg> élément seul. Vous pouvez PAS utiliser cette méthode sur un élément svg en ligne tel que <rect> .

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

Pour en savoir plus sur les filtres css, voir html5rocks .

55 votes

Cela semble fonctionner pour les images, ou pour l'ensemble du svg, mais pour les sélections à l'intérieur du svg. le violon

0 votes

L'utilisation du filtre : drop-shadow() ou box-shadow dans webkit est la même pour l'élément svg. Toujours pas de solution pour les éléments internes.

0 votes

@heneryville Pas sûr de ce que vous voulez dire par ce commentaire ? Voir l'exemple ici : jsbin.com/dipusemiye

412voto

Erik Dahlström Points 21519

Voici un exemple d'appliquer une ombre portée à un svg en utilisant la propriété "filter". Si vous voulez contrôler l'opacité de l'ombre portée, jetez un coup d'oeil à cet exemple . Le site slope contrôle le degré d'opacité à donner à l'ombre portée.

Les éléments pertinents de l'exemple :

<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 est défini pour fonctionner sur les boîtes CSS (lire : rectangles), tandis que svg est un peu plus expressif que de simples rectangles. Lisez le Introduction au SVG pour en savoir un peu plus sur ce que vous pouvez faire avec les filtres SVG.

2 votes

Existe-t-il un moyen de contrôler l'opacité de l'ombre portée ?

7 votes

@HughGuiney : oui, bien sûr. Voici un exemple d'une façon de le faire, xn--dahlstrm-t4a.net/svg/filtres/ . Il suffit de varier les slope pour ajuster le degré d'opacité que vous souhaitez.

0 votes

Notez qu'Internet Explorer et Safari ne prennent pas encore en charge les filtres SVG : w3schools.com/svg/svg_feoffset.asp

141voto

Jonny Ekholm Points 1107

Vous pouvez facilement ajouter un effet d'ombre portée à un élément svg en utilisant la fonction CSS drop-shadow() et les valeurs de couleur rgba. En utilisant les valeurs de couleur rgba, vous pouvez modifier l'opacité de votre ombre.

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" />

10 votes

@Foxhoundn C'est définitivement la solution moderne, et devrait être acceptée comme la réponse.

0 votes

Internet Explorer 11 : Échec (pas d'ombre portée mais l'image SVG originale est affichée). Firefox (Release & ESR) : OK. Google Chrome : OK. Edge Legacy : OK.

2 votes

Dam, si cela ne fonctionnait que sur les groupes et les formes dans le SVG !

56voto

nikk wong Points 3124

La méthode la plus simple que j'ai trouvée est la suivante feDropShadow .

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

Sur l'élément :

<path d="..." filter="url(#shadow)"/>

6 votes

J'ai fait un peu de lecture et maintenant que je comprends votre réponse, vous obtenez définitivement ce vote positif. Cette réponse n'est pas assez appréciée. Cependant, un peu plus d'explication serait bien. Cet exemple par exemple : developer.mozilla.org/fr/US/docs/Web/SVG/Element/

2 votes

Pour que cela fonctionne, vous devez ajouter filter:url(#shadow) à l'élément que vous souhaitez ombrager ( #shadow est l'identifiant du filter ). Par exemple <path d="..." style="filter:url(#shadow)"/> . Vous devriez peut-être ajouter cela à votre réponse.

0 votes

Avoir des valeurs plus petites dans feDropShadow dx="40" dy="40" stdDeviation="35" comme 3,3,1 au lieu de 40,40,35 pourrait éviter une certaine confusion.

11voto

Serj Sagan Points 2731

Donc, comme cela a été mentionné dans les commentaires enterrés de la réponse acceptée par Lorenzo Polidori, l'option la plus simple qui fonctionne pour moi dans Chrome (et je suis sûr que d'autres navigateurs Webkit) est :

-webkit-svg-shadow: 0 0 7px #53BE12;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X