Creación de un Tooltip con CSS Puro
Si necesitas un tooltip ligero y no quieres recurrir a una librería de JavaScript para construirlo, CSS por sí solo puede encargarse del trabajo sorprendentemente bien. Sin dependencias, sin event listeners — solo unas cuantas reglas CSS bien colocadas.
Este artículo recorre una implementación práctica y moderna utilizando pseudo-elementos, atributos data y transiciones, junto con las consideraciones de accesibilidad que realmente necesitas conocer.
Puntos Clave
- Un tooltip con CSS puro se puede construir usando un pseudo-elemento
::after,content: attr(data-tooltip)y un disparador:hover/:focus-visible. - Usa
opacityyvisibility(nodisplay) para que el tooltip pueda aparecer y desaparecer con un fundido suave. pointer-events: noneevita el parpadeo al impedir que el propio tooltip reciba eventos de hover.- Los tooltips en CSS tienen limitaciones reales de accesibilidad — no llegan de forma fiable a los lectores de pantalla y el comportamiento del hover es inconsistente en dispositivos táctiles.
- Para indicaciones críticas en la UI, recurre a JavaScript, la Popover API o referencias adecuadas con
aria-describedbyapuntando a elementos visibles.
Cómo Funciona un Tooltip con CSS Puro
La idea central es simple: aplica position: relative al elemento disparador, luego utiliza un pseudo-elemento ::after como la burbuja del tooltip, posicionado de forma absoluta respecto a su elemento padre. Ocúltalo por defecto y muéstralo en :hover y :focus-visible.
Como los pseudo-elementos no pueden leer directamente desde el DOM, debes pasar el texto del tooltip mediante un atributo data-tooltip y traerlo con content: attr(data-tooltip). Esto mantiene tu HTML limpio y evita duplicar texto en un <span> oculto.
La Estructura HTML
<button
class="tooltip-trigger"
data-tooltip="Saves your current progress"
>
Save
</button>
Es importante usar un <button> o un ancla (<a>) como elemento disparador. Estos elementos son enfocables de forma nativa, lo que significa que los usuarios de teclado pueden alcanzarlos sin trabajo adicional.
Nota: Si quieres usar
aria-describedby, debe apuntar alidde un elemento real y visible en el DOM — no a un pseudo-elemento. Dado que esta técnica utiliza::after, omitearia-describedbya menos que también renderices el texto del tooltip dentro de un elemento real.
El CSS
.tooltip-trigger {
position: relative;
cursor: pointer;
}
/* Tooltip bubble */
.tooltip-trigger::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
transform: translateX(-50%);
background-color: #1a1a1a;
color: #fff;
font-size: 0.8rem;
white-space: nowrap;
padding: 5px 10px;
border-radius: 4px;
/* Hidden by default */
opacity: 0;
visibility: hidden;
transition: opacity 0.2s ease, visibility 0.2s ease;
z-index: 10;
pointer-events: none;
}
/* Show on hover and keyboard focus */
.tooltip-trigger:hover::after,
.tooltip-trigger:focus-visible::after {
opacity: 1;
visibility: visible;
}
¿Por Qué opacity + visibility en Lugar de display?
Alternar entre display: none y display: block no admite transiciones — el tooltip simplemente aparecería y desaparecería de golpe. Usar opacity junto con visibility: hidden te permite hacer un fundido suave del tooltip mientras lo eliminas de la interacción del puntero cuando está oculto. Combinar visibility con opacity también evita que el tooltip oculto siga siendo visualmente interactivo.
¿Por Qué pointer-events: none?
Sin esa regla, la propia burbuja del tooltip puede activar un estado de hover, causando que el tooltip parpadee a medida que el cursor pasa sobre él. Establecer pointer-events: none en el elemento ::after lo evita por completo.
Discover how at OpenReplay.com.
¿Por Qué transform: translateX(-50%) para Centrar?
Establecer left: 50% mueve el borde izquierdo del tooltip al centro del disparador. Luego, el desplazamiento translateX(-50%) lo retrae la mitad de su propio ancho, centrándolo independientemente del ancho del texto del tooltip — sin necesidad de cálculos manuales en píxeles.
Limitaciones de Accesibilidad que Debes Conocer
Un tooltip por hover en CSS puro tiene limitaciones reales:
- Es posible que los lectores de pantalla no lo anuncien. La propiedad
contenten un pseudo-elemento no es leída de forma fiable por todos los lectores de pantalla. Para información crítica, inclúyela en la UI visible o usaaria-describedbyapuntando a un elemento real. - El comportamiento del hover es inconsistente en dispositivos táctiles. No se debe depender de tooltips solo en CSS para información esencial.
- Sin role ni live region. CSS por sí solo no puede comunicar la semántica del tooltip a las tecnologías de asistencia.
Para indicaciones complementarias simples sobre elementos interactivos, un tooltip en CSS está bien. Para cualquier cosa esencial para completar una tarea, querrás JavaScript que gestione el foco, el anuncio y el estado ARIA.
Mirando Hacia Adelante: CSS Anchor Positioning y la Popover API
CSS Anchor Positioning hace que el posicionamiento de tooltips sea mucho más flexible — puedes anclar un tooltip a cualquier elemento sin depender de position: relative en el padre. El soporte de navegadores para Anchor Positioning ya está ampliamente disponible en navegadores modernos según Can I Use.
Para un comportamiento interactivo más rico, vale la pena explorar la Popover API como una alternativa nativa para UI flotante interactiva.
Conclusión
Un tooltip con CSS puro construido con ::after, content: attr(data-tooltip) y una transición de visibility/opacity es limpio, rápido y libre de dependencias. Combínalo con :focus-visible para soporte de teclado y tendrás una base sólida. Solo sé honesto acerca de dónde se quedan cortos los tooltips en CSS — para cualquier cosa más allá de indicaciones complementarias, recurre a JavaScript o a una característica nativa de la plataforma como la Popover API.
Preguntas Frecuentes
Sí. La posición se controla mediante las propiedades de desplazamiento en el pseudo-elemento. Usa bottom con calc(100% + 8px) para colocarlo arriba, top con calc(100% + 8px) para colocarlo abajo, o usa right y left para una colocación horizontal. También puedes crear clases variantes como tooltip-bottom o tooltip-right que sobrescriban estas propiedades.
El comportamiento del hover es inconsistente en dispositivos táctiles, por lo que no se debe depender de los tooltips solo en CSS para información esencial. Si el contenido de tu tooltip importa en el móvil, renderízalo en un elemento real controlado por JavaScript, o usa la Popover API, que proporciona una base más robusta para UI flotante interactiva en distintos tipos de entrada.
La regla white-space: nowrap mantiene los tooltips en una sola línea, lo que puede desbordar pantallas estrechas. Reemplázala con un max-width y permite el ajuste de línea, por ejemplo max-width: 240px y white-space: normal. Para detección dinámica de bordes, necesitarás JavaScript o CSS Anchor Positioning, que admite un comportamiento de posicionamiento nativo más flexible en navegadores modernos.
Es aceptable para indicaciones complementarias y no esenciales sobre elementos enfocables como botones y enlaces. No es suficiente cuando el tooltip contiene información necesaria para completar una tarea, ya que el contenido de los pseudo-elementos no es anunciado de forma fiable por los lectores de pantalla y el comportamiento del hover es inconsistente en dispositivos táctiles. Para contenido crítico, usa un elemento real del DOM con aria-describedby y un comportamiento gestionado mediante JavaScript, o considera la Popover API.
Truly understand users experience
See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..