SVG apuntes para comenzar: el viewport y el viewBox 27.11.15
Unos apuntes para iniciarse en el uso y manejo de SVG´s. Qué es el viewport y el viewBox y las relaciones entre ambos.
SVG apuntes para comenzar: el viewport y el viewBox
De entrada, SVG no es un dibujito de rayas que puedes estirar o encoger a voluntad. SVG es toda una especificación web, con estatus de 'recomendación' su versión 1.1 desde 2011 y en desarrollo la actualización a la 2.
De ella dicen sus desarrolladores que es:
SVG es un lenguaje de gráficos* Web. SVG define el marcado y APIs para crear imágenes estáticas o dinámicas, con capacidad de ser interactivas y animadas, incluyendo efectos gráficos. Puede ser estilizado con CSS, y se combina con HTML
* Una matización personal. Creo que sería más preciso hablar de "lenguaje de representación web" que de "gráfico".
En el momento de iniciarse en su creación y/o uso lo más normal que nos sucede es encontrarnos (todos) con algunos problemillas debido, al menos en mi caso, a que no tenemos claro tres conceptos intrínsecos a los SVG´s que conforman su propio espacio de trabajo.
- Su viewport: el paño, lienzo o espacio físico en el que se representa
- Su viewBox: la parte de todo el SVG que se mostrará.
- Su aspectRatio o relación de aspecto.
El viewport en el SVG
Por definición un SVG carece de tamaño, o lo que es lo mismo, su anchura y altura son infinitas. De inicio no están acotadas o delimitadas.
Cuando creas un SVG puedes usar cualquier unidad de tamaño. Por otra parte, un SVG es un elemento contenedor y estructural. Puede contener multitud de "objetos" y estar distribuidos aleatoriamente en función de las necesidades y gustos de su creador en el momento de realizarlo.
Así que al incluir un SVG en otro documento como un HTML debemos ponerle límites. Esto se consigue declarando su anchura y altura, ya sea con los atributos width | height del elemento <svg> o si lo estilizamos con Css con las propiedades width | height en el selector svg.
Al acotar su tamaño estamos estableciendo el viewport del Svg: el paño, lienzo o superficie en que mostraremos todo el svg.
El viewBox en el SVG
Al mostrar el SVG en un espacio limitado surgen una serie de problemas. Es como intentar reducir todo el cielo nocturno a un folio. Demasiado grande y no interesa mostrar todo, incluidos los espacios vacíos.
Para solucionarlo está el viewBox que delimita y acota la parte del SVG que mostraremos en el viewport. Volviendo a la analogía del cielo nocturno, el viewBox es la ventana del telescopio con el que lo miramos o el trocito de todo el universo en el que fijamos nuestra atención.
El viewBox es un atributo del elemento svg y de aquellos otros que generan su propio viewBox (marker, pattern, view, symbol...) y se declara tal que así: <svg viewBox="0 0 100 100">. Está compuesto por cuatro valores separados por comas o espacios en blanco.
Realmente es un sistema de coordenadas que delimitan un rectángulo. Los dos primeros sitúan el punto 0,0 o esquina superior izquierda, la tercera la altura y la cuarta la anchura a partir del punto 0,0
Resumiendo: con el viewport damos unas medidas finitas y manejables al SVG y con el viewPort indicamos qué parte de todo el SVG mostraremos.
Unos ejemplos
Con el permiso no solicitado de @jorgeATGU tomo uno de sus pens para ejemplificar todo lo anterior. Sólo he colocado un color de fondo al html y al SVG para hacer visible su viewport.
See the Pen iMac SVG by Kseso (@Kseso) on CodePen.
Fíjate los valores que declara Jorge en la etiqueta de apertura del SVG para crear tanto el viewport como el viewBox. Esto es, a qué medidas escalamos todo el SVG y su contenido y la parte que quiere mostrar de todo el SVG. No es casualidad la concordancia entre algunos de sus valores:
<svg version="1.1"
width="644px" height="342px"
viewBox="0 0 644 342">
Pero si alteramos alguno de los valores de estos atributos (la anchura, altura o viewBox) del svg lo mostrado y cómo se muestra cambia. Por ejemplo, el resultante de declarar viewBox="200 240 5 50" es el siguiente:
See the Pen iMac SVG by Kseso (@Kseso) on CodePen.
El resultado final, aún siendo el mismo SVG en ambos casos, es notoriamente diferente.
Relación entre el viewport del SVG y las unidades Css relativas al vieport
A estas alturas debería ser innecesario explicar qué son las unidades Css relativas al viewport. Pero por si acaso alguien lo necesita resumamos que son unidades que toman el tamaño de la ventana en la que se muestra el documento como base. Así 100vw es el 100% de la ventana y 100vh el 100% de la altura.
En otros elementos, como los iframes dentro de un documento html, hacen que cambie la base de cálculo de estas unidades: no es el tamaño de la ventana (o pantalla) donde se muestra el documento que contiene el iframe sino las propias medidas del iframe las referentes para el cálculo de las unidades Css relativas al viewport.
Sin embargo con los SVG´s (y los elementos dentro de él que generan su propio viewport) no ocurre este cambio en la base del cálculo. Sigue siendo la ventana del navegador o pantalla del aparato la base para calcular los vw, vh y asociadas.
Debes tenerlo presente hoy por hoy. Quizás en un futuro próximo esto cambie pues hay un hilo de discusión en las listas del w3C.
Kseso
the obCSServer ᛯ Ramajero Argonauta, Enredique Amanuense de CSS.#impoCSSible inside
Dicen que, en español, EsCss es el mejor blog de CSS. Posíblemente exageren.
@Kseso EsCss Kseso
Genial! no conocía este tema de los SVG. Me imagino que podría dársele muchas utilidades cómo por ejemplo, una web que este construida como un mapa y solo baste desplazarse con el mouse o touch por todo el site. Es muy, muy interesante. ¿Y sobre los tiempos de carga? Esto me recuerda un poco a los sprite de Css. Lo que se me escapa un poco es lo de dimensiones infinitas. Supongo que se refiere que no hay un límite de medida del Viewport, pero al crearlo debe tener alguna dimensión en concreto ¿no? Por eso lo comparo con un sprite, donde el sprite tiene una determinada dimensión donde cada región contiene un gráfico que será mostrado por localización de coordenadas.
ResponderEliminarNo se que sucedió, iba a comentar y cuando le día a publicar no se publico nada :( y sino estoy mal es como la tercera vez que me sucede.
EliminarEn fin, en relación a lo que pregunta Pierre Daboin, en breves palabras: un icono de 16px en png no lo puedes reescalar por ejemplo a 100px sin que se pixele, sin embargo con un svg no importa si en el espacio o mesa de trabajo de donde lo crees sus dimensiones fuesen de 16px, al final lo podrás reescalar a 100, 1000 o 100% del viewport del navegador sin notar pixeles o perdidas por compresión, lo que hacer sprites con svg menos lío que por medio de js o php decirle al servidor que imagen cargar según en que dispositivo retina o no se previsualize nuestro site, claro solo aplicable a cosas como iconos o demás elementos realizado a partir de gráficos vectoriales, con fotografías, bueno... sigue siendo un lío.
Aunque ya he experimentado a mano y espada el uso de svg, siempre me impresiona re-descubrir conceptos como el control de viewbox y su diferencia con el viewport, me queda mucho más claro explicado de esta forma que leerlo en ingles y no se si es posible ahora, pero sería genial poder controlar al menos el viewbox (ah! y el aspect-ratio también) mediante CSS sin depender de js.
Por ultimo, reitero como siempre las mil gracias por compartir tus artículos con una calidad excelente. Saludos.
pd: no entendí lo del iframe xD.
g3kdigital
EliminarSabes qué es el viewport, ¿no? Es espacio físico donde se representa (se muestra) el documento (i.e. una página web html).
Normalmente este espacio (con unas dimensiones dadas) suele ser la ventana del navegador si se puede reescalar o la pantalla donde se muestra la página en los aparatos "móviles".
Eso es lo más común.
Sin embargo hay otros elementos que crean su propio viewport. Si una web la insertas en otra con un iframe, todo lo relativo a viewport (medidas en vw /vh en el caso que nos ocupa) ya no toman como referente del cálculo toda la ventana del navegador o la pantalla del aparato. Su referente es el iframe.
Así 10vw no será el 10% de la anchura de la ventana del navegador o pantalla del aparato. 10vw será el 10% de la anchura del iframe donde está "medita" la web embebida.
Sin embargo en el SVG, pese a crear su propio viewport, el referente para estos cálculos no es el mismo svg como pasa con el iframe. Sigue siendo la ventana del navegador o pantalla del cacharro donde se representa el svg.
Espero haberme explicado mejor ahora.
Un saludo