Fallbacks de SVG | Programar Plus

ACTUALIZAR: Aquí hay una guía más completa de las alternativas de SVG que hemos publicado.

Hay una técnica muy inteligente de Alexey Ten para proporcionar un respaldo de imagen para SVG que circula por Internet recientemente. Hace exactamente lo que desea en los navegadores clásicos que no admiten SVG, IE 8 y Android 2.3. Si profundizamos un poco más, encontramos algunas cosas bastante interesantes que incluyen un comportamiento inesperado que es un poco fastidioso.

La técnica de Alexey se ve así:

<svg width="96" height="96">
  <image xlink:href="https://css-tricks.com/svg-fallbacks/svg.svg" src="svg.png" width="96" height="96" />
</svg>

La idea se basó en la revisión de Jake Archibald del hecho de que los navegadores <image> etiqueta como <img>. Es solo un alias extraño de los días de antaño que se puede explotar.

Qué muestra

La técnica es casi perfecta en términos de lo que muestran los navegadores compatibles y no compatibles. IE 8, que no admite SVG, muestra el PNG de respaldo. Android 2.3, la misma historia.

La parte en la que me confundí fue iOS 3 y 4. El navegador nativo en esos sistemas operativos es compatible con SVG, en forma de <img src="https://css-tricks.com/svg-fallbacks/*.svg"> o como CSS background-image. Pero con esta técnica, se muestra el PNG en lugar del SVG. El problema es que iOS 3 y 4 no es compatible con SVG “en línea” (por ejemplo, usando SVG con un <svg> etiqueta directamente en el HTML) (gráfico de soporte). La compatibilidad con SVG no es tan simple como sí / no. Depende de cómo se utilice.

El punto: es raro de ver <img> trabaja y <image> no funciona en estos casos. Y dado que esos navegadores son compatibles con SVG, es una pena no usarlo.

Qué descargas

Por supuesto, también nos preocupamos por lo que se descarga porque eso afecta el rendimiento de la página. Una vez más, son en su mayoría buenas noticias. Los navegadores modernos como Chrome solo descargan el SVG. Android 2.3 solo descarga el PNG.

Pero nos encontramos con un problema con las versiones 9, 10 y 11 de Internet Explorer (una vista previa en este momento). En IE 9, puede ver que ambas imágenes aparecen en la línea de tiempo de la red.

El PNG termina con un resultado de “Abortado” y aparece como 0 B recibido, pero aún afecta el tiempo de descarga.

Es una historia similar en IE 10, simplemente parece abortar más rápido y pasar al SVG sin mucho tiempo de inactividad.

Scott Jehl sugirió utilizando Charles Proxy para probar lo que se está descargando con mayor precisión. Charles verifica que se esté solicitando el PNG.

El tamaño del cuerpo de respuesta es de hecho 0 B, por lo que el aborto ocurre lo suficientemente rápido como para que no se transfieran muchos datos. Aunque el encabezado de solicitud y respuesta combinados es 782 B y tarda ~ 300 ms en suceder. A Yoav Weiss Señala, el problema puede empeorar si hay scripts de bloqueo en la parte superior de la página.

También tenga en cuenta que existe la posibilidad de que el uso de un proxy afecte lo que se descarga / no se descarga, como señala Steve Souders en este artículo de Jason Grigsby sobre Charles Proxy.

La investigación de Andy Davies sugiere que la solicitud de PNG no se cancela en absoluto en IE 11 en Windows 7.

@stopsatgreen @jaffathecake @chriscoyier En mi IE11 / Win7, la respuesta no se cancela y aparece en las herramientas de desarrollo y pcap pic.twitter.com/ypitwTYAAH

– Andy Davies (@andydavies) 19 de agosto de 2013

Recomendaciones

Hice las pruebas de visualización de este lápiz, pero las pruebas de descarga las hice con solo una de las técnicas presentes en la página y usando la vista de depuración para que no hubiera nada más en la página que la técnica en bruto.

Vea las pruebas de Pen SVG de Chris Coyier (@chriscoyier) en CodePen

Entonces, Fallbacks

El Alexey Ten todavía es inteligente y si el problema de visualización de iOS y el problema de descarga de IE son aceptables para usted, aún se puede usar. Aquí hay algunas técnicas de respaldo más, que difieren según cómo use SVG.

Si está utilizando SVG como imagen de fondo …

Modernizr tiene una prueba SVG. Por lo tanto, podría declarar un respaldo con los nombres de clase que inyecta en el elemento HTML.

.my-element {
  background-image: url(image.svg);
}
.no-svg .my-element {
  background-image: url(image.png);
}

Eso no debería tener problemas de doble descarga, pero no tiene la dependencia de Modernizr.

Una técnica muy inteligente sin dependencia en absoluto es usar un pequeño truco CSS con múltiples fondos y gradientes lineales de sintaxis antigua:

.my-element {
  background-image: url(fallback.png);
  background-image: 
    linear-gradient(transparent, transparent),
    url(image.svg);
}

Había una técnica que solo usaba múltiples fondos aquí. Pero eso no funcionó del todo porque Android 2.3 lo admitía, pero no SVG y, por lo tanto, se rompió. Esto combina degradados de sintaxis antigua con múltiples fondos, por lo que funciona en todas partes. Referencia.

Si ambas cosas son compatibles, el navegador usará la segunda declaración (con SVG), de lo contrario recurrirá a la primera declaración (con PNG).

Si usa SVG como en línea…

David Ensinger publicó una técnica utilizando la <foreignObject> etiqueta en <svg>. Pero el problema con eso es que el respaldo se carga sin importar lo que resulte en la descarga doble todo el tiempo en lugar de solo a veces como el <image> técnica.

Esto se complica un poco, pero Artur A publicó esta idea que parece resolver la doble descarga y funcionar en todas partes:

    Demostración de HTML5 SVG      

Alternatively, you could do something like:

<svg> ... inline SVG stuff ... </svg>
<div class="my-svg-alternate"></div>

Then use the Modernizr SVG test again to get the support HTML class and then…

.my-svg-alternate {
  display: none;
}
.no-svg .my-svg-alternate {
  display: block;
  width: 100px;
  height: 100px;
  background-image: url(image.png);
}

Or wrap the SVG in that div so the div could be used for consistent sizing.

If you’re using inline SVG, there is a good chance you are doing it with <use>, in which case the script svg3everybody does a pretty good job. If SVG the way you are using inline SVG is supported, it just works. If it’s being referenced externally in IE (which doesn’t work), it makes it work by ajaxing it in. If it doesn’t work at all, it has a syntax you can use to specify a PNG fallback.

If you’re using SVG as <object>…

You could use the object tag itself as the element to style after the Modernizr test.

<object type="image/svg+xml" data="https://css-tricks.com/svg-fallbacks/image.svg" class="logo"></object>
.no-svg .logo {
  display: block;
  width: 100px;
  height: 100px;
  background-image: url(image.png);
}

If you’re using SVG as <img>…

There is a technique which a failing SVG file can get swapped out on the fly:

<img src="https://css-tricks.com/svg-fallbacks/image.svg" onerror="this.src="https://css-tricks.com/svg-fallbacks/image.png"">

That requires special HTML as you can see, so if that’s not possible or practical for you, you could swap sources with Modernizr. This uses the JS API of Modernizr, not the class names:

if (!Modernizr.svg) {
  $("img[src$='.svg']") .attr (" src ", respaldo);}

Donde fallback es una cadena de una URL donde se encuentra el respaldo de la imagen que no es SVG. Podrías mantenerlo en un data-fallback atributo, use un patrón de URL consistente donde simplemente reemplace .svg con .png, o cualquier otra cosa inteligente que se le ocurra. SVGeezy es una biblioteca que hace exactamente esto y utiliza un método de detección inteligente.

El problema con esos métodos es que requieren un <img src> y ese src se precargará y no hay forma de que puedas combatirlo. Así que estás buscando posibles descargas dobles, lo que siempre es malo.

O puede usar una técnica similar a la del SVG en línea y las técnicas de objetos donde se muestra un DIV oculto con un respaldo.

Otra opción bastante buena es utilizar Picturefill. El <picture> El elemento permite retrocesos de tipo de contenido. Necesitará el polyfill porque la imagen aún no es muy compatible. Sin embargo, esto resuelve el problema de la doble descarga, lo cual es genial, pero no funciona sin JavaScript. Pero tampoco lo hacen los otros métodos. Se parece a esto:

<picture>

  <source  type="image/svg+xml">

  <img  alt="A lovely graph.”>

</picture>

Recuerde que un tipo de respaldo no es nada en absoluto

Si está utilizando el SVG como imagen de fondo, probablemente sea decorativo y no vital para el funcionamiento del sitio, por lo que es probable que sea una situación en la que no haya ningún respaldo.

Lo mismo ocurre con los adornos SVG de cualquier tipo, como un icono acompañado de una palabra en un botón. Sin ese SVG, sigue siendo un botón con una palabra, una alternativa aceptable.

Bien entonces

Si esta publicación no significó mucho para usted porque aún no está usando SVG, debería hacerlo porque es increíble. Esta publicación podría ayudarlo a comenzar.

Si tiene más datos para compartir, nos encantaría saberlo.

¡Buena suerte!