Visualizar fragmentos

facebook-svg gplus-svg twitter-svg

Podemos utilizar un elemento SVG como imagen ( <img> o background-image ) y también podemos utilizar solo un fragmento de este elemento SVG. Para utilizar fragmentos necesitamos un método para cambiar el valor del atributo viewBox. En SVG hay varias maneras de hacerlo

El documento SVG utilizado

Este es el aspecto del documento .svg utilizado en los siguientes ejemplos:

fragmentos svg

Se trata de un documento .svg con un viewBox="0 0 72 24". Esto quiere decir que tiene una anchura de 72 unidades y una altura de 24. La esquina izquierda arriba del elemento SVG coincide con el punto {x:0,y:0}.
El documento contiene 3 iconos ( home, ok y mail ). Cada ícono tiene una anchura y una altura de 24 unidades y están colocados uno al lado de otro, parecido a los sprites del CSS.

Para utilizar solo un fragmento de este elemento svg necesitamos cambiar el valor del atributo viewBox del elemento svg de "0 0 72 24" a otro valor. Por ejemplo si quiero visualizar el sobre ( mail ) necesito utilizar este valor "48 0 24 24".

A continuación una pequeña demostración para explicar que pasa al cambiar el viewBox del elemento svg

See the Pen explicación fragmentos SVG*** by Gabi (@enxaneta) on CodePen.

Por favor lea acerca del atributo viewBox

Es posible entender de que va todo esto analizando detenidamente los siguientes ejemplos en codepen:

See the Pen SVG Fragment Identifiers in HTML and CSS by Gabi (@enxaneta) on CodePen.

Para quienes la necesitan a continuación viene una larga explicación detallada:

Fragmentos referenciados con elementos <view>

En SVG el elemento <view> puede ser utilizado para redefinir el valor de los atributos viewBox y preserveAspectRatio.
Un elemento SVG puede tener varios elementos <view>, uno por cada fragmento que queramos definir.
Podemos utilizar esta técnica modificando el URL de una imagen <img> o de una imagen de fondo (background-image).
Para definir un fragmento, en el URL utilizamos el símbolo almohadilla (#) seguido del id del elemento <view> invocado.

view-element.svg#el_id_del_elemento_view_invocado
Imágenes <img> recortadas

El código simplificado del documento SVG utilizado a continuación es el siguiente:


 <svg viewBox="0 0 72 24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" >
 
  <view id="home-view" viewBox="0 0 24 24"/>
  <view id="ok-view" viewBox="24 0 24 24"/>
  <view id="mail-view" viewBox="48 0 24 24"/>
  
  <g id="home">...</g>
  <g id="ok">...</g>
  <g id="mail">...</g>
</svg>

Para ver el todo el código del elemento svg utilizado por favor abra este documento svg en view-source.

Lo más importante es que dentro del elemento svg aparecen 3 elementos <view>, uno para cada fragmento que queremos utilizar.

<view id="home-view" viewBox="0 0 24 24" />
<view id="ok-view" viewBox="24 0 24 24" />
<view id="mail-view" viewBox="48 0 24 24" />

Como ya he explicado el atributo viewBox de los elementos <view> invocados puede modificar ( sobreescribir ) el valor del atributo viewBox del elemento svg.

Por ejemplo dada la siguiente imagen:

<img src="view-element.svg#home-view" alt="…" />

el fragmento referenciado corresponde al primer icono: la casa ( home ). La vista utilizada es el primer elemento <view>

<view id="home-view" viewBox="0 0 24 24" />

cuyo atributo viewBox="0 0 24 24" sobreescribe el atributo viewBox del elemento svg padre, cambiando lo que aparece visualizado.

Para visualizar el tercer icono ( el sobre ) voy a utilizar el siguiente código:

<img src="view-element.svg#mail-view " alt="…" />

En este caso el atributo viewBox del elemento <view> invocado es viewBox="48 0 24 24".

Cambiar el valor del atributo preserveAspectRatio en imágenes SVG

Podemos utilizar la misma técnica para sobreescribir el valor del atributo preserveAspectRatio del elemento svg padre.

Este es el código simplificado del documento svg utilizado:


<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" enable-background="new 0 0 24 24"  preserveAspectRatio="xMinYMin meet">
  <view id="stretch" preserveAspectRatio="none" />
  <g id="home">...</g>
</svg>

Para ver todo el código del elemento svg utilizado por favor abra el siguiente documento svg en view-source.

En este caso el elemento <view> utilizado tiene esta sintaxis:

<view id="stretch" preserveAspectRatio="none"/>

En el HTML podemos utilizar la siguiente imagen:

<img src="view-element_1.svg#stretch" alt="…"/>

El elemento <view> utilizado sobreescribe el valor del atributo preserveAspectRatio del elemento SVG.  Si damos a la imagen una anchura exagerada ( img{width:90%} ), como que el nuevo valor de preserveAspectRatio="none" la imagen aparece deformada.

Fragmentos referenciados con elementos <view> en CSS

En el HTML tengo el siguiente código:

<span class="icon home"></span>

Quiero que el elemento <span class="icon home" tenga la casa ( home ) como imagen de fondo (background-image).

El documento svg utilizado es muy parecido al anterior con la única diferencia que ahora el elemento svg tiene también una anchura width y una altura height, la misma anchura y altura que el elemento .icon.

<svg width="24" height="24" viewBox="0 0 72 24"...

En el CSS utilizamos un fragmento del elemento svg como imagen de fondo:

.icon{
  width: 24px;
  height: 24px;
  background: url("view-element-css.svg#home-view") no-repeat;
  }

En el caso en el cual queremos cambiar el tamaño de los iconos podemos utilizar el mismo documento SVG y estirar la imagen utilizando background-size:cover.

.icon{
   width: 48px;
   height: 48px;
   background: url("view-element-css.svg#home-view") no-repeat;
   background-size:cover;
    }

Fragmentos referenciados con #svgView(viewBox())

A veces es imposible editar el código del elemento svg para añadir los elementos <view> necesarios. Otras veces no sabemos de antemano el valor del nuevo atributo viewBox que necesitamos. Para estas ocasiones y para otras más podemos utilizar el valor del viewBox directamente en el URL

Imágenes recortadas

En el HTML puedo utilizar la siguiente imagen:

<img src="view-box.svg#svgView(viewBox(0,0,24,24))" alt="…"/>

El valor que sobreescribe el viewBox del elemento SVG aparece después de una almohadilla (#) seguida por la palabra clave svgView. En este caso el nuevo valor de viewBox = "0,0,24,24". Por favor observe que he utilizado comas como separadores en lugar de espacios. Esta es una sintaxis perfectamente válida y como que se trata de un URL es mejor evitar los espacios en blanco.

El elemento SVG utilizado es muy parecido a los anteriores, aunque esta vez no contiene los elementos <view> porque ya no son necesarios.

Este es el código simplificado del documento svg utilizado:


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 72 24" >
  <g id="home">...</g>
  <g id="ok">...</g>
  <g id="mail">...</g>
</svg>

Para verlo por favor abra el siguiente documento svg en view-source.em>

En el HTML la sintaxis es la siguiente:

elemento.svg#svgView(atributo(valor))

Donde el atributo puede ser viewBox, preserveAspectRatio o transform. También es posible especificar varios atributos utilizando una lista de valores separados por punto y coma (;)

elemento.svg#svgView(atributo1(valor);atributo2(valor))
Imagenes de fondo recortadas en CSS (background-image)

En el HTML tengo el siguiente código:

<span class="icon home-2"></span>

y quiero que el elemento <span class="icon home-2" tenga la casa ( home ) como imagen de fondo (background-image).

El documento svg utilizado es muy parecido al anterior  con la única diferencia que ahora el elemento svg tiene también una anchura width y una altura height, la misma anchura y altura que el elemento .icon

<svg width="24" height="24" viewBox="0 0 72 24"…

En el CSS utilizamos el elemento svg como imagen de fondo donde #svgView(viewBox(0,0,24,24)) especifica el nuevo valor de viewBox para visualizar el fragmento deseado: la casa.

.icon{
      width: 24px;
      height: 24px;
      background: url("view-box_1.svg#svgView(viewBox(0,0,24,24))") no-repeat;
    }

En el caso en el cual queremos cambiar el tamaño de los iconos podemos utilizar el mismo documento SVG y estirar la imagen utilizando background-size:cover

.icon{
      width: 48px;
      height: 48px;
      background: url("view-box_1.svg#svgView(viewBox(0,0,24,24))") no-repeat;
      background-size:cover;
  }

Imágenes con fragmentos referenciados utilizando el selector :target

Una estrategia alternativa sería utilizar CSS y el pseudo-selector :target. En este caso los tres iconos aparecen apilados uno encima de otro. Esto es importante. En este caso ya no necesitamos redefinir el valor del atributo viewBox. En el CSS los elementos que no son :target son invisibles:

:not(:target){display:none;}

Esto quiere decir que al abrir el documento SVG no podemos ver nada. No obstante si uno de los elementos es :target este elemento será visible ( display:inline; )

<img src="view-target_1.svg#mail" alt="" />

Para ver la estructura del documento SVG utilizado por favor abra este elemento SVG o este otro en view-source.

Este es el código simplificado del documento svg utilizado:


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 24 24">
<style type="text/css">
 <![CDATA[	
	g:not(:target) {
	display: none;
	}
	]]> 
</style>  
  <g id="home">...</g>
  <g id="ok">...</g>
  <g id="mail">...</g>
</svg>

Imágenes SVG como sprites CSS

En el CSS podemos utilizar este tipo de imágenes SVG como sprites, o sea especificando el tamaño del ícono y la posición (background-position) de la imagen de fondo:

Para ver la estructura del documento SVG utilizado por favor abra view-element.svg en view-source.

.icon {
      width: 24px;
      height: 24px;
    }
    .icon.home-3 {
      background: url("view-box.svg") no-repeat;
      background-size: 72px 24px;
      background-position: 0 0;
    }
    .icon.ok-3 {
      background: url("view-box.svg") no-repeat;
      background-size: 72px 24px;
      background-position: -24px 0px;
    }
    .icon.mail-3 {
      background: url("view-box.svg") no-repeat;
      background-size: 72px 24px;
      background-position: -48px 0px;
    }

En este momento el soporte en los navegadores de los identificadores de fragmentos es muy bueno.