【问题标题】:Positioning SVG elements using CSS使用 CSS 定位 SVG 元素
【发布时间】:2011-01-12 17:29:39
【问题描述】:

假设以下 svg 文档:

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

现在我要做的是使用 css 重新定位此文本。

我尝试添加style="dx:20"style="transform: translate(20)"。两者都对 firefox 和 safari 无效。添加这些作为普通属性可以正常工作,但我无法将定位与实际代码分开。 在样式中设置xylefttop 也不起作用。

有没有办法使用 css 定位 svg 元素?

【问题讨论】:

  • 我想我会使用符号作为一个不错的选择。用户需要手动指定更多,但至少我不必通过我的库代码传递布局内容。
  • 你找到解决这个问题的方法了吗?我希望用 CSS 文档定位我的 SVG,但定位无法正常工作......
  • 不,从未找到解决方案。我认为大卫托马斯的答案是你现在能找到的最好的答案。
  • 你找到解决这个问题的方法了吗?我希望能够响应地定位我的动画 SVG 文本,但是动画不幸地停止了......

标签: css svg


【解决方案1】:

我已经设法使用以下 CSS 在 chrome 中移动了一些 SVG 文本:

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

但是,它在 Firefox 中并没有改变...

【讨论】:

  • 我认为这是我见过的最昂贵的文本移动方式之一
  • 你是对的,但遗憾的是 SVG 和 CSS 结合在一起,正如我们现在所希望的那样。如果您有更快的方法,我很乐意看到它。
  • 从 Firefox 23 开始,-moz-transform 不是必需的; -transform 工作正常!
【解决方案2】:

我来这里是为了寻找解决方案,但我自己解决了这个问题,我想我会分享:

transform: translate(100px, 100px)

似乎可以在除 Internet Explorer 之外的所有现代浏览器中使用,直到 Microsoft Edge(甚至还没有推出),这令人非常失望。我测试过的元素是:

<path>
<polygon>
<g>

我遇到的唯一问题是&lt;text&gt; 元素,解决方案是将&lt;text&gt; 包装在&lt;g&gt; 中并对其应用转换。这也应该适用于我尚未测试的任何与transform: translate() 存在问题的元素。

我还没有找到适合 Internet Explorer 的后备方案,而是确保转换对于 SVG 的功能并不重要。

【讨论】:

  • 这真的救了我,我被难住了几天。谢谢!如果你感到沮丧,试试这个技巧!
  • 这肯定适用于大多数 SVG 元素,但我们正在制作动画的元素除外。翻译这样的元素会阻止其动画。至少在我所有的情况下。
【解决方案3】:

通过滥用属性‘letter-spacing’ 用于x 坐标和‘baseline-shift’ 用于y 坐标,这是一种纯粹通过CSS 专门定位文本元素的骇人可能性:

<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’ 仅适用于 ‘tspan’ 元素,因此在呈现的代码中需要内部 &lt;tspan&gt;。基线移位的正值向上移动文本,与 svg 中的正常方向相反。

‘letter-spacing’ 需要一个首字母才能生效,因此. 是必需的。为了消除第一个字母的宽度,我们使用了特制的字体cssPosAnchor,其中的点没有宽度也没有形状。以下&lt;tspan&gt; 额外恢复字体和字母间距。

范围

应该适用于所有符合标准的 SVG 实现。

虽然对于负 x 坐标有一个无限的限制。 “字母间距”属性的规范说:“值可能是负数,但可能存在特定于实现的限制。”

兼容性

文本'direction'更改应该可以正常工作,当施加在内部&lt;tspan&gt;上时。

必须在外部&lt;text&gt; 上施加非标准的‘writing-mode’。这样做肯定会有问题。

可能更重要的 'text-anchor'middleend 可以这样实现:

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

‹space›. 在结束 &lt;\text&gt; 标记之前产生的间距等于负 x 坐标。所以内部的&lt;tspan&gt; 被移动了,但在&lt;text&gt; 中保留了它的空间,就好像它仍然在那里一样。

由于对间距属性的负值可能存在特定于实现的限制,因此不能保证对所有客户端都有效!

【讨论】:

    【解决方案4】:

    目前,似乎-根据Shelley Powers,在她的A List Apart Article、“Using SVG for Flexible, Scalable and Fun Backgrounds: Part I”和“Part II”中,CSS 目前并不是最适合定位 SVG。事实上,将 SVG 合并到网页中似乎是一个雷区,而不是直接将其嵌入到 html 本身中。

    我希望能找到解决方案,而且确实,Powers 确实提供了一些变通方法,以便正确分离 SVG 的样式和内容。我大胆猜测当前的问题是概念/标准相对较新(例如,相对于.gif 甚至.png...),遗憾的是。

    很抱歉,我无法提供更好的答案。 =/

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

        多边形 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;填充规则:非零;"

        如果您想移动星形,则将点数增加到 10 或更多,例如 points="33,20 25,37 44,26 20,26 41,37"

        【讨论】:

          【解决方案7】:

          我警告你,我是一个相对的初学者,但是“x”和“y”以及用数字和“px”分配它们呢

          也许:

          left: 290px;    top: 1200px;
          

          x:30px; y:50px;
          

          text-anchor:start;
          

          示例:

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

          【讨论】:

          • 谢谢,从没想过要使用 left 和 top。但这些也不起作用。我已经更新了我的问题以包括这些。
          • 添加答案而不检查它是否有效有什么意义? (它没有。)
          猜你喜欢
          • 1970-01-01
          • 2011-02-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-17
          • 2018-01-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多