CSS :hover Pseudoclase
Aprende cómo funciona la pseudoclase CSS :hover, cómo combinarla con transitions y cómo manejar dispositivos táctiles y accesibilidad correctamente.
La pseudoclase :hover coincide con un elemento mientras el puntero del usuario está posicionado sobre él. Se activa en cuanto el puntero entra en el elemento y se desactiva en el momento en que el puntero se aleja — no se requiere ningún clic.
Esta página cubre:
- Sintaxis básica y cómo apuntar a enlaces, botones y cualquier elemento
- Combinar
:hovercontransitionpara efectos animados suaves - Pasar el cursor sobre un padre para revelar o reestilizar sus hijos (patrón dropdown)
- Restringir estilos de hover con
@media (hover: hover)para seguridad en dispositivos táctiles - Requisitos de accesibilidad y la combinación con
:focus/:focus-within
Sintaxis
selector:hover {
/* declarations applied while pointer is over the element */
}El selector puede ser cualquier selector CSS válido — elemento, clase, ID o una cadena de combinadores.
Estilizar enlaces al pasar el cursor
El uso más común de :hover es cambiar la apariencia de los enlaces de anclaje. Para un estilizado predecible de los enlaces, declara las reglas en orden LVHA: :link, :visited, :hover, :active. Este orden garantiza que las pseudoclases posteriores puedan sobrescribir las anteriores sin sorpresas de especificidad.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
a:hover {
background-color: #8ebf42;
color: #666;
}
</style>
</head>
<body>
<h2>:hover selector example</h2>
<a href="https://www.w3docs.com/">W3docs.com</a>
</body>
</html>Mueve el puntero sobre el enlace para ver cómo cambia el fondo y el color del texto.
Hover en enlaces de texto en línea
Cuando un enlace aparece dentro de un párrafo, :hover sigue apuntando solo a ese elemento <a> — el texto circundante no se ve afectado.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
a {
color: #1c87c9;
}
a:hover {
background-color: #555;
color: #eee;
}
</style>
</head>
<body>
<h2>:hover selector example</h2>
<p>Lorem Ipsum is simply dummy text of the printing and <a href="#">typesetting</a> industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into <a href="#">electronic</a> typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like <a href="#">Aldus PageMaker</a> including versions of Lorem Ipsum.</p>
</body>
</html>Hover en elementos de bloque
:hover funciona en cualquier elemento, no solo en los enlaces. Aplicarlo a un <div> permite crear efectos interactivos de tarjeta o panel.
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
div {
padding: 30px;
background-color: #8ebf42;
color: #eee;
}
div:hover {
background-color: #444;
color: #fff;
}
</style>
</head>
<body>
<h2>:hover selector example</h2>
<div>
Lorem ipsum is simply dummy text...
</div>
</body>
</html>Efectos de hover suaves con transition
Una regla :hover simple cambia los estilos de forma instantánea. Añadir una transition en el selector base (no en la regla :hover) hace que el navegador anime el cambio en ambas direcciones — cuando el puntero entra y cuando sale.
.button {
background-color: #1c87c9;
color: #fff;
padding: 0.5rem 1.2rem;
border: none;
border-radius: 4px;
cursor: pointer;
/* Place transition on the base rule, not :hover */
transition: background-color 0.25s ease, box-shadow 0.25s ease;
}
.button:hover {
background-color: #145e8a;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}Si colocas transition solo dentro de la regla :hover, la animación se reproduce al entrar pero vuelve instantáneamente al salir — un error común de principiantes.
Puedes aplicar la transición a varias propiedades separándolas con comas, o usar transition: all 0.25s ease como abreviatura (aunque apuntar a propiedades específicas es mejor para el rendimiento).
Hover en un padre para estilizar sus hijos
:hover puede ser parte de un selector combinador para reaccionar al estado hover de un padre y estilizar un descendiente. Esta es la base de los menús de navegación desplegables y los efectos de revelar al pasar el cursor.
/* Card image starts dimmed; brightens when the card is hovered */
.card .card-image {
opacity: 0.75;
transition: opacity 0.2s ease;
}
.card:hover .card-image {
opacity: 1;
}
/* Reveal an overlay label on hover */
.card .card-label {
display: none;
}
.card:hover .card-label {
display: block;
}Patrón de menú desplegable
.nav-item .dropdown {
display: none;
position: absolute;
top: 100%;
left: 0;
}
.nav-item:hover .dropdown {
display: block;
}Los menús que solo funcionan con hover son inaccesibles para usuarios de teclado y táctiles. Combina :hover con :focus-within para que el menú también se abra cuando un elemento hijo recibe el foco mediante la navegación por teclado:
.nav-item:hover .dropdown,
.nav-item:focus-within .dropdown {
display: block;
}Restringir estilos de hover para dispositivos táctiles
Muchos dispositivos con pantalla táctil simulan un hover al tocar, lo que puede dejar los estilos "pegados" hasta que el usuario toque en otro lugar. Para evitarlo, envuelve las reglas específicas de hover en una media query que compruebe si el dispositivo de entrada principal admite realmente el hover:
/* Only apply on devices with a real pointer (mouse, trackpad) */
@media (hover: hover) {
.card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
}
}La media feature hover: hover es ampliamente compatible con los navegadores modernos. En dispositivos solo táctiles, el bloque simplemente se ignora, por lo que los estilos base permanecen limpios.
También puedes combinarlo con pointer: fine para apuntar a dispositivos de puntero precisos (ratón/trackpad) mientras se excluyen los imprecisos (táctil):
@media (hover: hover) and (pointer: fine) {
.button:hover {
background-color: #145e8a;
}
}Accesibilidad: combinar :hover con :focus
Los usuarios de teclado navegan con la tecla Tab, lo que activa :focus en lugar de :hover. Si tus estilos de hover transmiten retroalimentación visual importante (como resaltar el elemento de navegación activo), aplica los mismos estilos a :focus para que los usuarios de teclado reciban una retroalimentación equivalente:
/* Always pair hover and focus for interactive elements */
a:hover,
a:focus {
outline: 2px solid #1c87c9;
outline-offset: 2px;
text-decoration: underline;
}Para componentes compuestos (como una tarjeta que contiene un botón), :focus-within permite estilizar el padre cuando cualquier hijo tiene el foco:
.card:hover,
.card:focus-within {
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}Efectos de hover en otras propiedades
:hover no se limita a los colores. Cualquier propiedad CSS animable puede activarse o transicionarse al pasar el cursor:
| Propiedad | Efecto de hover típico |
|---|---|
opacity | Aparición/desaparición gradual de superposiciones o UI secundaria |
transform | Escalar, trasladar o rotar un elemento |
box-shadow | Añadir profundidad a tarjetas y botones |
color | Cambiar el color del texto o del icono |
cursor | Indicar que un elemento es interactivo |
Buenas prácticas
- Combina
:hovercon:focuspara que los usuarios de teclado reciban la misma retroalimentación visual:a:hover, a:focus { ... }. - Restringe las animaciones de hover con
@media (hover: hover)para evitar estados pegados en dispositivos táctiles. - Coloca
transitionen la regla base, no dentro de:hover, para que la animación se aplique en ambas direcciones. - No ocultes contenido esencial que solo aparezca al pasar el cursor — es invisible para los usuarios táctiles y puede pasarse por alto con lectores de pantalla.
- Combina los menús de hover con
:focus-withinpara que la navegación por teclado pueda abrirlos sin ratón. - Sigue el orden LVHA al estilizar enlaces:
:link,:visited,:hover,:active.
Compatibilidad con navegadores
:hover es compatible con todos los navegadores modernos y lo ha sido desde IE 7 para la mayoría de los elementos (IE 6 solo lo admitía en etiquetas <a>). La media query @media (hover: hover) es compatible con Chrome 41+, Firefox 64+, Safari 9+ y Edge 79+.