Hacer un tooltip con jQuery y CSS3

Explicamos como utilizar jQuery en combinación con CSS3 para crear un pequeño tooltip que despliegue mensajes al colocar el mouse sobre un elemento.

En esta ocasión haremos uso de un recurso bastante sencillo y atractivo visualmente el cual nos ayudará a mejorar el SEO de nuestro sitio y la experiencia del usuario al navegar. Para aquellos que no estén muy familiarizados con el tema, un tooltip es una herramienta de ayuda visual muy utilizada en sitios con el fin de mostrar una descripción o información relevante de cierto elemento que se despliega sobre una página.

Esta funcionalidad te puede resultar familiar, puede que en más de una ocasión te hayas percatado que al colocar el mouse sobre un elemento, como una imagen, aparezca un mensaje dentro de una pequeña caja de color. Esta es la funcionalidad clásica de un tooltip por defecto, el cual es agregado por el navegador, gracias a que nosotros especificamos un atributo “alt” o “title” a nuestro elemento.

En esta ocasión también haremos uso de dichos atributos, pero en lugar de utilizar el tooltip que nos ofrece el navegador haremos uno personalizado, que lucirá acorde al diseño del sitio y hará que luzca más profesional.

Tooltip personalizado

El uso de tooltips personalizados no es nuevo, se ha venido aplicando desde hace tiempo en el diseño web y en el pasado se pudieron apreciar sobretodo en desarrollos que fueron elaborados con Flash. En la actualidad su elaboración ya no involucra el uso de Flash, puesto que resulta mucho más sencilla gracias al uso de jQuery para el manejo de animaciones y transiciones.

Aunque jQuery simplifica la creación, aún necesitamos realizar una serie de tareas para poder personalizar nuestro tooltip. En esta ocasión nos apoyaremos con CSS3 para no utilizar imágenes al dar forma a nuestro tooltip, también haremos uso del atributo “title” en cada elemento donde queramos desplegarlo, agregando al mismo tiempo un alto valor de SEO a los elementos ya que indicaremos una descripción de lo que estamos desplegando.

De esta manera nuestro tooltip personalizado tendrá una muy buena presentación, sin necesidad de cargar imágenes que demanden peticiones extra al servidor, mostrando información relevante e importante para el usuario, mejorando su experiencia de navegación, con un código limpio y de fácil SEO para los buscadores.

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<title>Tooltips personalizados</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<style>
body{
background: steelblue;
font-family: Arial, Verdana;
}

.tooltip_elemento {
position: relative;
}

h2{
color: #FFF;
margin-top: 100px;
}

a{ color: #CCC }

.tooltip { display: none; position: absolute; width: 200px; padding: 10px;margin: 0 0 12px 0; z-index: 100;bottom: 100%; background: #FDD017; color: #fff; text-align: center; font-weight: bold; font-size: 11px; border-radius: 5px; }

.tooltip:after { content: ""; position: absolute; bottom: -14px; z-index: 100; border: 0 solid #FDD017; border-bottom: 14px solid transparent; border-left-width: 10px; width: 50%; left: 50%; }

.tooltip:before { content: ""; position: absolute; border: 0 solid #FDD017; bottom: -14px; z-index: 100; border-right-width: 10px; border-bottom: 14px solid transparent; width: 50%; right: 50%; } </style> </head> <body> <center> <h2>Tooltips con JQuery</h2> <a href="#" title="Este enlace actualmente no lleva a ningún lado pero sirve para mostrarte el uso del tooltip"
class="tooltip_elemento center">Tooltip en un enlace</a> <div class="tooltip">Texto del tooltip</div> </center> <script type="text/javascript"> jQuery("a").mouseenter(function (e) { var posMouse = e.pageX - this.offsetLeft; var textoTooltip = jQuery(this).attr("title"); if (textoTooltip.length > 0) { jQuery(this).append('<div class="tooltip">' + textoTooltip + '</div>'); jQuery("a > div.tooltip").css("left", "" + posMouse - 103 + "px"); jQuery("a > div.tooltip").fadeIn(300); } }); jQuery("a").mouseleave(function () { jQuery("a > div.tooltip").fadeOut(300).delay(300).queue(function () { jQuery(this).remove(); jQuery(this).dequeue(); }); }); </script> </body></html>

Ver ejemplo anterior

Estructura HTML para el tooltip

La base del proyecto estará sustentada por una estructura de lenguaje HTML, empezaremos por definir los elementos que mostrarán un tooltip, en esta ocasión nos decidimos a utilizar elementos de enlace por lo que utilizaremos la etiqueta “a” para definirlos. Debemos aclarar que cualquier elemento que acepte el atributo title puede ser utilizado, pero en esta ocasión solo quisimos utilizar enlaces, más adelante declararemos los elementos pueden utilizar esta herramienta.

<a href="#" title="Este enlace actualmente no lleva a ningún lado pero sirve para mostrarte el uso del tooltip"
 class="tooltip_elemento center"> Tooltip en un enlace</a>

A nuestros elementos les agregamos una clase que lleva por nombre “tooltip” esta será definida más adelante en nuestro código CSS, y se utiliza para darle un estilo con el que contará cada vez que la caja de descripción se abra. Después de definir los elementos que abrirán el tooltip debemos establecer la estructura del tooltip en sí, para ello haremos uso de un elemento de tipo “div” el cual contendrá un texto por defecto.

<div class="tooltip">Texto del tooltip</div>

Estilo del tooltip

Lo primero que debemos definir es la posición de los elementos que contendrán el tooltip, la cual debe ser relativa para que el tooltip pueda ser desplegando y para ello le daremos un valor de “relative” a la propiedad “position”:

.tooltip_elemento {

    position: relative;

}

Después le daremos estilo a la caja que define nuestra descripción, es decir el div que lleva la clase “tooltip” en sus atributos. El tooltip debe permanecer oculto por defecto por lo que estableceremos un valor “none” a la propiedad “display”, le daremos una posición absoluta para que sea relativa al elemento que lo despliega, estableceremos las dimensiones de la caja dependiendo del tamaño que queramos y finalmente definimos el color de fondo y algunos aspectos de la fuente para estilizar el elemento.

.tooltip {
    display: none;
    position: absolute;
    width: 200px;    
    padding: 10px;
    margin: 0 0 12px 0;    
    z-index: 100;
    bottom: 100%;
    background: #FDD017;
    color: #fff;
    text-align: center;
    font-weight: bold;
    font-size: 11px;
}

Finalmente definimos el estilo de la flecha que lucirá en la parte inferior del tooltip, para ello haremos uso de los pseudo elementos “after” y “before”. El estilo que le demos a ambos definirá cada mitad de la forma de la flecha, por lo que al juntarlos tendremos la flecha completa.

.tooltip:after {
    content: "";
    position: absolute;
    bottom: -14px;
    z-index: 100;
    border: 0 solid #FDD017;
    border-bottom: 14px solid transparent;
    border-left-width: 10px;
    width: 50%;
    left: 50%;
}
 
.tooltip:before {
    content: "";
    position: absolute;
    border: 0 solid #FDD017;
    bottom: -14px;
    z-index: 100;
    border-right-width: 10px;
    border-bottom: 14px solid transparent;
    width: 50%;
    right: 50%;
}

Uso de jQuery para desplegar el tooltip

El último paso a realizar es establecer la funcionalidad de despliegue de nuestro tooltip, para ello haremos uso de jQuery y definiremos un par de funciones. Utilizaremos los eventos “mouseenter” y “mouseleave” para disparar nuestras funciones, dichos eventos se producen cuando ponemos el mouse sobre un elemento y cuando lo retiramos.
Al momento de poner el mouse sobre el elemento (mouseenter) debemos obtener la posición del mouse para calcular donde colocar el tooltip, después obtenemos el texto del atributo “title” para poder desplegarlo, lo añadimos al div que define nuestro tooltip y finalmente mediante la función “fadeIn” mostramos la descripción.

jQuery("a").mouseenter(function (e) {             
    var posMouse = e.pageX - this.offsetLeft; 
    var textoTooltip = jQuery(this).attr("title"); 
			
    if (textoTooltip.length > 0) {
        jQuery(this).append('
<div class="tooltip">' + textoTooltip + '</div>;

');
        jQuery("a <div.tooltip").css("left", "" + posMouse - 103 + "px");
        jQuery("a <div.tooltip").fadeIn(300);
    }
});

Como se puede apreciar en nuestro selector de jQuery únicamente estamos especificando los elementos de tipo enlace “a”, si quisiéramos agregar más elementos o especificar ciertos tipos de enlaces, tendríamos que modificar ese selector.
Al momento de retirar el mouse del elemento (mouseleave) llamaremos a la función “fadeOut” que agrega una transición para desaparecer nuestro tooltip, finalmente removemos el elemento del marcado con la función “remove” después de introducirlo en una cola mediante al función “queue” para que el remover se aplique hasta que el efecto haya terminado.

jQuery("a").mouseleave(function () {             
    jQuery("a &gt; div.tooltip").fadeOut(300).delay(300).queue(function () {
        jQuery(this).remove();
        jQuery(this).dequeue();
    });
});

Mostrar un tooltip con datos recuperados del servidor en forma asincrónica

Implementaremos un problema utilizando todos los conceptos aprendidos hasta ahora.

ProblemaImplementar un Tooltip con jQuery recuperando la información a mostrar del servidor en forma asincrónica.
Agregar una imagen al tooltip. En el servidor ya hay cuatro imágenes llamadas imagen1.jpg, imagen2.jpg etc. y se encuentran en el directorio donse se almacenan las páginas. ( <img src="imagen1.jpg"> )

<!DOCTYPE html>
<html>

<head>
  <title>Ejemplo de jQuery</title>
  <meta charset="UTF-8">
  <link rel="StyleSheet" href="estilos32.css" type="text/css">
</head>

<body>
  <p>Entre con el mouse al recuadro.</p>
  <div class="cuadradito" id="c1"></div>
  <div class="cuadradito" id="c2"></div>
  <div class="cuadradito" id="c3"></div>
  <div class="cuadradito" id="c4"></div>

  <script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
  <script src="func32.js"></script>
</body>

</html>
Ver ejemplo anterior

estilos32.css

.cuadradito{
  background-color: #f00;
  height: 50px; 
  width: 50px;
  margin:3px;
  z-index: -1;
}

#divmensaje {
  background-color: yellow;
   position: absolute; 
   padding: 5px;
   width:250px;
   left:120px;
   top:100px;
  z-index: 100;
}

func32.js

$(document).ready(function () {
  $("body").append('<div id="divmensaje">hhhh</div>');
  $("#divmensaje").hide();
  $(".cuadradito").hover(function (e) {
    $("#divmensaje").show();
    $("#divmensaje").css("left", e.clientX + document.body.scrollLeft + 5);
    $("#divmensaje").css("top", e.clientY + document.body.scrollTop + 5);
    $("#divmensaje").load("pag32.php?cod=" + $(this).attr('id'));
  },
    function () {
      $("#divmensaje").hide();
    })
  $(".cuadradito").mousemove(function (e) {
    $("#divmensaje").css("left", e.clientX + document.body.scrollLeft + 5);
    $("#divmensaje").css("top", e.clientY + document.body.scrollTop + 5);
  })
})

pag32.php

<?php
  if ($_REQUEST['cod']=='c1')
  {
    echo "<img src=imagen1.jpg">";
    echo "<p>Primer tooltip.</p>";
   
  }
  if ($_REQUEST['cod']=='c2')
  {    
    echo "<img src=imagen2.jpg>";
    echo "<p>Segundo tooltip.</p>";
   
  }
  if ($_REQUEST['cod']=='c3')
  {
    echo "<img src=imagen3.jpg>";
    echo "<p>Tercer tooltip.</p>";
  }
  if ($_REQUEST['cod']=='c4')
  {
    echo "<img src=imagen4.jpg">";
    echo "<p>Cuarto tooltip.</p>";
  }

?>

Como podemos ver el código JavaScript utilizando la librería jQuery queda muy compacto y reducido:

$(document).ready(function () {
  $("body").append('<div id="divmensaje">hhhh</div>');
  $("#divmensaje").hide();
  $(".cuadradito").hover(function (e) {
    $("#divmensaje").show();
    $("#divmensaje").css("left", e.clientX + document.body.scrollLeft + 5);
    $("#divmensaje").css("top", e.clientY + document.body.scrollTop + 5);
    $("#divmensaje").load("pagina1.php?cod=" + $(this).attr('id'));
  },
    function () {
      $("#divmensaje").hide();
    })
  $(".cuadradito").mousemove(function (e) {
    $("#divmensaje").css("left", e.clientX + document.body.scrollLeft + 5);
    $("#divmensaje").css("top", e.clientY + document.body.scrollTop + 5);
  })
})