html - manipulation - Inline SVG en CSS
svg manipulation css (7)
¿Es posible usar una definición SVG en línea en CSS?
Me refiero a algo como:
.my-class {
background-image: <svg>...</svg>;
}
Bifurqué una demostración de CodePen que tuvo el mismo problema con la incorporación de SVG en línea en CSS. Una solución que funciona con SCSS es construir una función simple de codificación de url.
Se puede crear una función de reemplazo de cadena a partir de las funciones incorporadas str-slice, str-index (vea css-tricks , gracias a Hugo Giraudel).
Entonces, simplemente reemplaza %
, <
, >
, "
, ''
, con los códigos
%xx
:
@function svg-inline($string){
$result: str-replace($string, "<svg", "<svg xmlns=''http://www.w3.org/2000/svg''");
$result: str-replace($result, ''%'', ''%25'');
$result: str-replace($result, ''"'', ''%22'');
$result: str-replace($result, "''", ''%27'');
$result: str-replace($result, '' '', ''%20'');
$result: str-replace($result, ''<'', ''%3C'');
$result: str-replace($result, ''>'', ''%3E'');
@return "data:image/svg+xml;utf8," + $result;
}
$mySVG: svg-inline("<svg>...</svg>");
html {
height: 100vh;
background: url($mySVG) 50% no-repeat;
}
También hay una función auxiliar de image-inline
disponible en Compass, pero como no es compatible con CodePen, esta solución probablemente sea útil.
Demostración en CodePen: http://codepen.io/terabaud/details/PZdaJo/
En Mac / Linux, puede convertir fácilmente un archivo SVG a un valor codificado en base64 para el atributo de fondo CSS con este simple comando bash:
echo "background: transparent url(''data:image/svg+xml;base64,"$(openssl base64 < path/to/file.svg)"'') no-repeat center center;"
Probado en Mac OS X. De esta manera también evita que la URL se escape.
Recuerde que la base64 que codifica un archivo SVG aumenta su tamaño, consulte la publicación del blog css-tricks.com .
Encontré una solución para SVG. Pero solo funciona para Webkit, solo quiero compartir mi solución con usted. En mi ejemplo, se muestra cómo utilizar el elemento SVG de DOM como fondo a través de un filtro (background-image: url (''# glyph'') no funciona).
Las características necesarias para este icono SVG se procesan:
- Aplicación de efectos de filtro SVG a elementos HTML usando CSS (IE y Edge no son compatibles)
- Compatibilidad con la carga de fragmentos de feImage (Firefox no es compatible)
.test {
/* background-image: url(''#glyph'');
background-size:100% 100%;*/
filter: url(#image);
height:100px;
width:100px;
}
.test:before {
display:block;
content:'''';
color:transparent;
}
.test2{
width:100px;
height:100px;
}
.test2:before {
display:block;
content:'''';
color:transparent;
filter: url(#image);
height:100px;
width:100px;
}
<svg style="height:0;width:0;" version="1.1" viewbox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="glyph">
<path id="heart" d="M100 34.976c0 8.434-3.635 16.019-9.423 21.274h0.048l-31.25 31.25c-3.125 3.125-6.25 6.25-9.375 6.25s-6.25-3.125-9.375-6.25l-31.202-31.25c-5.788-5.255-9.423-12.84-9.423-21.274 0-15.865 12.861-28.726 28.726-28.726 8.434 0 16.019 3.635 21.274 9.423 5.255-5.788 12.84-9.423 21.274-9.423 15.865 0 28.726 12.861 28.726 28.726z" fill="crimson"/>
</g>
<svg id="resized-glyph" x="0%" y="0%" width="24" height="24" viewBox="0 0 100 100" class="icon shape-codepen">
<use xlink:href="#glyph"></use>
</svg>
<filter id="image">
<feImage xlink:href="#resized-glyph" x="0%" y="0%" width="100%" height="100%" result="res"/>
<feComposite operator="over" in="res" in2="SourceGraphic"/>
</filter>
</defs>
</svg>
<div class="test">
</div>
<div class="test2">
</div>
Una solución más, es utilizar codificar url.
var container = document.querySelector(".container");
var svg = document.querySelector("svg");
var svgText = (new XMLSerializer()).serializeToString(svg);
container.style.backgroundImage = `url(data:image/svg+xml;utf8,${encodeURIComponent(svgText)})`;
.container{
height:50px;
width:250px;
display:block;
background-position: center center;
background-repeat: no-repeat;
background-size: contain;
}
<svg height="100" width="500" xmlns="http://www.w3.org/2000/svg">
<ellipse cx="240" cy="50" rx="220" ry="30" style="fill:yellow" />
</svg>
<div class="container"></div>
Es posible que el SVG en línea proveniente de fuentes de terceros (como los gráficos de Google) no contenga el atributo de espacio de nombres XML ( xmlns="http://www.w3.org/2000/svg"
) en el elemento SVG (o quizás se elimine una vez que se haya procesado el SVG - ni el inspector del navegador ni los comandos de jQuery de la consola del navegador muestran el espacio de nombres en el elemento SVG).
Cuando necesite reutilizar estos fragmentos de svg para sus otras necesidades (imagen de fondo en CSS o elemento img en HTML), tenga cuidado con el espacio de nombres faltante. Sin el espacio de nombres, los navegadores pueden negarse a mostrar SVG (independientemente de la codificación utf8 o base64).
Para las personas que todavía tienen dificultades, logré que esto funcionara en todos los navegadores modernos IE11 y superiores.
Base64 no era una opción para mí porque quería usar SASS para generar íconos SVG basados en cualquier color dado. Por ejemplo: @include svg_icon(heart, #FF0000);
De esta manera puedo crear un cierto icono en cualquier color, y solo tengo que incrustar la forma SVG una vez en el CSS. (con base64 tendrías que incrustar el SVG en cada color que quieras usar)
Hay tres cosas que debes tener en cuenta:
LA CODIFICACIÓN DE LA URL SU SVG Como han sugerido otros, debe codificar la URL de toda su cadena SVG para que funcione en IE11. En mi caso,
fill="#00FF00"
los valores de color en campos comofill="#00FF00"
ystroke="#FF0000"
y los reemplacé con una variable SASSfill="#{$color-rgb}"
para que estos puedan reemplazarse Con el color que quiero. Puede usar cualquier convertidor en línea para codificar en URL el resto de la cadena. Terminarás con una cadena SVG como esta:% 3Csvg% 20xmlns% 3D% 27http% 3A% 2F% 2Fwww.w3.org% 2F2000% 2Fsvg% 27% 20viewBox% 3D% 270% 200% 20494.572% 20494.572% 27% 20width% 3D% 27512% 27% 20height% 3D % 27512% 27% 3E% 0A% 20% 20% 3Cpath% 20d% 3D% 27M257.063% 200C127.136% 200% 2021.808% 20105.33% 2021.808% 20235.266c0 2041.012% 2010.535L41.020LL.0825 % 20464.586c345% 2012.797% 2041.813% 2012.797% 2015.467% 200% 2029.872-4.721% 2041.813-12.797v158.184z% 27% 20fill% 3D% 27 # {$ color-rgb} % 27% 2F% 3E% 3C% 2Fsvg% 3E
OMITIR EL CHARSET UTF8 EN LA URL DE DATOS Al crear su URL de datos, debe omitir el conjunto de caracteres para que funcione en IE11.
NO imagen de fondo: url (datos: imagen / svg + xml; utf-8,% 3Csvg% 2 ....)
PERO imagen de fondo: url (datos: imagen / svg + xml,% 3Csvg% 2 ....)
UTILIZAR RGB () EN LUGAR DE LOS Colores HEX. A Firefox no le gusta # en el código SVG. Así que necesitas reemplazar tus valores hexadecimales de color con valores RGB.
NO llenar = "# FF0000"
BUT fill = "rgb (255,0,0)"
En mi caso, uso SASS para convertir un hex dado a un valor rgb válido. Como se señaló en los comentarios, también es mejor codificar en URL la cadena RGB (para que la coma se convierta en% 2C)
@mixin svg_icon($id, $color) {
$color-rgb: "rgb(" + red($color) + "%2C" + green($color) + "%2C" + blue($color) + ")";
@if $id == heart {
background-image: url(''data:image/svg+xml,%3Csvg%20xmlns%3D%27http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%27%20viewBox%3D%270%200%20494.572%20494.572%27%20width%3D%27512%27%20height%3D%27512%27%3E%0A%20%20%3Cpath%20d%3D%27M257.063%200C127.136%200%2021.808%20105.33%2021.808%20235.266c0%204%27%20fill%3D%27#{$color-rgb}%27%2F%3E%3C%2Fsvg%3E'');
}
}
Me doy cuenta de que esta podría no ser la mejor solución para SVG''s muy complejos (el SVG en línea nunca está en ese caso), pero para los iconos planos con solo un par de colores, esto realmente funciona muy bien.
Pude omitir un mapa de bits de sprite completo y reemplazarlo con SVG en línea en mi CSS, que resultó ser de solo 25 kb después de la compresión. Por lo tanto, es una excelente manera de limitar la cantidad de solicitudes que tiene que hacer su sitio, sin ampliar su archivo CSS.
Sí, es posible. Prueba esto:
body { background-image:
url("data:image/svg+xml;utf8,<svg xmlns=''http://www.w3.org/2000/svg'' width=''10'' height=''10''><linearGradient id=''gradient''><stop offset=''10%'' stop-color=''%23F00''/><stop offset=''90%'' stop-color=''%23fcc''/> </linearGradient><rect fill=''url(%23gradient)'' x=''0'' y=''0'' width=''100%'' height=''100%''/></svg>");
}
(Tenga en cuenta que el contenido de SVG debe ser url-escaped para que esto funcione, por ejemplo, #
se reemplaza con %23
).
Esto funciona en IE 9 (que soporta SVG) . Las URL de datos también funcionan en versiones anteriores de IE (con limitaciones), pero no son compatibles de forma nativa con SVG.
Un poco tarde, pero si alguno de ustedes se ha estado volviendo loco tratando de usar SVG en línea como fondo , las sugerencias de escape anteriores no funcionan del todo. Por un lado, no funciona en IE, y dependiendo del contenido de su SVG, la técnica causará problemas en otros navegadores, como FF.
Si codifica en base64 el svg (¡no la url completa, solo la etiqueta svg y su contenido!) Funciona en todos los navegadores. Aquí está el mismo ejemplo de jsfiddle en base64: http://jsfiddle.net/vPA9z/3/
El CSS ahora se ve así:
body { background-image:
url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+PGxpbmVhckdyYWRpZW50IGlkPSdncmFkaWVudCc+PHN0b3Agb2Zmc2V0PScxMCUnIHN0b3AtY29sb3I9JyNGMDAnLz48c3RvcCBvZmZzZXQ9JzkwJScgc3RvcC1jb2xvcj0nI2ZjYycvPiA8L2xpbmVhckdyYWRpZW50PjxyZWN0IGZpbGw9J3VybCgjZ3JhZGllbnQpJyB4PScwJyB5PScwJyB3aWR0aD0nMTAwJScgaGVpZ2h0PScxMDAlJy8+PC9zdmc+");
Recuerde eliminar cualquier URL que se escape antes de convertir a base64. En otras palabras, el ejemplo anterior mostró color = ''# fcc'' convertido a color = ''% 23fcc'', debe volver a #.
La razón por la que base64 funciona mejor es que elimina todos los problemas con comillas simples y dobles y el escape de url
Si está utilizando JS, puede usar window.btoa()
para producir su base64 svg; y si no funciona (puede quejarse de caracteres no válidos en la cadena), simplemente puede utilizar https://www.base64encode.org/ .
Ejemplo para establecer un fondo div:
var mySVG = "<svg xmlns=''http://www.w3.org/2000/svg'' width=''10'' height=''10''><linearGradient id=''gradient''><stop offset=''10%'' stop-color=''#F00''/><stop offset=''90%'' stop-color=''#fcc''/> </linearGradient><rect fill=''url(#gradient)'' x=''0'' y=''0'' width=''100%'' height=''100%''/></svg>";
var mySVG64 = window.btoa(mySVG);
document.getElementById(''myDiv'').style.backgroundImage = "url(''data:image/svg+xml;base64," + mySVG64 + "'')";
html, body, #myDiv {
width: 100%;
height: 100%;
margin: 0;
}
<div id="myDiv"></div>
Con JS puede generar SVG sobre la marcha, incluso cambiando sus parámetros.
Uno de los mejores artículos sobre el uso de SVG está aquí: http://dbushell.com/2013/02/04/a-primer-to-front-end-svg-hacking/
Espero que esto ayude
Micro