JASoft.org

El blog de José Manuel Alarcón Aguín. Programación web y mucho más...

MENÚ - JASoft: JM Alarcón

Cómo hacer Tooltips personalizados solamente con CSS

Los tooltips son esas ventanitas flotantes pequeñas de color amarillo que aparecen cuando pasas por encima de algunos elementos de las interfaces de usuario de muchas aplicaciones. Los controla el sistema y poco puedes hacer para controlar su aspecto o ubicación.

En el caso concreto de la Web, las páginas HTML solamente ofrecen este tipo de tooltips en caso de que utilicemos el atributo title de algunos elementos:

Pero en el caso de querer mostrarlo en elementos concretos de un texto, por ejemplo, no tendremos tanta suerte. Además de que no podemos controlar el aspecto que tienen ni cómo se muestran.

Mediante JavaScript es fácil detectar el movimiento del cursor sobre un determinado elemento o un trozo de texto y mostrar una capa con el aspecto que deseemos en el lugar que queramos, pero no deja de ser un trabajo pesado y tedioso, además de propenso a errores y que carga un poco más la página.

En este post voy a explicar cómo podemos crear tooltips con el aspecto que deseemos, que aparezcan donde queramos y utilizando exclusivamente  CSS, sin escribir nada de código.

Para ello haremos uso de varias cuestiones fundamentales de CSS.

  • Elementos de datos de HTML5
  • Pseudo-elementos y pseudo-clases de CSS
  • La función CSS attr()
  • Posicionamiento de elementos

entre otras, y las utilizaremos para crear tooltips automáticos al pasar por encima de ciertas palabras de un texto, sin usar JavaScript.

El efecto que queremos conseguir es este:

Fíjate en cómo al pasar por encima se muestra el tooltip, que tiene el fondo negro semi-transparente para dejar ver un poco lo que hay debajo, y el texto blanco, con los bordes redondeados, pero podría tener el aspecto que quisiésemos, limitados tan solo por las propiedades CSS que le podamos aplicar (que son muchas).

¡Vamos allá!

 Para conseguir el efecto de tooltip, lo que tenemos que hacer es, en primer lugar, definir qué palabras o conjuntos de palabras van a mostrarlos, para lo cual deberemos rodearlos con algún elemento (generalmente un <span>) marcado con alguna clase que denote que es un tooltip. En un alarde de originalidad vamos a llamar a dicha clase .tooltip:

JavaScript es un <span class="tooltip">lenguaje de programación</span> interpretado,

De este modo denotaremos que esas palabras ("lenguaje de programación") van a mostrar un tooltip y además podemos usar también esta clase para darle un aspecto ligeramente distinto de modo que sean fáciles de localizar. Por ejemplo, en este caso yo les he puesto un borde inferior a rayas y les he cambiado el cursor:

span.tooltip {
border-bottom: 1px dashed gray;
cursor: pointer;
position:relative;
}

Además fíjate en otra cosa importante: le he colocado un position:relative;. El objeto de esto es crear un sistema de referencia para posicionamiento dentro de este elemento que me permitirá ahora colocar otros elementos (el tooltip) dentro de él de modo que estén posicionados como necesite a partir de los bordes de la caja de este <span>.

Si no sabes bien de qué va esto me temo que te toca repasar el modelo de cajas y cómo funciona el posicionamiento de elementos en HTML. Te puedo sugerir un recurso sensacional en el que aprenderás eso y mucho más apoyado por mi para resolverte las dudas.

Bien. Ahora hace falta decidir el contenido del tooltip y luego mostrarlo.

Lo primero lo conseguiremos mediante el uso de atributos de tipo data- de HTML5. Estos atributos están diseñados para poder incluir información extra de cualquier tipo dentro de una etiqueta HTML sin necesidad de recurrir a atributos existentes o inventarse atributos nuevos. Ofrecen una API específica en JavaScript para poder leerlos y escribirlos y además se validan perfectamente como HTML correcto semánticamente, por lo que no te darán problemas si tu web tiene que estar validada.

En nuestro caso vamos a definir un atributo data-info (pero podríamos haberle llamado de cualquier manera) para meter la información del tooltip:

<span class="tooltip" data-info="Un lenguaje de programación es...">

con el texto del tooltip metido en el atributo (lo he abreviado aquí con puntos suspensivos).

Para generar el tooltip a partir de este contenido lo que haremos será utilizar el pseudo-elemento CSS ::before. Éste genera un elemento "ficticio", que antes no estaba, y que se coloca antes del contenido del elemento al que se le aplica. De modo que si escribiese:

span.tooltip::before {
    content: 'Un texto aquí';
}

Lo que obtendría sería un elemento colocado dentro del span pero antes del contenido de éste con el texto 'Un texto aquí'.

Sabiendo esto lo tenemos muy fácil y solo nos faltan dos detalles por solucionar:

  • ¿Cómo ponemos en este elemento el contenido del texto del tooltip?
  • Cómo hacemos que se muestre al pasarle por encima solamente?

Para lo primero tenemos que echar mano de la función CSs llamada attr(). Ésta lo que hace es obtener el valor de un atributo que le indiquemos del elemento sobre el que está actuando, en función del selector CSS. Dado que el texto del tooltip lo tenemos en el atributo data-info, lo que tenemos que escribir es simplemente:

span.tooltip::before {
    content: attr(data-info);
}

 

Con lo que ya tendremos el contenido deseado. Ahora debemos, en primer lugar, ocultar este elemento ya que solo queremos que se vea cuando le pasemos por encima con el curso, darle un aspecto determinado que es el que queremos que tenga, y además (muy importante) posicionarlo de manera apropiada para que se vea bien al pasarle por encima.

Para esto último, como el span forma ahora un sistema de referencia porque tiene posición relativa, lo único que tenemos que hacer es posicionarlo de modo relativo o absoluto dentro de éste, por lo que no es muy difícil:

span.tooltip::before {
    display: none; /* Lo ocultamos*/
    content: attr(data-info);
    color: white;
    font-size: 0.8em;
    padding: 2px 8px;
    background: rgba(0,0,0,0.8);
    border-radius: 5px;
    position: absolute; /* Lo posicionamos de modo absoluto dentro del span */
    top: 1.5em;
    left: 5px;
    min-width: 500px;
    z-index: 999;
}

Ahora ya tenemos nuestro tooltip con el aspecto deseado y la posición apropiada, justo debajo del texto que hemos marcado con el span. Aunque, eso sí, oculto de momento.

Nota: le he colocado un ancho mínimo porque si no lo hacemos tomará como ancho exactamente el mismo que tenga el elemento que lo contiene, es decir, el texto de las palabras seleccionadas para mostrar el tooltip. Si tenemos palabras cortas se quedaría muy estrecho y crecería hacia abajo, quedando feo.

De acuerdo. Lo único que nos falta es mostrar el nuevo elemento cuando pasemos el cursor por encima. Esto clama a una pseudo-clase :hover, como en los enlaces. Pero ¿cómo combinamos esta pseudo-clase con el pseudo-elemento ::before que queremos mostrar? Muy fácil así:

span.tooltip:hover::before {
    display: block;
}

Con esto lo que le estamos diciendo al navegador es que cuando se pase por encima de un elemento span con la clase .tooltip aplicada, le aplique a su pseudo-elemento ::before la propiedad display:block, que anula la que tiene por defecto (display:none), y por lo tanto lo que va a hacer es mostrarlo.

¡Listo! Con esto ya tenemos un sistema de tooltips funcional, tal y como queríamos.

Te dejo aquí la página de ejemplo que he creado (ZIP, 1.13KB), de la que grabé la animación del principio, para que puedas verlo todo junto. Verás que es bastante sencillo, pero he querido explicarlo a fondo para que no quede lugar a muchas dudas.

Una cosa importante: el problema de utilizar los tooltips de esta manera es que no cumplen con las reglas de accesibilidad AA de la W3C. Si necesitas que tu sitio sea accesible tendrías que añadirle también la info del tooltip al elemento mediante atributos ARIA. Otra opción es añadirlos automáticamente usando JavaScript (no me gusta mucho, pero no soy experto en accesibilidad) o directamente usar el atributo ARIA para tomar el valor (por ejemplo aria-label) y no utilizar el atributo data- como hemos hecho ahora. La decisión es tuya, pero debes ser consciente de este detalle.

¡Espero que te resulte útil!

José Manuel Alarcón José Manuel Alarcón
Fundador de campusMVP.es, el proyecto de referencia en formación on-line para programadores en lengua española. Autor de varios libros y cientos de artículos. Galardonado como MVP de Microsoft desde 2004. Gallego de Vigo, amante de la ciencia y la tecnología, la música y la lectura. Ayudando a la gente en Internet desde 1996.
Descarga GRATIS mi último libro (no técnico): "Tres Monos, Diez Minutos".
Banner

Comentarios (5) -

Sebastián Palacio

Muchas gracias, me ha servido mucho. (y)

Responder

Óscar Domínguez

Buenas tardes,

Veo un pequeño inconveniente en el código.
Tal y como lo has preparado el tooltip crece de arriba a abajo, de manera que si el texto <span> que es relativo tiene dos lineas; como por ejemplo al caer la linea; el before, se supondrá a parte del texto inferior...impidiendo una correcta visualización.
Si me permites, yo lo modificaría de la siguiente manera:

span.tooltip::before {
   /* resto igual */
   /* top: 1.5em; *//* borramos*/
   top: 100%; /* añadimos */
}

De esta manera el tooltip crecerá desde la parte mas inferior que encuentre hasta donde necesite.

Un saludo

Responder

by Jose M. Alarcon

Hola Óscar:

Me fallaron las notificaciones del blog y no me enteré de tu comentario. Sorry.

Gracias por la aportación. Mi intención de todos modos no era tanto hacer una implementación correctísima y lista para ser usada en cualquier sitio de este tema, sino explicar una técnica concreta, que luego cada uno adaptaría a sus circunstancias, cómo quiere recibir la información, etc... De todos modos tu añadido hace que el ejemplo se vea mejor, sin duda. Gracias.

Saludos!

Responder

Carlos David Correa Santillan

Muy útil pero hay un inconveniente, tengo una fila de varias imágenes y justo en las ultimas a la derecha, el globo se pierde hacia el costado en vez de detectar el limite y tirar para la izquierda como lo hace el original, osea que se acomoda automáticamente según la posición en la pagina, me mostrarías cual seria tu solución por que a mi me tiene de cabeza la verdad, igual te agradezco el aporte.

Responder

by Jose M. Alarcon

Hola Carlos:

Para hacer eso necesitas un poco de JavaScript. Utiliza mi biblioteca OPen Source YACSSTooltip para conseguirlo fácilmente: www.jasoft.org/.../...-de-imagenes-con-jquery.aspx

Saludos.

Responder

Agregar comentario