css - 如何在保持宽高比和可伸缩性的同时使用 SVG Sprite Sheet 作为 CSS 背景图像

标签 css svg

TL;DR:我想使用 SVG Sprite 表中平铺的几个图标作为 CSS 背景图像,它们保持纵横比并自动缩放以填充父元素,只使用 SVG 和 CSS。请不要使用 JavaScript。


所以我有一个 SVG 格式的 spritesheet,我用 SVG-Edit 的组合制作的和一些在 Notepad++ 中的手工编码。这是源代码:

<svg version="1.1"
  xmlns:svg="http://www.w3.org/2000/svg"
  xmlns="http://www.w3.org/2000/svg"
  width="600"
  height="400"
  viewBox="0 0 600 400">
  <!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
  <title>chosen_sprite</title>
  <g>
    <title>Add</title>
    <rect fill="none" stroke-width="10" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x="5" y="5" width="90" height="90" id="svg_1" stroke="#dcdcdc"/>
    <line id="svg_2" y2="50" x2="70" y1="50" x1="30" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#00a00c" fill="none"/>
    <line id="svg_3" y2="30" x2="50" y1="70" x1="50" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#00a00c" fill="none"/>
  </g>
  <g>
    <title>Delete</title>
    <rect fill="none" stroke-width="10" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x="105" y="5" width="90" height="90" id="svg_1" stroke="#dcdcdc"/>
    <line id="svg_2" y2="70" x2="170" y1="30" x1="130" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#ff0000" fill="none"/>
    <line id="svg_3" y2="30" x2="170" y1="70" x1="130" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#ff0000" fill="none"/>
  </g>
  <g>
    <title>Expand Dark</title>
    <rect stroke="#505050" id="svg_1" height="90" width="90" y="5" x="205" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="10" fill="none"/>
    <line fill="none" stroke="#000000" stroke-width="12" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="round" x1="250" y1="65" x2="280" y2="35" id="svg_2"/>
    <line fill="none" stroke="#000000" stroke-width="12" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="round" x1="220" y1="35" x2="250" y2="65" id="svg_3"/>
  </g>
  <g>
    <title>Collapse Dark</title>
    <rect stroke="#505050" height="90" width="90" y="5" x="305" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="10" fill="none" id="svg_4"/>
    <line fill="none" stroke="#000000" stroke-width="12" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="round" x1="350" y1="35" x2="380" y2="65" id="svg_5"/>
    <line fill="none" stroke="#000000" stroke-width="12" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="round" x1="320" y1="65" x2="350" y2="35" id="svg_6"/>
  </g>
  <g>
    <title>Expand Green</title>
    <rect fill="none" stroke-width="10" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x="405" y="5" width="90" height="90" id="svg_1" stroke="#dcdcdc"/>
    <line id="svg_2" y2="35" x2="480" y1="65" x1="450" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#00a00c" fill="none"/>
    <line id="svg_3" y2="65" x2="450" y1="35" x1="420" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#00a00c" fill="none"/>
  </g>
  <g>
    <title>Collapse Green</title>
    <rect fill="none" stroke-width="10" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x="505" y="5" width="90" height="90" id="svg_1" stroke="#dcdcdc"/>
    <line id="svg_2" y2="65" x2="580" y1="35" x1="550" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#00a00c" fill="none"/>
    <line id="svg_3" y2="35" x2="550" y1="65" x1="520" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#00a00c" fill="none"/>
  </g>
  <g>
    <title>Search</title>
    <circle id="svg_9" r="32" cy="140" cx="60" stroke-width="8" stroke="#000000" fill="none"/>
    <line id="svg_11" y2="167.5" x2="32.5" y1="190" x1="10" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#000000" fill="none"/>
  </g>
  <g>
    <title>Search 2</title>
    <rect id="svg_10" stroke="#505050" height="90" width="90" y="105" x="105" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="10" fill="none"/>
    <circle r="25" cy="142.5" cx="157.5" stroke-width="8" stroke="#000000" fill="none" id="svg_7"/>
    <line y2="165" x2="135" y1="180" x1="120" stroke-linecap="round" stroke-linejoin="null" stroke-dasharray="null" stroke-width="12" stroke="#000000" fill="none" id="svg_8"/>
  </g>
</svg>

它工作正常,看起来像我想要的那样。

问题出在 CSS 上。在 spritesheet 中定义单元格比我希望的要复杂一些。这是我在其中显示这些图标的页面:

<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<html>
<head>
<style>

* {padding: 0px; margin: 0px; outline: 1px solid rgba(0,0,0,0.1);}

html {width: 100%; height: 100%;}

body {width: 100%; height: 100%;}

.svgSprite {
    background-image: url('./svgicons/form_icons_sprite.svg');
    background-repeat: no-repeat;
    background-size: 600%;
}

.svgSprite.add {
    background-position: 0px 0px;
    width: 12px;
    height: 12px;
}

.svgSprite.delete {
    background-position: -16px 0px;
    width: 16px;
    height: 16px;
}

.svgSprite.expandDark {
    background-position: -24px 0px;
    width: 12px;
    height: 12px;
}

.svgSprite.collapseDark {
    background-position: -36px 0px;
    width: 12px;
    height: 12px;
}

.svgSprite.expandGreen {
    background-position: -48px 0px;
    width: 12px;
    height: 12px;
}

.svgSprite.collapseGreen {
    background-position: -60px 0px;
    width: 12px;
    height: 12px;
}

.svgSprite.search {
    background-position: 0px -12px;
    width: 12px;
    height: 12px;
}

.svgSprite.search2 {
    background-position: -16px -16px;
    width: 16px;
    height: 16px;
}

</style>
</head>

<body>
<div class="svgSprite add"></div>
<div class="svgSprite delete"></div>
<div class="svgSprite expandDark"></div>
<div class="svgSprite collapseDark"></div>
<div class="svgSprite expandGreen"></div>
<div class="svgSprite collapseGreen"></div>
<div class="svgSprite search"></div>
<div class="svgSprite search2"></div>
</body>

</html>

基本上,我想知道是否有更简单的方法来定义 spritesheet 中的单元格并简化我用来告诉每个 div 从 spritesheet 显示哪个图标的 CSS。

我更希望这个解决方案是严格的 SVG 和 CSS;我对使用 JavaScript 库不感兴趣。我的目标是让它达到这样的程度,我可以简单地定义单元格并拥有我想要自动缩放以适合其容器的特定图标,同时保持其纵横比。目前,为了使图标适合其父容器,需要显式定义其宽度和高度,并匹配父容器的宽度和高度。如果我更改父容器的宽度和高度,我也需要更改背景位置的大小。

然后是扩展问题。通过此设置,SVG 可以缩放到适合在屏幕上绘制的大小,但如果我决定使用浏览器的缩放功能进行缩放,它就会像素化。这不是 SVG 应有的工作方式。

我想我可以将每个图标放在自己的文件中,因为这看起来效果很好,但我真的很喜欢使用 sprite;它不仅为我节省了几个服务器请求,而且非常酷。

我知道 SVG Icon Loader .它非常酷,但它又是一个我不想依赖的 JavaScript 文件。

我已经阅读了 w3 SVG 文档、MDN SVG 文档以及关于 SO 的以下主题:

SVG & Spritesheets

Fit <svg> to the size of <object> container

Using SVG as background image

...但即便如此,我仍未设法找到解决方案。

编辑:我忘了说,这需要在 IE9 中工作。这有点问题,我敢肯定,但 IE9 的 SVG 支持很不错,这就是我为这个元素选择 SVG 的原因。

最佳答案

如果您的图标大小相同,您可以执行以下操作:

  1. 将图标水平打包到 sprite 中(如果图标位于单独的文件中,请使用 svg-sprite)。
  2. 为您的目标选择器设置 background-size: auto 100%;
  3. 设置目标元素的widthheightfont-size 以进行缩放。

.icon {
    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="64" height="16" viewBox="0 0 64 16"> <circle fill="blue" cx="8" cy="8" r="8"/> <circle fill="red" cx="24" cy="8" r="8"/> <circle fill="yellow" cx="40" cy="8" r="8"/> <circle fill="green" cx="56" cy="8" r="8"/> </svg>');
    background-repeat: no-repeat;
    background-size: auto 100%;
    display: inline-block;
}
.icon.small {
    height: 1em;
    width: 1em;
}
.icon.medium {
    height: 2em;
    width: 2em;
}
.icon.large {
    height: 4em;
    width: 4em;
}
.icon_1 {
    background-position: 0 0;
}
.icon_2 {
    background-position: 33.33% 0;
}
.icon_3 {
    background-position: 66.67% 0;
}
.icon_4 {
    background-position: 100% 0;
}
<span class="icon icon_1 small"></span>
<span class="icon icon_1 medium"></span>
<span class="icon icon_2 large"></span>

关于css - 如何在保持宽高比和可伸缩性的同时使用 SVG Sprite Sheet 作为 CSS 背景图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10956636/

相关文章:

css - 菜单中的下划线过渡

javascript - 当它到达第四个选项卡时,它不应该转到第一个选项卡

html - CSS - 如何水平对齐我的 div?

javascript - 如何正确缩放 d3 图表?

css - 在一个规则中使用多个类的目标元素

html - 如何: Non collapsing navigation items Bootstrap 3

reactjs - 在 ReactJS 中包含 SVG 的正确方法是什么?

svg - 将 clipPath 应用于转换后的 g 元素

image - 较大的 SVG 比较小的 SVG 质量更好?

html - 固定 SVG 高度和可变 (100%) 宽度