html - movil - Cómo eliminar/ignorar: estilo hover css en dispositivos táctiles
cambiar hover por click (11)
Quiero ignorar todo :hover
declaraciones de CSS si un usuario visita nuestro sitio web a través del dispositivo táctil. Debido a que el :hover
CSS no tiene sentido, e incluso puede ser molesto si una tableta lo activa al hacer clic / tocar, porque entonces puede permanecer hasta que el elemento pierda el foco. Para ser sincero, no sé por qué los dispositivos táctiles sienten la necesidad de activarse :hover
en primer lugar, pero esta es la realidad, por lo que este problema también es la realidad.
a:hover {
color:blue;
border-color:green;
// etc. > ignore all at once for touch devices
}
Entonces, ¿cómo puedo eliminar / ignorar todas las declaraciones CSS :hover
mouse (sin tener que conocerlas una a la vez) para dispositivos táctiles después de haberlos declarado?
De acuerdo con la respuesta de Jason, solo podemos abordar los dispositivos que no admiten el vuelo estacionario con consultas de medios de CSS puro. También podemos abordar solo los dispositivos que soportan el vuelo estacionario , como la respuesta de moogal en una pregunta similar, con @media not all and (hover: none)
. Se ve raro pero funciona.
Hice una mezcla Sass de esto para un uso más fácil:
@mixin hover-supported {
@media not all and (hover: none) {
&:hover {
@content;
}
}
}
Lo siguiente cambiaría el color de fondo de .container
de rojo a azul al pasar el .container
sobre los dispositivos que lo admiten y permanecer en rojo para los dispositivos táctiles:
.container {
background-color: red;
@include hover-supported() {
background-color: blue;
}
}
Esta podría no ser la solución perfecta todavía (y es con jQuery) pero tal vez sea una dirección / concepto en que trabajar: ¿qué tal si lo hacemos al revés? Lo que significa desactivar de forma predeterminada los estados: css de desplazamiento y activarlos si se detecta un evento mousemove en cualquier parte del documento. Por supuesto, esto no funciona si alguien desactivaba js. ¿Qué más podría hablar en contra de hacerlo de esta manera?
Tal vez así:
CSS:
/* will only work if html has class "mousedetected" */
html.mousedetected a:hover {
color:blue;
border-color:green;
}
jQuery:
/* adds "mousedetected" class to html element if mouse moves (which should never happen on touch-only devices shouldn’t it?) */
$("body").mousemove( function() {
$("html").addClass("mousedetected");
});
Esta también es una solución posible, pero tendrá que revisar su CSS y agregar una clase .no-touch
antes de sus estilos de vuelo estacionario.
Javascript:
if (!("ontouchstart" in document.documentElement)) {
document.documentElement.className += " no-touch";
}
Ejemplo de CSS:
<style>
p span {
display: none;
}
.no-touch p:hover span {
display: inline;
}
</style>
<p><a href="/">Tap me</a><span>You tapped!</span></p>
Ps Pero deberíamos recordar que cada vez hay más dispositivos táctiles en el mercado que también admiten entrada de mouse al mismo tiempo.
Esto se puede resolver con sass / scss y una consulta de medios con el punto de interrupción deseado.
.myclass {
background-color: blue;
&:hover {
@media screen and (max-width: 320px) {
background-color: red;
}
}
}
Estoy lidiando con un problema similar actualmente.
Hay dos opciones principales que se me ocurren de inmediato: (1) comprobación de cadenas de usuario, o (2) mantenimiento de páginas móviles separadas usando una URL diferente y que los usuarios elijan lo que es mejor para ellas.
- Si puede usar un lenguaje de cinta de ducto de Internet como PHP o Ruby, puede verificar la cadena de usuario del dispositivo que solicita una página, y simplemente servir el mismo contenido pero con un
<link rel="mobile.css" />
lugar del estilo normal.
Las cadenas de usuario tienen información de identificación sobre el navegador, el procesador, el sistema operativo, etc. Depende de usted decidir qué dispositivos son "táctiles" y no táctiles. Es posible que pueda encontrar esta información disponible en algún lugar y asignarla a su sistema.
R. Si puede ignorar los navegadores antiguos , solo tiene que agregar una sola regla al CSS normal que no es móvil, a saber: EDITAR : Erk. Después de hacer algunos experimentos, descubrí que la regla a continuación también inhabilita la capacidad de seguir enlaces en navegadores webkit además de simplemente causar que los efectos estéticos se deshabiliten - ver http://jsfiddle.net/3nkcdeao/
Como tal, tendrás que ser un poco más selectivo en cuanto a cómo modificar las reglas para la carcasa del móvil que lo que muestro aquí, pero puede ser un punto de partida útil:
* {
pointer-events: none !important; /* only use !important if you have to */
}
Como nota al margen, deshabilitar los eventos de puntero en un elemento primario y luego habilitarlos explícitamente en un elemento secundario provoca actualmente que los efectos de desplazamiento en el elemento primario vuelvan a activarse si un elemento secundario entra :hover
.
Ver http://jsfiddle.net/38Lookhp/5/
B. Si está soportando legadoras web heredadas, tendrá que trabajar un poco más en la línea de eliminar cualquier regla que establezca estilos especiales durante :hover
. Para ahorrarle tiempo a todos, quizás desee construir un comando automático de copiado + sed que ejecute en sus hojas de estilo estándar para crear las versiones móviles. Eso le permitiría simplemente escribir / actualizar el código estándar y eliminar cualquier regla de estilo que utilice :hover
el :hover
para la versión móvil de sus páginas.
- (I) Alternativamente, simplemente haga que sus usuarios sepan que tiene un m.website.com para dispositivos móviles además de su sitio web.com . Aunque el subdominio es la forma más común, también podría tener alguna otra modificación predecible de una URL determinada para permitir que los usuarios móviles accedan a las páginas modificadas. En ese momento, querrá asegurarse de que no tengan que modificar la URL cada vez que naveguen a otra parte del sitio.
Nuevamente aquí, puede agregar una o dos reglas adicionales a las hojas de estilo u obligarse a hacer algo un poco más complicado usando sed o una utilidad similar. Probablemente sería más fácil de aplicar: no a sus reglas de estilo como div:not(.disruptive):hover {...
en el que agregaría class="disruptive"
a los elementos que hacen cosas molestas para los usuarios de dispositivos móviles que usan js o el lenguaje del servidor , en lugar de abatir el CSS.
(II) En realidad, puede combinar los dos primeros y (si sospecha que un usuario ha vagado a la versión incorrecta de una página) puede sugerirle que active o desactive la pantalla de tipo móvil, o simplemente que tenga un enlace en algún lugar permite a los usuarios hacer un flop de ida y vuelta. Como ya se dijo, las consultas de @media también pueden ser algo que se debe usar para determinar qué se está usando para visitar.
(III) Si está listo para una solución de jQuery una vez que sepa qué dispositivos son "táctiles" y cuáles no, es posible que encuentre que el desplazamiento de CSS no se ignora en los dispositivos de pantalla táctil .
Fue útil para mí: link
function hoverTouchUnstick() {
// Check if the device supports touch events
if(''ontouchstart'' in document.documentElement) {
// Loop through each stylesheet
for(var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
var sheet = document.styleSheets[sheetI];
// Verify if cssRules exists in sheet
if(sheet.cssRules) {
// Loop through each rule in sheet
for(var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
var rule = sheet.cssRules[ruleI];
// Verify rule has selector text
if(rule.selectorText) {
// Replace hover psuedo-class with active psuedo-class
rule.selectorText = rule.selectorText.replace(":hover", ":active");
}
}
}
}
}
}
Hay múltiples soluciones para este problema.
Quick''n''dirty - eliminar: estilos de desplazamiento usando JS
Puede eliminar todas las reglas de CSS que contengan :hover
usando 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 :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 (eso significa que no hay CDN). Inhabilita los controles deslizantes del mouse mixto y toca dispositivos como Surface, lo que perjudica al UX.
Solo CSS: use las consultas de los medios
Coloque todas sus: reglas de @media
en un bloque @media
:
@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: hover
desactiva los efectos de desplazamiento en los navegadores más antiguos, al hover: none
necesita anular todas las reglas de CSS definidas previamente. Ambos son incompatibles con dispositivos táctiles y de mouse mixtos .
El más robusto: use clases especiales de CSS y detecte el tacto a través de JS
Este método necesita anteponer todas las reglas de body.hasHover
con body.hasHover
. (o un nombre de clase de su elección)
body.hasHover a:hover { color: blue; }
La clase hasHover
se puede agregar usando hasTouch()
del primer ejemplo:
if (!hasTouch()) {
document.body.className += '' hasHover'';
}
Sin embargo, esto tiene el mismo problema con los dispositivos táctiles mixtos que los ejemplos anteriores, lo que nos lleva a la solución definitiva. Habilite los efectos de desplazamiento cuando se mueve un cursor del mouse, deshabilite los efectos de desplazamiento siempre que se detecte un toque.
function watchForHover() {
var hasHoverClass = false;
var container = document.body;
var lastTouchTime = 0;
function enableHover() {
// filter emulated events coming from touch events
if (new Date() - lastTouchTime < 500) return;
if (hasHoverClass) return;
container.className += '' hasHover'';
hasHoverClass = true;
}
function disableHover() {
if (!hasHoverClass) return;
container.className = container.className.replace('' hasHover'', '''');
hasHoverClass = false;
}
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 habilita / deshabilita los estilos de desplazamiento si es necesario. Pruébelo aquí: https://jsfiddle.net/dkz17jc5/19/
Me he encontrado con el mismo problema (en mi caso con los navegadores móviles de Samsung) y, por lo tanto, me encontré con esta pregunta.
Gracias a la respuesta de Calsal encontré algo que creo que excluirá prácticamente todos los navegadores de escritorio porque parece ser reconocido por los navegadores móviles que probé (vea la captura de pantalla de una tabla compilada: tabla de detección de características del puntero CSS ).
Los documentos web de MDN dicen que
La función puntero CSS @media se puede usar para aplicar estilos según si el mecanismo de entrada principal del usuario es un dispositivo señalador, y si es así, qué tan preciso es
.
Lo que descubrí es que el puntero: grosero es algo desconocido para todos los navegadores de escritorio en la tabla adjunta, pero es conocido por todos los navegadores móviles en la misma tabla. Esta parece ser la elección más efectiva porque todos los demás valores de palabras clave del puntero dan resultados inconsistentes.
Por lo tanto, podría construir una consulta de medios como Calsal pero ligeramente modificada. Hace uso de una lógica invertida para descartar todos los dispositivos táctiles.
Sass mixin:
@mixin hover-supported {
/*
* https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer
* coarse: The primary input mechanism includes a pointing device of limited accuracy.
*/
@media not all and (pointer: coarse) {
&:hover {
@content;
}
}
}
a {
color:green;
border-color:blue;
@include hover-supported() {
color:blue;
border-color:green;
}
}
Compilado CSS:
a {
color: green;
border-color: blue;
}
@media not all and (pointer: coarse) {
a:hover {
color: blue;
border-color: green;
}
}
También se describe en esta gist que creé después de investigar el problema. Codepen para la investigación empírica.
ACTUALIZACIÓN : Al escribir esta actualización, 2018-08-23, y señalada por @DmitriPavlutin esta técnica ya no parece funcionar con el escritorio de Firefox.
Puede utilizar Modernizr JS (consulte también esta respuesta de ) o crear una función JS personalizada:
function is_touch_device() {
return ''ontouchstart'' in window // works on most browsers
|| navigator.maxTouchPoints; // works on IE10/11 and Surface
};
if ( is_touch_device() ) {
$(''html'').addClass(''touch'');
} else {
$(''html'').addClass(''no-touch'');
}
para detectar el soporte del evento táctil en el navegador, y luego asignar una propiedad CSS
regular, atravesando el elemento con la clase html.no-touch
, como esta:
html.touch a {
width: 480px;
}
/* FOR THE DESKTOP, SET THE HOVER STATE */
html.no-touch a:hover {
width: auto;
color:blue;
border-color:green;
}
prueba esto:
@media (hover:<s>on-demand</s>) {
button:hover {
background-color: #color-when-NOT-touch-device;
}
}
ACTUALIZACIÓN: desafortunadamente W3C ha eliminado esta propiedad de las especificaciones ( https://github.com/w3c/csswg-drafts/commit/2078b46218f7462735bb0b5107c9a3e84fb4c4b1 ).
¡Adaptación del puntero al rescate!
Como esto no se ha tocado por un tiempo, puede usar:
a:link {
color: red;
}
a:hover {
color:blue;
}
@media (hover: none) {
a:link {
color: red;
}
}
Vea esta demostración tanto en su navegador de escritorio como en el navegador de su teléfono . Compatible con dispositivos táctiles modernos .
Nota : tenga en cuenta que, dado que la entrada principal de Surface PC (capacidad) es un mouse, terminará siendo un enlace azul, incluso si se trata de una pantalla separada (tableta). Los navegadores siempre (por defecto) tendrán la capacidad de entrada más precisa.