Cómo eliminar/ignorar: estilo CSS al pasar el cursor en dispositivos táctiles

Resuelto Simon Ferndriger asked hace 10 años • 18 respuestas

Quiero ignorar todas :hoverlas declaraciones CSS si un usuario visita nuestro sitio web a través de un dispositivo táctil. Porque el :hoverCSS no tiene sentido, e incluso puede resultar molesto si una tableta lo activa al hacer clic o tocar, porque entonces podría permanecer hasta que el elemento pierda el foco. Para ser honesto, no sé por qué los dispositivos táctiles sienten la necesidad de activarse :hoveren primer lugar, pero esto es la realidad, por lo que este problema también es una realidad.

a:hover {
  color:blue;
  border-color:green;
  /* etc. > ignore all at once for touch devices */
}

Entonces, (¿cómo) puedo eliminar/ignorar todas :hoverlas declaraciones CSS a la vez (sin tener que conocer cada una) para dispositivos táctiles después de haberlas declarado?

Simon Ferndriger avatar May 27 '14 16:05 Simon Ferndriger
Aceptado

tl;dr usa esto: https://jsfiddle.net/57tmy8j3/

Si te interesa por qué o qué otras opciones hay, sigue leyendo.

Quick'n'dirty: elimina los estilos :hover usando JS

Puede eliminar todas las reglas CSS que contienen :hoverel uso de Javascript. Esto tiene la ventaja de no tener que tocar CSS y ser compatible incluso con navegadores más antiguos.

function hasTouch() {
  return 'ontouchstart' in document.documentElement
         || navigator.maxTouchPoints > 0
         || navigator.msMaxTouchPoints > 0;
}

if (hasTouch()) { // remove all the :hover stylesheets
  try { // prevent exception on browsers not supporting DOM styleSheets properly
    for (var si in document.styleSheets) {
      var styleSheet = document.styleSheets[si];
      if (!styleSheet.rules) continue;

      for (var ri = styleSheet.rules.length - 1; ri >= 0; ri--) {
        if (!styleSheet.rules[ri].selectorText) continue;

        if (styleSheet.rules[ri].selectorText.match(':hover')) {
          styleSheet.deleteRule(ri);
        }
      }
    }
  } catch (ex) {}
}

Limitaciones: las hojas de estilo deben estar alojadas en el mismo dominio (es decir, sin CDN). Desactiva el desplazamiento en dispositivos táctiles y de mouse combinados como Surface o iPad Pro, lo que perjudica la UX.

Solo CSS: use consultas de medios

Coloque todas sus reglas :hover en un @mediabloque:

@media (hover: hover) {
  a:hover { color: blue; }
}

o alternativamente, anule todas sus reglas de desplazamiento (compatible con navegadores más antiguos):

a:hover { color: blue; }

@media (hover: none) {
  a:hover { color: inherit; }
}

Limitaciones: funciona solo en iOS 9.0+, Chrome para Android o Android 5.0+ cuando se usa WebView. hover: hoverrompe los efectos de desplazamiento en navegadores más antiguos y hover: nonenecesita anular todas las reglas CSS definidas previamente. Ambos son incompatibles con dispositivos combinados de mouse y táctiles .

El más robusto: detecta el tacto a través de JS y antepone CSS: reglas de desplazamiento

Este método necesita anteponer todas las reglas de desplazamiento con body.hasHover. (o un nombre de clase de su elección)

body.hasHover a:hover { color: blue; }

La hasHoverclase se puede agregar usando hasTouch()el primer ejemplo:

if (!hasTouch()) document.body.className += ' hasHover'

Sin embargo, esto debería tener los mismos inconvenientes con dispositivos táctiles mixtos que en los ejemplos anteriores, lo que nos lleva a la solución definitiva. Habilite los efectos de desplazamiento cada vez que se mueva el cursor del mouse, deshabilite los efectos de desplazamiento cada vez que se detecte un toque.

function watchForHover() {
  // lastTouchTime is used for ignoring emulated mousemove events
  let lastTouchTime = 0

  function enableHover() {
    if (new Date() - lastTouchTime < 500) return
    document.body.classList.add('hasHover')
  }

  function disableHover() {
    document.body.classList.remove('hasHover')
  }

  function updateLastTouchTime() {
    lastTouchTime = new Date()
  }

  document.addEventListener('touchstart', updateLastTouchTime, true)
  document.addEventListener('touchstart', disableHover, true)
  document.addEventListener('mousemove', enableHover, true)

  enableHover()
}

watchForHover()

Esto debería funcionar básicamente en cualquier navegador y habilitar/deshabilitar los estilos de desplazamiento según sea necesario.

Aquí está el ejemplo completo: moderno: https://jsfiddle.net/57tmy8j3/
Legacy (para usar con navegadores antiguos): https://jsfiddle.net/dkz17jc5/19/

blade avatar May 18 '2015 12:05 blade

Solución 2020: solo CSS, sin Javascript

Usar el desplazamiento multimedia con el puntero multimedia le ayudará a resolver este problema. Probado en Chrome Web y dispositivos móviles Android. Conocía esta vieja pregunta pero no encontré ninguna solución como esta.

@media (hover: hover) and (pointer: fine) {
  a:hover { color: red; }
}
<a href="#" >Some Link</a>
Expandir fragmento

Hải Bùi avatar Oct 27 '2020 11:10 Hải Bùi

¡Pase el cursor sobre CSS Media Feature al rescate! Usando solo CSS, puede anular estilos cuando un dispositivo no tiene hovercapacidades.

La siguiente demostración es compatible con dispositivos táctiles modernos .

/* hover query styles */

a {
  color: red;
  font-size: 3em;
}

a:hover {
  color: blue;
}

@media (hover: none) {
  a:link,
  a:visited {
    color: blue;
    text-decoration: none;
    border: 0.1em solid currentColor;
    padding: 0 0.1em;
  }
}

/* used to show if demo browser has hover capabilities */
.detection:before {
  content: 'UNKNOWN';
  color: red;
}

@media(hover) {
  .detection:before {
    content: 'YES';
    color: green;
  }
}

@media (hover: none) {
  .detection:before {
    content: 'NO';
  }
}
<p>Hoverable pointer detected: <span class="detection"></span></p>

<h3>Experiences between device hover capabilities</h3>

<p>If the device has a hover capability, the link below:</p>

<ul>
  <li>should be red</li>
  <li>should be blue when hovered</li>
</ul>

<p>If the device does not have a hover capability, the link below:</p>

<ul>
  <li>should always be blue</li>
  <li>should be surrounded by a blue border</li>
</ul>

<p><a href="https://www.google.com">Link</a></p>
Expandir fragmento

Nota : tenga en cuenta que, dado que la entrada (capacidad) principal de una Surface PC es un mouse, terminará siendo un enlace azul, incluso si se trata de una pantalla separada (tableta). Los navegadores siempre (deberían) utilizar de forma predeterminada la capacidad de entrada más precisa.

Jason avatar Mar 22 '2017 03:03 Jason