css - manipulation - svg web
Cómo usar SVG Sprite Sheet como imagen de fondo de CSS mientras se mantiene la relación de aspecto y la escalabilidad (2)
TL; DR: Quiero usar varios íconos embaldosados en una hoja de sprite SVG como imágenes de fondo CSS, que mantienen su relación de aspecto y escala automáticamente para llenar el elemento padre, usando nada más que SVG y CSS. Sin JavaScript por favor.
Así que tengo una hoja de sprites en formato SVG, que hice con una combinación de SVG-Edit y una codificación manual en Notepad ++. Aquí está el código fuente:
<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>
Funciona bien y se ve como yo quiero.
El problema es el CSS. Definir las celdas en la hoja de sprites es un poco más desordenado de lo que me gustaría que fuera. Aquí está la página en la que estoy mostrando estos íconos:
<!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>
Básicamente, quiero saber si hay una manera más fácil de definir las celdas en la hoja de sprites y simplificar el CSS que uso para decirle a cada div qué icono mostrar de la hoja de sprites.
Preferiría que esta solución sea estrictamente SVG y CSS; No estoy interesado en usar bibliotecas de JavaScript. Mi objetivo es llegar a un punto en el que simplemente pueda definir las celdas y tener el ícono particular que pretendo escalar automáticamente para que se ajuste a su contenedor, mientras se mantiene su relación de aspecto. Actualmente, para que el icono se ajuste a su contenedor primario, su ancho y alto deben definirse explícitamente, y debe coincidir con el ancho y la altura del contenedor primario. Si cambio el ancho y la altura del contenedor principal, también necesito cambiar los tamaños de la posición de fondo.
Luego, está el problema de escalar. Con esta configuración, el SVG se adapta al tamaño apropiado para dibujarse en la pantalla, pero si decido hacer zoom con el zoom de mi navegador, se pixela. No es así como se supone que SVG funciona.
Supongo que podría poner cada icono en su propio archivo, porque parece funcionar maravillosamente, pero realmente me gusta usar sprites; no solo me ahorra varias solicitudes de servidor, es simplemente genial.
Estoy al tanto de SVG Icon Loader . Es genial, pero es un archivo JavaScript más en el que prefiero no confiar.
Ya he leído los documentos de w3 SVG, los documentos de MDN SVG y los siguientes temas en SO:
Ajuste <svg> al tamaño del contenedor <objeto>
... pero incluso después de todo eso, no he logrado encontrar una solución.
EDITAR: Olvidé mencionar, esto necesita funcionar en IE9. Eso es un problema, estoy seguro, pero el soporte SVG de IE9 es bueno, por lo que elegí SVG para este proyecto.
Básicamente, quiero saber si hay una manera más fácil de definir las celdas en la hoja de sprites y simplificar el CSS que uso para decirle a cada div qué icono mostrar de la hoja de sprites.
No, no puedes hacerlo más fácil.
Prueba este artículo
Luego, está el problema de escalar. Con esta configuración, el SVG se adapta al tamaño apropiado para dibujarse en la pantalla, pero si decido hacer zoom con el zoom de mi navegador, se pixela. No es así como se supone que SVG funciona.
En Chromium 18 se ve bastante bien, sin pixelaciones en absoluto.
En mi lista de navegadores de prueba (FF3.6 Opera 9.2 IE6) no vi lo que vi en Chromium
Y sobre IE9, tal vez problema en el engine
Si sus iconos tienen el mismo tamaño, puede hacer lo siguiente:
- Embale sus iconos en sprite horizontalmente (use svg-sprite si los iconos están en archivos separados).
- Establecer
background-size: auto 100%;
para su selector de destino - Establezca el
width
, laheight
ofont-size
defont-size
los elementos de destino para la escala.
.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>