style imagen enlaces ejemplos css hover media-queries touch interaction-media-features

imagen - hover text css



Consulta de medios para dispositivos compatibles con hover (5)

De acuerdo con la respuesta de Artin , podemos abordar solo los dispositivos que admiten hover con css puro, con @media not all and (hover: none) . Parece 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 mouse por los dispositivos que admiten el hover, sin cambios para los dispositivos táctiles:

.container { background-color: red; @include hover-supported() { background-color: blue; } }

Me gustaría proporcionar un comportamiento separado para los navegadores que admiten hover (por ejemplo, navegadores de escritorio) y otros que no (por ejemplo, dispositivos con pantalla táctil) Específicamente, quiero declarar un estado de desplazamiento en los navegadores que lo admiten, pero no para los navegadores que no lo hacen, para evitar que los navegadores móviles lo emulen con toques adicionales, ya que esto rompe otras interacciones en la página, al no definir un desplazamiento. Estado para esos navegadores esto se evita.

He leído sobre la característica de consultas de medios de interacción y parece que debería hacer el truco. Sería capaz de hacer algo como:

@media (hover: none) { /* behaviour for touch browsers */ }

De acuerdo con CanIUse , está disponible en todos los navegadores que necesito soportar, excepto IE11 y Firefox.

Así que me pregunté si podría hacerlo al revés, ya que todos los dispositivos táctiles principales lo admiten, luego lo niegan:

@media not (hover: none) { /* behaviour for desktop browsers */ }

Sin embargo, esto no parece funcionar en absoluto.

Ejemplo de pseudocódigo de lo que estoy tratando de hacer:

.myelement { /* some styling */ /* note: no hover state here */ } @media(this device supports hover) { .myelement:hover { /* more styling */ } }

Entonces, ¿hay alguna manera de hacer que esto funcione de la manera prevista o estoy en el camino equivocado?


De las especificaciones:

none

Indica que el sistema de puntero primario no puede moverse, o que no hay un sistema de puntero. Los ejemplos incluyen pantallas táctiles y pantallas que usan un lápiz de dibujo.
Los sistemas de señalización que pueden flotar, pero para los cuales es inconveniente y no forman parte de la forma normal en que se utilizan, también coinciden con este valor.

Por ejemplo, una pantalla táctil en la que una pulsación prolongada se trata como si estuviera flotando coincidiría con la flotación: ninguna.

Si su navegador (móvil / táctil) admite una pulsación larga para simular el desplazamiento, el uso de este hover: none funcionará. Lo que puede hacer es usar un valor predeterminado y anularlo (con precedencia CSS predeterminada):

body { background: red; } @media (hover: hover) { body { background: blue; } }

El escritorio tendrá blue fondo blue y el móvil / táctil tendrá red fondo red

Compruebe el siguiente ejemplo:
https://jsfiddle.net/mcy60pvt/1/

Para verificar la opción de larga duración del móvil, puede usar este ejemplo:
https://jsfiddle.net/mcy60pvt/3/

En el ejemplo anterior, el bloque verde tiene :hover definición de :hover tanto para el escritorio como para el móvil, sin embargo, para el escritorio, el fondo cambiará a yellow y para el móvil (con una pulsación larga) cambiará a white .

Aquí está el css para el último ejemplo:

body { background: red; } div.do-hover { border: 1px solid black; width: 250px; height: 250px; background: green; } div.do-hover:hover { background: white; } @media (hover: hover) { body { background: blue; } div.do-hover:hover { background: yellow; } }

En este ejemplo, los navegadores que no lo admiten :hover verá el cuadro Hover me con fondo verde, y mientras "hover" (toque / mantenga presionada) el fondo cambiará a blanco.

actualizar

En cuanto al pseudo código añadido:

.myelement { /* some styling #1 */ /* note: no hover state here */ } @media(hover: hover) { .myelement { /* some styling that override #1 styling in case this browser suppot the hover*/ } .myelement:hover { /* what to do when hover */ } }


Gracias a los comentarios de Dekel, resolví esto ejecutando la lógica en JS y aplicando una clase en su lugar:

p.ej

const canHover = !(matchMedia(''(hover: none)'').matches); if(canHover) { document.body.classList.add(''can-hover''); }

Luego en la hoja de estilo:

.myElement { background: blue; } .can-hover .myElement:hover { background: red; }

He probado esto en el escritorio de Chrome, Safari y Firefox, y en iOS Safari y funciona como se esperaba.


Para ser compatible con Firefox (consulte bugzilla.mozilla.org/show_bug.cgi?id=1035774 ), posiblemente tenga que escribir algunas reglas dos veces. Tenga en cuenta, aunque no se especificó en la pregunta que he agregado pointer: coarse en el supuesto de que el propósito de estas reglas es apuntar a las pantallas móviles:

/* BEGIN devices that DON''T pinch/zoom */ /* If https://bugzilla.mozilla.org/show_bug.cgi?id=1035774 is fixed then we can wrap this section in a ... @media not all and (pointer: coarse) and (hover: none) { .. and do away with the ''NEGATE'' items below */ .myelement { /* some styling that you want to be desktop only (style as an anchor on desktop) */ font-size: 14px; text-decoration: underline; border: none; } /* END devices that DON''T pinch/zoom */ /* BEGIN devices that DO pinch/zoom */ @media (pointer: coarse) and (hover: none) { .myelement { /* style as a large button on mobile */ font-size: inherit; /* maintain e.g. larger mobile font size */ text-decoration: none; /* NEGATE */ border: 1px solid grey; } .myelement:hover { /* hover-only styling */ } } /* END devices that DO pinch/zoom */

La combinación de (pointer: coarse) and (hover: none) debería ser más útil para apuntar a dispositivos móviles a medida que las pantallas móviles se hacen más grandes y perdemos la correlación entre las dimensiones de píxeles y el móvil frente al escritorio (ya es el caso cuando se desea distinguir entre tableta y escritorio


not debe prefijar el tipo de medio (pantalla, imprimir, todo, etc.) y no la función de medios (desplazamiento, punto, etc.).

Incorrecto:

@media not (hover: none)

Correcto:

@media not all and (hover: none)

Sí, es poco intuitivo y extraño. Fuente (ver comentarios) .

Por lo tanto, no necesita javascript para alternar el resultado de la consulta de medios.