如何使用SVG Sprite Sheet作为CSS背景图像,同时保持高宽比和可扩展性 [英] How to use SVG Sprite Sheet as CSS background-image while maintaining aspect ratio and scalability

查看:142
本文介绍了如何使用SVG Sprite Sheet作为CSS背景图像,同时保持高宽比和可扩展性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR:我想使用在SVG精灵表格中平铺的几个图标作为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>
<! - 使用SVG-edit创建 - http://svg-edit.googlecode.com/ - >
< title> selected_sprite< / title>
< g>
< title>添加< / title>
< rect fill =nonestroke-width =10stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =nullx =5y = width =90height =90id =svg_1stroke =#dcdcdc/>
< line id =svg_2y2 =50x2 =70y1 =50x1 =30stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#00a00cfill =none/>
< line id =svg_3y2 =30x2 =50y1 =70x1 =50stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#00a00cfill =none/>
< / g>
< g>
< title>删除< / title>
< rect fill =nonestroke-width =10stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =nullx =105y = width =90height =90id =svg_1stroke =#dcdcdc/>
< line id =svg_2y2 =70x2 =170y1 =30x1 =130stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#ff0000fill =none/>
< line id =svg_3y2 =30x2 =170y1 =70x1 =130stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#ff0000fill =none/>
< / g>
< g>
< title> Expand Dark< / title>
< rect stroke =#505050id =svg_1height =90width =90y =5x =205stroke-linecap =nullstroke-linejoin = NULLstroke-dasharray =nullstroke-width =10fill =none/>
< line fill =nonestroke =#000000stroke-width =12stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =roundx1 =250 y1 =65x2 =280y2 =35id =svg_2/>
< line fill =nonestroke =#000000stroke-width =12stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =roundx1 =220 y1 =35x2 =250y2 =65id =svg_3/>
< / g>
< g>
< title> Collapse Dark< / title>
< rect stroke =#505050height =90width =90y =5x =305stroke-linecap =nullstroke-linejoin =nullstroke-dasharray =nullstroke-width =10fill =noneid =svg_4/>
< line fill =nonestroke =#000000stroke-width =12stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =roundx1 =350 y1 =35x2 =380y2 =65id =svg_5/>
< line fill =nonestroke =#000000stroke-width =12stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =roundx1 =320 y1 =65x2 =350y2 =35id =svg_6/>
< / g>
< g>
< title>展开绿色< / title>
< rect fill =nonestroke-width =10stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =nullx =405y = width =90height =90id =svg_1stroke =#dcdcdc/>
< line id =svg_2y2 =35x2 =480y1 =65x1 =450stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#00a00cfill =none/>
< line id =svg_3y2 =65x2 =450y1 =35x1 =420stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#00a00cfill =none/>
< / g>
< g>
< title> Collapse Green< / title>
< rect fill =nonestroke-width =10stroke-dasharray =nullstroke-linejoin =nullstroke-linecap =nullx =505y = width =90height =90id =svg_1stroke =#dcdcdc/>
< line id =svg_2y2 =65x2 =580y1 =35x1 =550stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#00a00cfill =none/>
< line id =svg_3y2 =35x2 =550y1 =65x1 =520stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#00a00cfill =none/>
< / g>
< g>
< title>搜索< / title>
< circle id =svg_9r =32cy =140cx =60stroke-width =8stroke =#000000fill =none/>
< line id =svg_11y2 =167.5x2 =32.5y1 =190x1 =10stroke-linecap =roundstroke-linejoin =nullstroke-dasharray = nullstroke-width =12stroke =#000000fill =none/>
< / g>
< g>
< title>搜索2< / title>
< rect id =svg_10stroke =#505050height =90width =90y =105x =105stroke-linecap =nullstroke-linejoin = nullstroke-dasharray =nullstroke-width =10fill =none/>
< circle r =25cy =142.5cx =157.5stroke-width =8stroke =#000000fill =noneid =svg_7/>
< line y2 =165x2 =135y1 =180x1 =120stroke-linecap =roundstroke-linejoin =nullstroke-dasharray =null width =12stroke =#000000fill =noneid =svg_8/>
< / g>
< / svg>

它工作正常,看起来我想要的方式。



问题是CSS。在spritesheet中定义单元格比我想要的有点乱。这是在我显示这些图标的页面:

 <!DOCTYPE html> 
< meta http-equiv =Content-Typecontent =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中的单元格, CSS我用来告诉每个div从spritesheet显示哪个图标。



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



然后,有缩放的问题。使用此设置,SVG会缩放到适当的大小以在屏幕上绘制,但如果我决定使用浏览器的缩放进行缩放,它会像素化。这不是SVG应该如何工作。



我想我可以把每个图标放在自己的文件,因为这似乎工作很好,但我只是真的很喜欢使用sprites;它不仅保存了几个服务器请求,只是很酷。



我知道 SVG图标加载器。这是非常酷,但它是一个更多的JavaScript文件,我不想依靠。



我已经读过w3 SVG文档,MDN SVG文档, SO上的以下主题:



SVG& Spritesheets



Fit< svg>到< object>的大小。容器



使用SVG作为背景图片



...但即使如此,我还是没有找到解决方案。



编辑:我忘了提到,这需要在IE9工作。这是一个问题,我敢肯定,但IE9的SVG支持是体面的,这就是为什么我选择SVG为这个项目。

解决方案

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


不,你不能更容易。



尝试这篇文章


然后,有缩放的问题。使用此设置,SVG会缩放到适当的大小以在屏幕上绘制,但如果我决定使用浏览器的缩放进行缩放,它会像素化。这不是SVG应该如何工作。


在Chromium 18它看起来很漂亮 - 没有像素。



在我的测试浏览器列表中(FF3.6 Opera 9.2 IE6)我没有看到我在Chromium中看到的内容



有关IE9,也许是引擎中的问题


TL;DR: I want to use several icons tiled in an SVG sprite sheet as CSS background-images, which maintain their aspect ratio and automatically scale to fill the parent element, using nothing but SVG and CSS. No JavaScript please.


So I have a spritesheet in SVG format, which I made with a combination of SVG-Edit and some hand-coding in Notepad++. Here's the source code:

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

It works fine and looks the way I want it to.

The problem is the CSS. Defining the cells in the spritesheet is a little bit messier than I would like it to be. Here's the page I'm displaying these icons in:

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

Basically, I want to know if there's an easier way to define the cells in the spritesheet and simplify the CSS I use to tell each div which icon to display from the spritesheet.

I would prefer that this solution be strictly SVG and CSS; I am not interested in using JavaScript libraries. I am aiming to get it to a point where I can simply define the cells and have the particular icon I'm aiming for automatically scale to fit its container, while maintaining its aspect ratio. Currently, in order to make the icon fit its parent container, its width and height need to be explicitly defined, and match the width and height of the parent container. If I change the width and height of the parent container, I need to change the background-position sizes as well.

Then, there's the problem of scaling. With this setup, the SVG scales to the appropriate size to be drawn on-screen, but if I decide to zoom using my browser's zoom, it pixelates. This is not how SVG is supposed to work.

I suppose I could just put each icon in its own file, because that seems to work wonderfully, but I just really like using sprites; it not only saves me several server requests, it's just cool.

I am aware of SVG Icon Loader. It's pretty cool, but it's one more JavaScript file that I would rather not rely on.

I've already read the w3 SVG docs, the MDN SVG docs, and the following threads on SO:

SVG & Spritesheets

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

Using SVG as background image

...but even after all that, I haven't managed to find a solution.

EDIT: I forgot to mention, this needs to work in IE9. That's a bit of an issue, I'm sure, but IE9's SVG support is decent, which is why I chose SVG for this project.

解决方案

Basically, I want to know if there's an easier way to define the cells in the spritesheet and simplify the CSS I use to tell each div which icon to display from the spritesheet.

No, you can't do it easier.

Try this article

Then, there's the problem of scaling. With this setup, the SVG scales to the appropriate size to be drawn on-screen, but if I decide to zoom using my browser's zoom, it pixelates. This is not how SVG is supposed to work.

In Chromium 18 it looks pretty fine - no pixelations at all.

In my test browsers list (FF3.6 Opera 9.2 IE6) I didn't see what I saw in Chromium

And about IE9, maybe problem in engine

这篇关于如何使用SVG Sprite Sheet作为CSS背景图像,同时保持高宽比和可扩展性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆