web-dev-qa-db-fra.com

Positionnement des éléments SVG à l'aide de CSS

Supposons le document svg suivant:

<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">
<text x="20" y="20">My text</text>
</svg>

Maintenant, ce que je veux faire, c'est repositionner ce texte en utilisant CSS.

J'ai essayé d'ajouter style="dx:20" Et style="transform: translate(20)". Les deux n'ont aucun effet dans Firefox et Safari. L'ajout de ceux-ci en tant qu'attributs normaux fonctionne bien, mais je ne peux pas séparer le positionnement du code réel. La définition de x, y, left et top dans le style ne fonctionne pas non plus.

Existe-t-il un moyen de positionner un élément svg en utilisant css?

36
Yorick Sijsling

J'ai réussi à déplacer du texte SVG dans chrome en utilisant le CSS suivant:

text.identity{
transform: translate(74px,0px);
-ms-transform: translate(74px,0px); /* IE 9 */
-webkit-transform: translate(74px,0px); /* Safari and Chrome */
-o-transform: translate(74px,0px); /* Opera */
-moz-transform: translate(74px,0px); /* Firefox */
}

Mais ça ne bouge pas dans Firefox ...

29
pluke

Je suis venu ici à la recherche d'un correctif mais j'ai résolu le problème moi-même, pensant partager:

transform: translate(100px, 100px)

Semble fonctionner dans tous les navigateurs modernes à l'exception d'Internet Explorer, jusqu'à Microsoft Edge (qui n'est même pas encore sorti), ce qui est assez décevant. Les éléments sur lesquels j'ai testé sont:

<path>
<polygon>
<g>

Le seul problème que j'ai rencontré concerne les éléments <text>, Et la solution consiste à encapsuler le <text> Dans un <g> Et à y appliquer la transformation. Cela devrait également fonctionner pour tous les éléments que je n'ai pas encore testés et qui ont des problèmes avec transform: translate().

Je n'ai pas trouvé de solution de rechange décente pour Internet Explorer, au lieu de cela, je me suis assuré que les transformations ne sont pas vitales pour la fonction du SVG.

21
ryanpither

Voici une possibilité hacky de positionner spécifiquement des éléments de texte purement par CSS, en abusant des attributs 'letter-spacing' for la coordonnée x et 'baseline-shift' pour la coordonnée y:

<defs>
    <font><font-face font-family="cssPosAnchor" />
        <glyph unicode="." horiz-adv-x="0" />
    </font>
    <style type="text/css"><![CDATA[
#cssPos {
    font-family:cssPosAnchor;
    letter-spacing:10px; /* x-coordinate */
}
#cssPos>tspan {
    font-family:serif;
    letter-spacing:normal;
    baseline-shift:-30px; /* negative y-coordinate */
}
]]>
    </style>
</defs>
<text id="cssPos">.<tspan>CSS-Positioned Text!</tspan></text>

'baseline-shift' n'est applicable que sur 'tspan' Elements, rendant ainsi le <tspan> intérieur nécessaire dans le code présenté. Les valeurs positives pour le décalage de ligne de base déplacent le texte vers le haut, à l'opposé de la direction normale dans le svg.

L’espacement des lettres a besoin d’une lettre initiale pour avoir un effet, rendant ainsi le . Nécessaire. Pour éliminer la largeur de cette première lettre, nous utilisons la police spéciale faite cssPosAnchor, où le point n'a ni largeur ni forme. Le <tspan> Suivant restaure également la police et l'espacement des lettres.

Portée

Devrait fonctionner dans chaque implémentation SVG conforme.

Il existe cependant une limitation indéfinie pour les coordonnées x négatives. La spécification de l'attribut "espacement des lettres" indique: "Les valeurs peuvent être négatives, mais il peut y avoir des limites spécifiques à l'implémentation."

Compatibilité

Le changement de texte ‘direction’ devrait très bien fonctionner, une fois imposé au <tspan> Intérieur.

Un "mode d’écriture" non standard doit être imposé sur le <text> Extérieur. Il y aura très certainement des problèmes avec cela.

Les valeurs probablement les plus importantes 'text-anchor' middle and end peut être rendu possible comme ceci:

<defs>
    <font><font-face font-family="cssPosAnchor" />
        <glyph unicode="." horiz-adv-x="0" />
        <glyph unicode=" " horiz-adv-x="0" />
    </font>
    <style type="text/css"><![CDATA[
#cssPos {
    font-family:cssPosAnchor;
    letter-spacing:100px; /* x-coordinate */
    Word-spacing:-200px; /* negative double x-coordinate */
}
#cssPos>tspan {
    font-family:serif;
    Word-spacing:normal;
    letter-spacing:normal;
    baseline-shift:-30px; /* negative y-coordinate */
}
#cssPos {
    text-anchor=middle;
}
]]>
    </style>
</defs>
<text id="cssPos">.<tspan>CSS-Positioned Text!</tspan> .</text>

La balise ‹space›. Avant la balise de fermeture <\text> Produit un espacement égal à la coordonnée x moins. Ainsi, le <tspan> Intérieur est déplacé mais conserve son espace dans le <text> Comme s'il était toujours là.

Puisqu'il peut y avoir des limites spécifiques à l'implémentation sur les valeurs négatives pour les attributs d'espacement, cela ne garantit pas de fonctionner sur tous les clients!

13
Tobias Simon

Pour le moment, il semble -selon Shelley Powers , dans son A List Apart Article " tilisation de SVG pour des arrière-plans flexibles, évolutifs et amusants: Partie I "et" Part II "- que CSS n'est pas actuellement le mieux adapté au positionnement de SVG. En fait, il semble être tout à fait un champ de mines d'incorporer SVG dans une page Web, sans l'intégrer directement dans le html lui-même.

J'espère qu'il y a des solutions à trouver, et, en effet, Powers offre quelques solutions de contournement, pour permettre une séparation correcte du style et du contenu pour SVG. Je suppose que les problèmes actuels sont la nouveauté relative du concept/de la norme (par exemple, par rapport à .gif ou même .png...), Malheureusement.

Je suis désolé, je ne peux pas offrir une meilleure réponse. = /

6
David Thomas

Utilisez le positionnement CSS:

index.html

<link href="style.css" rel="stylesheet" />
<div class="parent">
  <div class="child">
    <svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg"><text x="20" y="20">My text</text>
    </svg>
  </div>
</div>

style.css

.parent {
  position: relative;
  height: 1000; /* bigger than your svg */
  width: 1000; /* bigger than your svg */
}

.child {
  position: absolute;
  top: 10px;  /* relative to parent container */
  left: 10px; /* relative to parent container */
}
2
Isaac Pak

polygone r = "7" id = "map_points_55" points = "23,10 15,27 34,16 10,16 31,27" style = "fill: Lime; stroke: purple; stroke-width: 0; fill-rule : différent de zéro; "

si vous voulez déplacer l'étoile, ajoutez-en 10 ou plus en points comme des points = "33,20 25,37 44,26 20,26 41,37"

0
bhaveshvirani63