开发者

Positioning SVG elements using CSS

开发者 https://www.devze.com 2022-12-18 19:51 出处:网络
Assume the following svg document: <svg version=\"1.1\" baseProfile=\"full\" width=\"300\" height=\"200\" xmlns=\"http://www.w3.org/2000/svg\">

Assume the following svg document:

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

Now what i want to do is reposition this text using css.

I have tried adding style="dx:20" and style="transform: translate(20)". Both have no effect in firefox and safari. Adding these as norm开发者_开发问答al attributes works fine but then i can't split the positioning from the actual code. Setting x, y, left and top in the style isn't working either.

Is there a way to position an svg element using css?


I've managed to move some SVG text in chrome using the following CSS:

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

However, it's not budging in Firefox...


I came here looking for a fix but fixed the issue myself, thought I would share:

transform: translate(100px, 100px)

Appears to work in all modern browsers except for Internet Explorer, right up until Microsoft Edge (which isn't even out yet) which is quite disappointing. The elements I've tested on are:

<path>
<polygon>
<g>

The only issue I've had is with <text> elements, and the solution there is to wrap the <text> in a <g> and apply the transformation to that. That should also work for any elements I haven't yet tested that have issues with transform: translate().

I haven't found a decent fallback for Internet Explorer, instead I've made sure that the transforms aren't vital to the function of the SVG.


Here is a hacky possibility to position specifically text-elements purely by CSS, by abusing the attributes ‘letter-spacing’ for the x-coordinate and ‘baseline-shift’ for the y-coordinate:

<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’ is only applicable on ‘tspan’ Elements, thus making the inner <tspan> necessary in the presented code. Positive values for baseline-shift move the text upwards, opposite of the normal direction in the svg.

‘letter-spacing’ needs an initial letter to have an effect, thus making the . necessary. To eliminate the width of this first letter, we use the special made font cssPosAnchor, where the dot has no width and no shape. The following <tspan> additionally restores font and letter-spacing.

Scope

Should work in every conforming SVG implementation.

There is one indefinite limitation though for negative x-coordinates. The specification for the ‘letter-spacing’ attribute says: “Values may be negative, but there may be implementation-specific limits.”

Compatibility

Text ‘direction’ change should work just fine, when imposed on the inner <tspan>.

A non-standard ‘writing-mode’ must be imposed on the outer <text>. There will most certainly be problems with that.

The probably more important ‘text-anchor’ values middle and end can be made possible like this:

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

The ‹space›. before the closing <\text> tag produces spacing equal to minus x-coordinate. So the inner <tspan> is moved around but preserves it's space in the <text> as if it was still there.

Since there may be implementation-specific limits on negative values for the spacing attributes, this is not guaranteed to work on all clients!


At the moment, it seems -according to Shelley Powers, in her A List Apart Article "Using SVG for Flexible, Scalable and Fun Backgrounds: Part I" and "Part II"- that CSS is not currently best-suited to positioning of SVG. In fact it seems to be quite a minefield to incorporate SVG into a web-page, without directly embedding it within the html itself.

I hope that there are solutions to be found, and, indeed, Powers does offer a couple of workarounds, to enable proper separation of style and content for SVG. I'd hazard a guess that the current problems are the relative new-ness of the concept/standard (relative to, for example, .gif or even .png...), sadly.

I'm sorry I can't offer a better answer. =/


Use css positioning:

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


polygon 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:nonzero;"

if you want to move the star then add to 10 or more in points like points="33,20 25,37 44,26 20,26 41,37"


I warn you i'm a relative beginner but what about "x" and "y" and assigning these with number and "px"

maybe:

left: 290px;    top: 1200px;

or

x:30px; y:50px;

and

text-anchor:start;

Sample:

<text
       xml:space="preserve"
       style="font-size:32;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Comic Sans MS;-inkscape-font-specification:Comic Sans MS Bold"
       x="131.42857"
       y="269.50504"
       id="text2383"
       sodipodi:linespacing="125%"><tspan
         sodipodi:role="line"
         id="tspan2385"
         x="131.42857"
         y="269.50504">Position ze text</tspan></text>
0

精彩评论

暂无评论...
验证码 换一张
取 消