Efecto Hover: Aprende a usarlo correctamente en tus estilos CSS
La pseudo-clase :hover es, sin duda, una de las más utilizadas en CSS, ya que nos permite definir un segundo estado para cualquier elemento cuando el usuario interactúa con él, por ejemplo, al pasar el cursor por encima. Esta pseudo-clase existe desde los inicios del estándar de CSS, cuando aún no existían las pantallas táctiles.
Sin embargo, al utilizarla en este tipo de dispositivos, puede presentar comportamientos inesperados, dependiendo del navegador. Por ejemplo, podría no funcionar correctamente, generar destellos en el elemento con el estado hover o hacer que el elemento quede como si tuviera el foco activo, obligando al usuario a tocar otra parte de la pantalla para que pierda el efecto hover.
Para evitar estos efectos secundarios al usar la pseudo-clase :hover, muchos desarrolladores web optaron por utilizar media queries con tamaños mínimos de pantalla, por ejemplo:
button { color: #fff; background: dodgerblue;}
@media (min-width: 1000px) { button:hover { background: blue; }}Sin embargo, debido a la evolución de las pantallas —como el aumento en la densidad de píxeles o la aparición de laptops con pantallas táctiles—, este enfoque dejó de ser suficiente.
Por ello, se introdujo un nuevo estándar en CSS que permite identificar si un dispositivo cuenta con un cursor o no, brindando una forma más precisa de controlar los estilos según las capacidades del dispositivo.
Interaction Media Features
Las Interaction Media Features forman parte del estándar Media Queries Level 4 y constituyen un conjunto de consultas que nos permiten detectar el tipo de interacción disponible en el dispositivo del usuario —por ejemplo, si utiliza un cursor, una pantalla táctil o ambos—.
Estas media queries nos ofrecen una forma más precisa de adaptar la experiencia de usuario según las capacidades de interacción del dispositivo.
Entre las principales media queries del estándar se encuentran:
Y si te preguntas por su soporte en los navegadores modernos, no hay razón para no empezar a usarlas: cuentan con una excelente compatibilidad.
Puedes consultar los datos más actualizados sobre compatibilidad en el siguiente enlace: https://caniuse.com/css-media-interaction
Media Pointer
La media query pointer nos permite identificar si el usuario dispone de un dispositivo de entrada con puntero (por ejemplo, un mouse o un stylus) y determinar su nivel de precisión.
Gracias a esto, podemos adaptar la experiencia de usuario según el tipo de dispositivo que esté utilizando.
Esta media query admite tres valores posibles:
coarse: Indica que el dispositivo tiene una precisión limitada, como una pantalla táctil.fine: Señala que el dispositivo cuenta con un puntero de alta precisión, como un mouse o trackpad.none: Indica que el usuario no dispone de ningún dispositivo de entrada con puntero.
¿Cómo utilizar la media query pointer?
Podemos emplearla para modificar el comportamiento o la apariencia de los elementos dependiendo del tipo de entrada detectado.
Utilizando el valor coarse
/* Color de fondo del botón por defecto (en pantallas no táctiles). */button { background: lightblue;}
/* Si el dispositivo es táctil cambiamos el color de fondo y el texto del botón. */@media (pointer: coarse) { button { background: dodgerblue; color: #fff; }}En este ejemplo, los dispositivos táctiles (con punteros de baja precisión) aplicarán el segundo bloque de estilos, mientras que los dispositivos con mouse mantendrán el estilo predeterminado.
Utilizando el valor fine
/* Color de fondo del botón por defecto (en pantallas táctiles). */button { background: lightblue;}
/* Si el dispositivo NO es táctil cambiamos el color de fondo y el texto del botón. */@media (pointer: fine) { button { background: dodgerblue; color: #fff; }}En este caso, los estilos dentro de la media query se aplicarán únicamente en dispositivos con puntero preciso, como computadoras de escritorio o portátiles con mouse o trackpad.
Los dispositivos táctiles mantendrán el estilo base definido fuera de la media query.
Media Hover
La media query hover permite detectar si el dispositivo de entrada principal del usuario puede “flotar” sobre un elemento, como ocurre con un cursor de mouse.
Para comprender su utilidad, primero debemos entender cómo funciona el efecto :hover.
¿Cómo funciona el efecto hover?
Cuando aplicamos la pseudo-clase :hover a un elemento, esta se activa cuando el cursor se posiciona sobre él sin hacer clic.
Esa es precisamente la clave: en las pantallas táctiles no existe un cursor que flote sobre los elementos, por lo que el comportamiento del hover puede ser inconsistente o incluso inexistente.
La media query hover admite dos valores posibles:
hover: Indica que el usuario cuenta con un dispositivo capaz de flotar sobre un elemento (por ejemplo, un mouse o trackpad).none: Indica que el dispositivo no posee esa capacidad (por ejemplo, una pantalla táctil).
¿Cómo utilizar la media query hover?
Podemos combinar la pseudo-clase :hover con la media query hover para aplicar efectos solo cuando el dispositivo lo permita:
button { background: palegreen;}
/* Si el dispositivo puede usar el efecto hover, aplicamos los estilos correspondientes. */@media (hover: hover) { button:hover { background: mediumseagreen; color: #fff; }}De esta forma, evitamos aplicar estilos de hover en dispositivos táctiles, asegurando una experiencia más coherente y sin comportamientos inesperados.
Limitaciones de las Media Queries pointer y hover
Aunque las media queries pointer y hover son herramientas muy útiles para adaptar la experiencia del usuario según su dispositivo, presentan una limitación importante: no consideran que un mismo dispositivo puede contar con múltiples tipos de entrada.
Estas media queries detectan únicamente el tipo de entrada principal, sin tomar en cuenta otras entradas secundarias que también puedan estar activas.
¿Qué tipos de entradas existen?
En general, los usuarios pueden interactuar en un sitio web mediante una pantalla táctil o un puntero (como un mouse o trackpad).
Sin embargo, es importante distinguir entre la entrada principal y las entradas secundarias que un dispositivo puede tener.
A continuación, se detallan algunos casos comunes:
-
Teléfonos móviles y tablets:
Su entrada principal es táctil (
pointer: coarse), pero muchos dispositivos permiten conectar un mouse o trackpad vía Bluetooth. En estos casos, las media queriespointer: fineyhover: hoverno detectan correctamente el cambio cuando el usuario decide navegar con el mouse. -
Dispositivos con lápiz óptico:
Algunos equipos permiten usar stylus además de la pantalla táctil. Aquí, la media query
pointer: coarsepuede no ser suficiente, ya que el lápiz suele identificarse como un puntero de alta precisión (pointer: fine). -
Laptops con pantalla táctil:
En estos dispositivos, la entrada principal suele ser un cursor (
pointer: fine), pero si el usuario decide interactuar directamente con la pantalla táctil, las media queriespointer: fineyhover: hoverpierden relevancia, ya que el comportamiento cambia dinámicamente.
En resumen, estas limitaciones surgen porque pointer y hover se enfocan únicamente en la entrada primaria del dispositivo, sin contemplar los casos en los que un usuario puede alternar entre diferentes métodos de interacción.
En la siguiente tabla podrás ver cómo se comportan las media queries pointer y hover según los distintos tipos de entradas principales que puede tener un dispositivo:
| Media Query | Pantalla táctil | Pantalla táctil con Mouse | Laptop/Escritorio | Laptop/Escritorio con pantalla táctil |
|---|---|---|---|---|
| pointer: coarse | true | true | false | false |
| pointer: fine | false | false | true | true |
| pointer: none | false | false | false | false |
| hover: hover | false | false | true | true |
| hover: none | true | true | false | false |
En resumen, si únicamente queremos evaluar la entrada principal del dispositivo del usuario, podemos utilizar las media queries pointer y hover.
Sin embargo, si necesitamos un control más completo sobre todas las posibles formas de interacción que un usuario puede emplear (por ejemplo, usar simultáneamente una pantalla táctil y un mouse), entonces debemos recurrir a las media queries any-pointer y any-hover.
Media Any Pointer
La Media Query any-pointer tiene la capacidad de comprobar si cualquier tipo de dispositivo de entrada (ya sea táctil o con cursor) puede utilizar un puntero.
Es especialmente útil para detectar entradas secundarias que un usuario puede emplear, a diferencia de la Media Query pointer, que solo evalúa la entrada principal.
La Media Query any-pointer admite tres valores:
- coarse: El dispositivo del usuario posee al menos una entrada con precisión limitada (por ejemplo, una pantalla táctil).
- fine: El usuario dispone de al menos una entrada con precisión exacta (por ejemplo, un mouse o lápiz óptico).
- none: No hay ningún tipo de entrada que permita el uso de un cursor (esto no implica necesariamente que el dispositivo sea táctil).
¿Cómo utilizar la Media Query Any Pointer?
Podemos usar la Media Query any-pointer de las siguientes maneras:
Utilizando el valor coarse
/* Color de fondo del botón por defecto. */button { background: palevioletred;}
/* Si el dispositivo al menos tiene una entrada táctil cambiamos el color de fondo y el texto del botón. */@media (any-pointer: coarse) { button { background: mediumvioletred; color: #fff; }}Utilizando el valor fine
/* Color de fondo del botón por defecto. */button { background: palevioletred;}
/* Si el dispositivo al menos puede utilizar un cursor cambiamos el color de fondo y el texto del botón. */@media (any-pointer: fine) { button { background: mediumvioletred; color: #fff; }}Media Any Hover
Para verificar si al menos una entrada del dispositivo del usuario puede flotar sobre un elemento y activar el estado :hover, podemos utilizar la Media Query any-hover.
Esta media query resulta muy útil cuando, por ejemplo, en un móvil o tablet el usuario conecta un mouse o trackpad como entrada secundaria, evitando así la limitación de la Media Query hover, que solo evalúa la entrada principal.
La Media Query any-hover admite dos valores:
- hover: El dispositivo del usuario posee al menos una entrada que puede activar el estado hover en un elemento.
- none: No existe ningún tipo de entrada que pueda activar el estado hover.
¿Cómo utilizar la Media Query Any Hover?
Al emplear la Media Query any-hover, podemos combinarla con la pseudo-clase :hover:
button { background: lavender;}
@media (any-hover: hover) { button:hover { background: mediumpurple; color: #fff; }}Ventajas de la Media Any Pointer y Media Any Hover
Como seguramente ya habrás notado, la principal ventaja de estas dos media queries es su capacidad para detectar múltiples tipos de entrada que los usuarios puedan emplear, sin importar cuál sea la entrada principal del dispositivo.
Por esta razón, las media queries any-pointer y any-hover resultan mucho más convenientes en la mayoría de los casos.
En la siguiente tabla podemos comparar las media queries que detectan únicamente la entrada principal frente a aquellas que pueden identificar múltiples entradas en los distintos escenarios:
| Media Query | Pantalla táctil | Pantalla táctil con Mouse | Laptop/Escritorio | Laptop/Escritorio con pantalla táctil |
|---|---|---|---|---|
| pointer: coarse | true | true | false | false |
| pointer: fine | false | false | true | true |
| pointer: none | false | false | false | false |
| hover: hover | false | false | true | true |
| hover: none | true | true | false | false |
| any-pointer: coarse | true | true | false | true |
| any-pointer: fine | false | true | true | true |
| any-pointer: none | false | false | false | false |
| any-hover: hover | false | true | true | true |
| any-hover: none | true | false | false | false |
Otros casos de uso
Combinar media queries
Como probablemente ya sabes, es posible combinar media queries utilizando el operador and.
Esto nos permite realizar comprobaciones más específicas o complejas al trabajar con las Media Queries de Interaction Media Features. Por ejemplo:
@media (pointer: coarse) and (any-pointer: fine) { /* Evalúamos que la entrada principal sea táctil, pero que también el usuario podría usar algún dispositivo con precisión exacta, como un mouse. */}Detectar el tipo de entrada mediante JavaScript
En algunos casos, podríamos necesitar ejecutar código JavaScript que dependa del tipo de entrada del usuario.
Por ejemplo, podríamos querer detectar si el usuario está utilizando una pantalla táctil, un cursor o cualquier otro tipo de entrada, para adaptar la experiencia de uso según el caso.
const isPrimaryTouch = window.matchMedia('(pointer: coarse)').matches
// O también...const isTouch = window.matchMedia('(any-pointer: coarse)').matchesAunque podríamos utilizar el ejemplo anterior para detectar si el dispositivo puede usar una pantalla táctil y establecer Eventos Touch, no es del todo recomendable hacerlo, ya que los Eventos de Puntero también funcionan en este tipo de pantallas y ofrecen una excelente compatibilidad.
Incluso los clásicos Eventos del Mouse siguen siendo válidos en la mayoría de los casos.
Además, usar distintas APIs implicaría escribir código adicional (o duplicado) para manejar las validaciones, por lo que la elección dependerá de tus necesidades específicas.
Obviamente, no estamos limitados solo a estos casos de uso.
Efecto hover con any-pointer: fine
Como vimos en la tabla anterior, la Media Any Pointer con el valor fine tiene la misma validez que la Media Any Hover con el valor hover.
Por lo tanto, también podemos implementar el siguiente ejemplo:
button { background: lavender;}
@media (any-pointer: fine) { button:hover { background: mediumpurple; color: #fff; }}Siendo un poco creativo.
Alternativa al efecto hover en pantallas táctiles
Si necesitamos replicar el efecto hover en pantallas táctiles (cuando el usuario no puede utilizar un dispositivo con puntero), podemos recurrir a otra pseudo-clase: :active.
Esta pseudo-clase se activa cuando el usuario hace clic o toca un elemento, y se desactiva cuando deja de hacerlo. Es especialmente útil en este caso, ya que el usuario no necesita presionar en otra parte de la pantalla para eliminar los estilos del elemento ni se producen efectos secundarios (como ocurre con :hover).
Veamos un ejemplo:
button { background: pink;}
button:active { background: crimson; color: #fff;}
/* También podemos mantener el mismo estilo cuándo se usa el efecto hover. */@media (any-hover: hover) { button:hover { background: crimson; color: #fff; }}Este es el resultado:
Este ha sido un repaso completo de las media queries Interaction Media Features, que, como habrás visto, resultan muy útiles para crear efectos o diseños centrados en la experiencia del usuario, ya que nos permiten tener en cuenta el tipo de entrada que puede llegar a utilizar para interactuar en nuestro sitio web.
De esta forma, podemos aplicar los estilos o efectos más adecuados según cada caso y evitar los efectos secundarios que pueden presentarse al utilizar la pseudo-clase :hover en pantallas táctiles.