我希望在不同颜色的页面上有一系列相同的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精灵表。
答案 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语句。为了简洁起见,我刚刚使用了一个圆圈,但你可以拥有更复杂的路径或其他任何东西。
<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的良好指南:
答案 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;
}