faire un objet svg html également un lien cliquable

143

J'ai un objet SVG dans ma page HTML et je l'encapsule dans une ancre, donc lorsque vous cliquez sur l'image svg, l'utilisateur accède au lien d'ancrage.

<a href="http://www.google.com/">
    <object data="mysvg.svg" type="image/svg+xml">
        <span>Your browser doesn't support SVG images</span>
    </object>
</a>

Lorsque j'utilise ce bloc de code, cliquer sur l'objet svg ne m'amène pas à google. Dans IE8 <le texte de la plage est cliquable.

Je ne veux pas modifier mon image svg pour contenir des balises.

Ma question est la suivante: comment puis-je rendre l'image svg cliquable?

Iancoleman
la source

Réponses:

20

Le moyen le plus simple est de ne pas utiliser <object>. Utilisez plutôt une balise <img> et l'ancre devrait fonctionner correctement.

Erik Dahlström
la source
1
La balise img irait normalement là où se trouve la balise span pour que cela se dégrade gracieusement.
Adrian Garner
18
N'est-ce pas l'idée d'afficher un vecteur svg, pas une image?
Luke
7
@ ErikDahlström mais <img>avec une référence aux données svg ne fonctionne pas toujours comme prévu, même dans la dernière version de Chrome :( stackoverflow.com/questions/15194870/…
dshap
15
Comme @energee l'a souligné, vous pouvez utiliser une <object>balise et ajouter une point-event: none;pour la rendre cliquable. Il préserve l'accès à votre code source svg et vous permet de le manipuler dynamiquement.
Antoine
1
Utiliser un imgn'est pas toujours une option. Dans mon cas, j'ai besoin de manipuler le svg, ce qui ne peut pas être fait correctement via img, je dois utiliser object.
Martijn
216

En fait, la meilleure façon de résoudre ce problème est ... sur la balise <object>, utilisez:

pointer-events: none;

Remarque: les utilisateurs qui ont installé le plugin Ad Blocker obtiennent un onglet [Block] dans le coin supérieur droit lors du survol (le même que celui d'une bannière flash). En paramétrant ce css, cela disparaîtra également.

http://jsfiddle.net/energee/UL9k9/

énergé
la source
4
Remarque: IE ne prendra pas en charge les événements de pointeur sur les éléments réguliers avant IE 11, mais les prend déjà en charge sur SVG. Voir caniuse.com/pointer-events
webdesserts
9
Un inconvénient de cette solution (et de celle de noelmcg également) est que si votre fichier SVG contient des règles CSS avec un sélecteur: hover, ces règles cesseront de fonctionner. La solution proposée par Ben Frain n'a pas ce problème.
MathieuLescure
6
Cela devrait être une réponse approuvée. Utiliser imgavec svg rend alors inutilisable pour changer les styles SVG internes.
cadavre
3
Cela doit être la réponse approuvée! Vraiment gentil, merci
Daniel Broughan
5
Très bonne réponse. J'ai rendu le mien universel avec cela dans le CSS global. object [type * = "svg"] {pointer-events: none}
Gregor Macgregor
40

J'ai eu le même problème et j'ai réussi à le résoudre en:

Emballage de l'objet avec un élément défini sur block ou inline-block

<a>
    <span>
        <object></object>
    </span>
</a>

Ajout au <a>tag:

display: inline-block;
position: relative; 
z-index: 1;

et au <span>tag:

display: inline-block;

et au <object>tag:

position: relative; 
z-index: -1

Voir un exemple ici: http://dabblet.com/gist/d6ebc6c14bd68a4b06a6

Trouvé via le commentaire 20 ici https://bugzilla.mozilla.org/show_bug.cgi?id=294932

Richard
la source
1
Excuses, j'ai oublié l'affichage: élément bloc / bloc en ligne pour envelopper l'objet
Richard
1
La meilleure solution ici!
Baldráni
c'est la meilleure solution pour ce problème et fonctionne sur tous les navigateurs
Kalpesh Popat
1
si l'image a transparent bg alors ces bits ne semblent pas cliquables
sobelito
Cela a fonctionné pour moi, j'ai également dû ajouter de la hauteur: 100% aux éléments a et span de ma situation
sk03
32

Je voudrais m'en attribuer le mérite, mais j'ai trouvé une solution ici:

https://teamtreehouse.com/forum/how-do-you-make-a-svg-clickable

ajoutez ce qui suit au css pour l'ancre:

a.svg {
  position: relative;
  display: inline-block; 
}
a.svg:after {
  content: ""; 
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left:0;
}


<a href="#" class="svg">
  <object data="random.svg" type="image/svg+xml">
    <img src="random.jpg" />
  </object>
</a>

Link fonctionne sur le svg et sur le fallback.

noelmcg
la source
2
C'est la solution la plus simple et la plus prise en charge selon l'opinion
Type-Style
3
cela a toujours un problème: les événements de pointeur SVG (animations) ne fonctionnent plus (survol, souris, clic)! Tout comme simplement en utilisant des événements de pointeur: aucun sur l'objet lui-même ...
qdev
26

Vous pouvez également coller quelque chose comme ça au bas de votre SVG (juste avant la </svg>balise de fermeture ):

<a xmlns="http://www.w3.org/2000/svg" id="anchor" xlink:href="/" xmlns:xlink="http://www.w3.org/1999/xlink" target="_top">
    <rect x="0" y="0" width="100%" height="100%" fill-opacity="0"/>
</a>

Ensuite, modifiez simplement le lien en conséquence. J'ai utilisé 100% de largeur et de hauteur pour couvrir le SVG dans lequel il se trouve. Le crédit de la technique revient aux gens intelligents de Clearleft.com - c'est là que je l'ai vu pour la première fois.

Ben Frain
la source
2
J'ai des styles css avec un sélecteur: hover intégré dans mon fichier SVG. C'est la seule solution qui ne désactive pas le style.
MathieuLescure
21

Une simplification de la solution de Richard. Fonctionne au moins dans Firefox, Safari et Opera:

<a href="..." style="display: block;">
    <object data="..." style="pointer-events: none;" />
</a>

Voir http://www.noupe.com/tutorial/svg-clickable-71346.html pour des solutions supplémentaires.

Feuermurmel
la source
3
Merci, j'avais besoin de l'affichage réglé sur blockou inline-blocksur le parent <a>.
element119
Bon lien: noupe.com/inspiration/tutorials-inspiration/… a des avantages et des inconvénients pour chaque solution.
Serge Stroobandt
J'avais également besoin d'utiliser inline-blockdans certains cas, mais blocksemblait bien fonctionner sur d'autres cas; Je suppose que cela dépend des blocs englobants ...
Gwyneth Llewelyn
9

Pour ce faire dans tous les navigateurs, vous devez utiliser une combinaison des méthodes @energee, @Richard et @Feuermurmel.

<a href="" style="display: block; z-index: 1;">
    <object data="" style="z-index: -1; pointer-events: none;" />
</a>

Ajouter:

  • pointer-events: none; le fait fonctionner dans Firefox.
  • display: block; le fait fonctionner dans Chrome et Safari.
  • z-index: 1; z-index: -1; le fait également fonctionner dans IE.
ChristopherStrydom
la source
@janaspage Je ne suis pas sûr ... Je ne l'ai pas essayé sur IE 10. Faites-moi savoir si cela fonctionne :)
ChristopherStrydom
@jaepage Cela ne devrait pas avoir d'importance, car il objectsera maintenant dans un contexte d'empilement inférieur (sous) à celui de son parent.
Jason T Featheringham le
cela fonctionne-t-il sur un iPhone / mobile? pas pour moi. pas cliquable / tapable
bafromca
3

J'ai également résolu ce problème en modifiant le fichier svg.

J'ai enveloppé le xml de tout le graphique svg dans une balise de groupe contenant un événement de clic comme suit:

<svg .....>
<g id="thefix" onclick="window.top.location.href='http://www.google.com/';">
 <!-- ... your graphics ... -->
</g>
</svg>

La solution fonctionne dans tous les navigateurs prenant en charge le script svg objet. (par défaut, une balise img à l'intérieur de votre élément objet pour les navigateurs qui ne prennent pas en charge svg et vous couvrirez la gamme des navigateurs)

Bruce Pezzlo
la source
Avez-vous trouvé que l'ajout de onclick à l' <svg>élément externe et ne pas l'envelopper du tout ne fonctionnait pas?
Robert Longson
1
Vous pouvez également utiliser les événements de l'élément racine svg. en plus des événements onclick, j'utilise onmouseout, ontouchstart, ontouchend etc ... et comme pour l'élément racine svg, j'utilise fréquemment l'événement onload. La solution Ben Frain ci-dessous consiste à dessiner un objet de couverture supplémentaire (un rectangle) pour capturer les événements de clic ... j'ai donc proposé cette solution montrant l'obtention d'événements sur les éléments de dessin eux-mêmes sans avoir à créer une couverture transparente juste pour obtenir un événement de clic. Particulièrement utile lorsque vous ne voulez pas dessiner un autre élément ou que vous voulez les événements spécifiques à une forme existante et non un rectangle.
Bruce Pezzlo
3

J'ai essayé cette méthode simple et propre et semble fonctionner dans tous les navigateurs. À l'intérieur du fichier svg:

<svg>
<a id="anchor" xlink:href="http://www.google.com" target="_top">
  
<!--your graphic-->
  
</a>
</svg>
  

Dario Rigon
la source
L'espace de noms 'xlink' suivant devra être ajouté à l'élément svg pour que cela fonctionne: xmlns: xlink = " w3.org/1999/xlink "
Développement simple
Aucune des autres solutions n'a fonctionné pour moi, mais celle-ci a fonctionné, ouf, merci!
ByteMyPixel
Bien que je n'ai généralement aucun scrupule à changer directement un fichier SVG, dans mon scénario, j'utilise le même SVG pour plusieurs liens différents - ce qui signifie que théoriquement, je devrais créer un SVG différent pour chacun. Alternativement, bien sûr, je pourrais ajouter le bit graphique en ligne dans la balise <svg>, mais je déteste le code en double (même si le SVG réel que j'ai est petit ...)
Gwyneth Llewelyn
0

Ne l'utilisez pas <object>. Voici une solution qui a fonctionné pour moi avec <a>et les <svg>balises:

<a href="<your-link>" class="mr-5 p-1 border-2 border-transparent text-gray-400 rounded-full hover:text-white focus:outline-none focus:text-white focus:bg-red-700 transition duration-150 ease-in-out" aria-label="Notifications">
    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="30" 
    height="30"><path class="heroicon-ui" fill="#fff" d="M17 16a3 3 0 1 1-2.83 
    2H9.83a3 3 0 1 1-5.62-.1A3 3 0 0 1 5 12V4H3a1 1 0 1 1 0-2h3a1 1 0 0 1 1 
    1v1h14a1 1 0 0 1 .9 1.45l-4 8a1 1 0 0 1-.9.55H5a1 1 0 0 0 0 2h12zM7 12h9.38l3- 
   6H7v6zm0 8a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm10 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/>
    </svg>
</a>
Ege Hurturk
la source
btw j'utilise tailwind css.
Ege Hurturk le
-5

Faites-le avec javascript et ajoutez un onClick-attribut à votre object-element:

<object data="mysvg.svg" type="image/svg+xml" onClick="window.location.href='http://google.at';">
    <span>Your browser doesn't support SVG images</span>
</object>
Stefan Fandler
la source
J'ai essayé ceci, à la fois avec et sans les balises <a> environnantes, et je n'arrive pas à faire fonctionner cela. J'ai essayé FF et Chrome sous Linux. Dans quel navigateur avez-vous essayé cela?
iancoleman
6
Ce serait formidable si vous pouviez l'essayer et confirmer que cela fonctionne afin que les autres personnes qui lisent ceci puissent avoir confiance en votre réponse. «Cela doit fonctionner» est bien en théorie, mais pour moi, cela doit fonctionner dans la pratique.
iancoleman
Je viens d'essayer ceci sur Chrome 45 sous Windows et cela semble fonctionner correctement. J'ai ajouté onClick directement à une balise SVG sans ancre d'encapsulation. Ce serait bien si les votes négatifs expliquaient pourquoi.
Chase