样式相同的SVG <object>不同的方式

时间:2016-01-20 14:05:42

标签: html css image svg

我希望在不同颜色的页面上有一系列相同的SVG文件。我知道将SVG放入页面而不会使代码膨胀,并且仍具有外部样式的最佳方法是通过<object>标记。

这是我到目前为止所拥有的:

HTML

<object type="image/svg+xml" data="images/circle.svg" class="object-circle red" >
    <!-- fallback image in CSS -->
</object>

<object type="image/svg+xml" data="images/circle.svg" class="object-circle blue" >
    <!-- fallback image in CSS -->
</object>

CSS

.object-circle {
    height:16px;
    width:16px;
}

.red .svg-circle {
    fill:#f00;
}
.blue .svg-circle {
    fill:#00f;
}

SVG

<?xml-stylesheet type="text/css" href="styles.css" ?>
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
  <defs>
    <style>
      .svg-circle {
        fill-rule: evenodd;
      }
    </style>
  </defs>
  <path class="svg-circle" d="M200,398.688A199.552,199. ..."/>
</svg>

这不能正常工作。我认为定位<object>标记来操纵CSS中的SVG fill属性存在问题。

.red选择器从样式表中取出并将.svg-circle选择器保留在原位 - 按预期工作 - 将圆圈变为红色,但我希望能够在页面上使用不同颜色的几个

非常感谢任何帮助!

如果我不能解决这个问题,我可能会选择一个老式的.png精灵表。

4 个答案:

答案 0 :(得分:3)

请参阅https://css-tricks.com/using-svg/,“将SVG用作<object>”部分:

  

[...]如果你想让CSS的东西工作,你不能在文档上使用外部样式表或<style>,你需要在SVG文件中使用<style>元素本身。

因此似乎无法通过CSS在对象“外部”object内部设置SVG元素的样式。

答案 1 :(得分:2)

正如CBroe所说,它是造型外部对象的问题。您可以通过JS访问它并更改它,但我怀疑这是理想的,并且确保首先加载等问题。

但是,我不相信这一定是你说的最好的方法,除非有其他一些要求(例如没有javascript或libs,它必须是外部的,你仍然可以通过Snap加载方法加载它,例如然后,如果你支持js)。

您可以简单地使用defs / use语句。为了简洁起见,我刚刚使用了一个圆圈,但你可以拥有更复杂的路径或其他任何东西。

jsfiddle

<svg xmlns="http://www.w3.org/2000/svg" width="400" height="400" viewBox="0 0 400 400">
  <defs>
    <style>
      .svg-circle {
        fill-rule: evenodd;
        fill: 'red';
      }
    </style>
    <circle id="myDefsCircle" class="svg-circle" r="20" cx="100" cy="100"/>
  </defs>

   <use x="10" y="0"   xlink:href="#myDefsCircle" style="fill:red"/>
   <use x="10" y="50"  xlink:href="#myDefsCircle" style="fill:blue"/>
   <use x="10" y="100" xlink:href="#myDefsCircle" style="fill:green"/>
</svg>

答案 2 :(得分:0)

我处在同样的困境中,但是意识到按照当前规范,这是完全不可能的,因为SVG文档与主框架(类似于this answer)位于与主文档分开的自己的DOM中。但是,这并不意味着我们暂时无法绕过这一限制。

由于SVG文件是纯文本文件,因此我想出了为什么不使用JavaScript渲染它的原因(因为该问题未明确指出不能使用JS)。以上面的SVG圆为例,该函数将如下所示:

// Render an SVG circle
// optional oStyles = { selector: style [, ...] }
function renderCircle(oStyles) {
  var sId = ('svg-'+performance.now()).replace('.', ''),
    sCss = '',
    sSel;
  if (!oStyles) oStyles = {};
  for (var i in oStyles) {
    // Handle group of selectors
    sSel = '';
    i.split(/ *, */).forEach(function(s) {
      sSel += '#' + sId + ' ' + s + ',';
    });
    sSel = sSel.slice(0, -1);
    sCss += sSel + '{' + oStyles[i] + '}';
  }
  return '' +
    '<svg xmlns="http://www.w3.org/2000/svg" id="' + sId + '" width="40" height="40" viewBox="0 0 40 40">' +
      '<style type="text/css">' +
      '<![CDATA[' +
      // Default styles
      '#' + sId + ' .svg-circle { fill: red; }' +
      // Overrides
      sCss +
      ']]>' +
      '</style>' +
      '<circle class="svg-circle" r="20" cx="20" cy="20"/>' +
    '</svg>';
}

document.getElementById('canvas').innerHTML = renderCircle();
document.getElementById('canvas').innerHTML += renderCircle({'.svg-circle':'fill:blue'});
<div id="canvas"></div>

这对于像徽标这样的一次性图像来说还可以,但是如果您有一堆SVG图标,则应该考虑使用SVG图标字体或SVG精灵。一般而言,这是为网络实现SVG的良好指南:

https://svgontheweb.com/

答案 3 :(得分:0)


document.addEventListener("DOMContentLoaded", function() {
  //attribute name
  const ATTR_NAME = "data-src";
  //base64 encoded brocken image icon
  const ERROR_PLACEHOLDER =
    "<img src='data:image/gif;base64,R0lGODlhEQATAPcAAFKyOVGxOlOxPFSyPFSzPFSyPVSyPlWyPlWyP16kTViyRFmzRVm0RV+1T2GlUGKmUWG2U2K0VGO2V2e6UmW3Wm27X3C/XWyrYHKsaXW7ZHqwbHe7dnTAYnfBcH3EcISGhIWGhIWGhYeFh4aGhoeGh4aIhY6NjpORlJOSlJSSlJSSlZWTlZiYl5qYmpuZm5ubnp6cn5+dn4SqgIqqi56eoaGfoaGhoaKho6Kio6Oio6OhpKKipKShpKSjpKSipaSjpaajpqSlqqilqKmoqaysrL+/v4TEhY/DnpLEpJTEp5vLqaXGsaDJta3FvaXKvafKv7zhs8HjuMHjucfmv8bnv6jLwrDNz7zbyrXP17bO27jP3b3V373R5MfHyMnIycrJy8rKys3MzcTL38LP3MfO3cvR3tTW09DQ1NXV19TU2dDU39jY2dra29nd2N3d397e38rlx9jr2sfQ4cjQ4czT4crT58/X58HT6cLT6sTU6MPR7cPT7MPT7cTT78vV6dba49Tc7MXT8MXT8cbU8cbU8sfU8sbV8sfV8sfU88jW8snX88rY88vY88zZ8svY9MzZ9Mza9M3a9c3b9c7b9c3b9s7b9s/c9tDc8tPe9dPf9tDd+NHe+NPf+NLf+dvg6tvi8dXh+Nbi+Nbi+dfi+djj+drk+eDg4OHg4OHh5+Xl5uLi6Orq6uzs7OTn8eXp8ers9OHq++Tr+uXs+Obs++ft++fu++Tr/OTs/OXs/Ofu/enu+eju++jv++jv/enw/O3y/fT09Pb79PP3//r6+vr6+/v9+/r7/Pn7/vv8/vz8/Pz8/f3//P7//fz9/v79//3+//7+//7//////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAARABMAAAj+AGsAEUKwIEEeLdwQk8YwxxlVqCJKVJXGBZE3yhr+6YULly1bt3Dl8gTDS5c1GXHQIcVpVC1epVraobHKFBg2xnDI6cQp1jNpu0BtqvMizKkiQ9DoFDUrGkNptDT5CaLjh48YKXT6Ooasa7NYjy59auXqVZoVOkFlWrt2kiNLoUqVgqVmxQ45lQwZOsT3UCJFixgx4kTmxF1KgxIPIsRY8SBJgL7clZSYECI+d/YUIjRIEKZf0u5GGtSHixUnTJ5gwROokSyGdyHp0ZIkggIGDTZUyaMLWjJgsbMggYBgQIEDCyrEcSYtVQ8cc7YckXCggAEDAiZMCSZNWBkUN8ZKKKEw4LqBABakFJMG54oYFTaWdABAoH4ADlCkLaPiwUgTFCzIcIEDBD6QQRTSDNOGBglgMIMJIowQwgcUlmAGM9KwksKEIZAgQkAAOw==' >";
  let target = document.querySelectorAll(`[${ATTR_NAME}]`);
  //unsorted list
  let _filesList = [];
  target.forEach(function(item) {
    _filesList.push(item.getAttribute(ATTR_NAME).replace(/\\/g, "/"));
  });
  //sorted list
  let filesList = _filesList.filter(function(item, pos) {
    return _filesList.indexOf(item) == pos;
  });
  //ajax request
  filesList.forEach(function(item) {
    let ajax = new XMLHttpRequest();
    ajax.open("GET", item, true);

    ajax.onload = function() {
      document.querySelectorAll(`[${ATTR_NAME}="${item}"]`).forEach(item => {
        if (this.status >= 200 && this.status < 400) {
          // Success!
          item.innerHTML = this.response;
        } else {
          // Error!
          item.innerHTML = ERROR_PLACEHOLDER;
        }
      });
    };

    ajax.send();
  });
});
<div class="icon" data-src="icon.svg">
.icon path{
  fill:#000;
}