CSS avanzado

6.2. Mapas de imagen

Los mapas de imagen se llevan utilizando desde los orígenes de HTML. Combinando las etiquetas <map> y <area> junto con el atributo usemap de la etiqueta <img> es posible definir diferentes zonas pinchables dentro de una misma imagen.

Hoy en día los mapas de imagen HTML han sido sustituidos por otras soluciones como Flash, que son más fáciles de utilizar y disponen de más posibilidades. No obstante, recientemente ha surgido un nuevo tipo de mapa de imagen creado sólo con CSS.

Estos mapas de imagen CSS no suelen utilizarse para definir zonas pinchables dentro de una imagen, sino que se emplean para mostrar información adicional y comentarios sobre las diferentes zonas de una imagen. El sitio de fotografía Flickr utiliza los mapas de imagen para mostrar notas y comentarios de los usuarios. Otros sitios web como Facebook utilizan los mapas de imagen para que los usuarios etiqueten las fotografías indicando el nombre de las personas que aparecen en cada una.

A continuación se explican los pasos necesarios para crear un mapa de imagen exclusivamente con CSS similar a los de Flickr y Facebook.

En primer lugar, selecciona la imagen en la que se van a mostrar las notas. En este ejemplo se utiliza una imagen de la fotógrafa visualpanic que se puede utilizar libremente y que está disponible en Flickr:

Imagen original en la que se va a mostrar el mapa de imagen

Figura 6.1 Imagen original en la que se va a mostrar el mapa de imagen

El funcionamiento del mapa de imagen terminado es el que muestra la siguiente secuencia de imágenes:

Funcionamiento del mapa de imagen creado con CSS

Figura 6.2 Funcionamiento del mapa de imagen creado con CSS

La imagen por defecto no muestra ninguna zona activa. Cuando el usuario pasa el ratón por encima de cualquier parte de la imagen, se muestra el recuadro de todas las zonas activas disponibles. Además, cuando el usuario pasa el ratón por encima de una zona activa, se muestra el comentario asociado.

El código HTML del mapa de imagen creado con CSS varía mucho en función de la solución utilizada. Aunque algunas soluciones crean varios <div> y tablas por cada nota/comentario, en este ejemplo se simplifica al máximo el código HTML y sólo se utiliza un elemento <div> y una lista <ul>:

<div class="mapa_imagen">
  <img src="imagenes/mar.jpg" />

  <ul class="notas">
    <li id="nota1"><p>Todo el mar es suyo :)</p></li>
    <li id="nota2"><p>¡Me encanta este color azul!</p></li>
    <li id="nota3"><p>Dan ganas de tirarse...</p></li>
  </ul>
</div>

El elemento <div class="mapa_imagen"> encierra todos los elementos que forman el mapa de imagen (la imagen original y las notas/comentarios). Los comentarios se incluyen mediante una lista no ordenada <ul>, en la que cada elemento <li> es un comentario.

El elemento <div> y la lista <ul> deben utilizar el atributo class y no id porque en una misma página puede haber varios mapas de imagen. Por su parte, los elementos <li> de cada comentario deben utilizar atributos id, ya que cada comentario se muestra en una posición única y tiene unas dimensiones únicas de anchura y altura.

La clave de los mapas de imagen CSS consiste en posicionar cada <li> de forma absoluta respecto de la imagen y asignarles una anchura/altura adecuadas. Posteriormente, se emplea la pseudo-clase :hover para mostrar/ocultar elementos cuando el usuario pasa el ratón por encima.

1) Posicionar de forma absoluta cada nota:

div.mapa_imagen {
  position: relative
}
ul.notas li {
  position: absolute;
}

2) Aplicar los estilos básicos a las notas (borde blanco y sin adornos de lista):

ul.notas li {
  border: medium solid #FFF;
  list-style: none;
}

3) Ocultar por defecto las notas y mostrarlas cuando se pasa el ratón por encima de la imagen:

ul.notas li {
  display: none;
}
div.mapa_imagen:hover ul.notas li {
  display: block;
}

4) Aplicar los estilos básicos al texto de las notas y posicionarlo debajo de cada nota:

ul.notas li p {
  position: absolute;
  top: 100%;

  background: #FFF;
  opacity: 0.65;

  margin: 10px 0 0 0;
  padding: 0.3em;
}

5) Ocultar por defecto el texto de las notas y mostrarlo cuando se pasa el ratón por encima de la nota:

ul.notas li p {
  display: none;
}
ul.notas li:hover p {
  display: block;
}

6) Establecer la posición y dimensiones de cada nota:

ul.notas li#nota1 {
  width: 140px; height: 110px; top: 130px; left: 345px;
}
ul.notas li#nota2 {
  width: 30px; height: 200px; top: 10px; left: 10px;
}
ul.notas li#nota3 {
  width: 60px; height: 60px; top: 200px; left: 150px;
}

Aplicando las reglas CSS anteriores el mapa de imagen CSS ya funciona correctamente en los navegadores Firefox y Safari. Desafortunadamente, los navegadores Internet Explorer y Opera tienen errores que impiden que el ejemplo funcione correctamente. El problema reside en que los elementos <li> tienen un fondo transparente y tanto Internet Explorer como Opera tienen problemas con la pseudo-clase :hover sobre estos elementos.

La solución consiste en añadir un fondo (color o imagen) sobre los elementos <li>. Como lo único importante es añadir un fondo, independientemente de si el fondo es real o no, la siguiente regla CSS es suficiente:

ul.notas li {
  background: url("esta_imagen_no_existe");
}

El código CSS completo del mapa de imagen que funciona en todos los navegadores es el siguiente:

div.mapa_imagen {
  position: relative
}
ul.notas li {
  list-style: none;
  display: none;
  position: absolute;
  border: medium solid white;
  background: url("esta_imagen_no_existe");
}
div.mapa_imagen:hover ul.notas li {
  display: block;
}
ul.notas li p {
  margin: 10px 0 0 0;
  padding: .3em;
  display: none;
  background: #FFF;
  opacity: 0.65;
  position: absolute;
  top: 100%;
}
ul.notas li:hover p {
  display: block;
}

ul.notas li#nota1 {
  width: 140px; height: 110px; top: 130px; left: 345px;
}
ul.notas li#nota2 {
  width: 30px; height: 200px; top: 10px; left: 10px;
}
ul.notas li#nota3 {
  width: 60px; height: 60px; top: 200px; left: 150px;
}

El resultado final es el que muestra la siguiente imagen:

Mapa de imagen con todas sus zonas activadas

Figura 6.3 Mapa de imagen con todas sus zonas activadas