222 votes

Comment éviter les effets de survol collants pour les boutons sur les appareils tactiles ?

J'ai créé un carrousel avec un bouton précédent et un bouton suivant qui sont toujours visibles. Ces boutons ont un état de survol, ils deviennent bleus. Sur les appareils tactiles, comme l'iPad, l'état de survol est collant, de sorte que le bouton reste bleu après avoir été touché. Ce n'est pas ce que je veux.

  • Je pourrais ajouter un no-hover classe ontouchend pour chaque bouton, et faire mon CSS comme ceci : button:not(.no-hover):hover { background-color: blue; } mais c'est probablement très mauvais pour les performances, et cela ne permet pas de pas les appareils comme le Chromebook Pixel (qui possède à la fois un écran écran tactile et une souris) correctement.

  • Je pourrais ajouter un touch à la classe documentElement et faire mon CSS comme ceci : html:not(.touch) button:hover { background-color: blue; } Mais cela ne fonctionne pas non plus correctement sur les appareils dotés à la fois d'un écran tactile et d'une souris. souris.

Ce que je préférerais, c'est de supprimer l'état de survol. ontouchend . Mais il ne semble pas que cela soit possible. La mise au point d'un autre élément ne supprime pas l'état de survol. Le fait de toucher manuellement un autre élément le fait, mais je ne parviens pas à le déclencher en JavaScript.

Toutes les solutions que j'ai trouvées semblent imparfaites. Existe-t-il une solution parfaite ?

174voto

cvrebert Points 8264

Puisque cette partie de Requêtes médias CSS niveau 4 a maintenant été largement mis en œuvre depuis 2018 vous pouvez utiliser ceci :

@media (hover: hover) {
    button:hover {
        background-color: blue;
    }
}

Ou en anglais : "Si le navigateur prend en charge le survol correct/vrai/réel/non émulé (par exemple, s'il dispose d'un périphérique d'entrée principal semblable à la souris), appliquez ce style dans les cas suivants button sont survolés."

Pour les navigateurs qui ne disposent pas de cette fonctionnalité (ou qui n'en disposaient pas au moment de la rédaction de cette réponse initiale), J'ai écrit un polyfill pour faire face à cette situation. En l'utilisant, vous pouvez transformer le CSS futuriste ci-dessus en.. :

html.my-true-hover button:hover {
    background-color: blue;
}

(Une variation sur le .no-touch ) Puis, à l'aide d'un JavaScript côté client issu du même polyfill qui détecte la prise en charge du survol, vous pouvez activer la présence de l'icône my-true-hover en conséquence :

$(document).on('mq4hsChange', function (e) {
    $(document.documentElement).toggleClass('my-true-hover', e.trueHover);
});

58voto

Sjoerd Visscher Points 8310

Vous pouvez supprimer l'état de survol en retirant temporairement le lien du DOM. Voir http://testbug.handcraft.com/ipad.html


Dans le CSS vous avez :

:hover {background:red;}

Dans le JS vous avez :

function fix()
{
    var el = this;
    var par = el.parentNode;
    var next = el.nextSibling;
    par.removeChild(el);
    setTimeout(function() {par.insertBefore(el, next);}, 0)
}

Et puis dans votre HTML vous avez :

<a href="#" ontouchend="this.onclick=fix">test</a>

30voto

Tim Medora Points 30969

Il s'agit d'un problème courant pour lequel il n'existe pas de solution parfaite. Le comportement de survol est utile avec une souris et surtout préjudiciable avec le tactile. Les appareils qui prennent en charge le toucher et la souris (simultanément, rien que ça !), comme le Chromebook Pixel et la Surface, aggravent le problème.

La solution la plus propre que j'ai trouvée consiste à n'activer le comportement de survol que si l'appareil n'est pas censé prendre en charge la saisie tactile.

var isTouch =  !!("ontouchstart" in window) || window.navigator.msMaxTouchPoints > 0;

if( !isTouch ){
    // add class which defines hover behavior
}

Il est vrai que vous perdez le survol sur les appareils qui peuvent le supporter. Cependant, il arrive que le survol ait un impact plus important que le lien lui-même, par exemple si vous souhaitez afficher un menu lorsqu'un élément est survolé. Cette approche vous permet de tester l'existence du toucher et peut-être d'attacher conditionnellement un événement différent.

Je l'ai testé sur l'iPhone, l'iPad, le Chromebook Pixel, la Surface et une variété d'appareils Android. Je ne peux pas garantir que cela fonctionnera lorsqu'une entrée tactile USB générique (comme un stylet) est ajoutée au mélange.

19voto

OrganicPanda Points 667

Vous pouvez remplacer l'effet de survol pour les appareils qui ne prennent pas en charge le survol. Par exemple :

.my-thing {
    color: #BADA55;
}

.my-thing:hover {
    color: hotpink;
}

@media (hover: none) {
    .my-thing {
        color: #BADA55;
    }
}

Testé et vérifié sur iOS 12

Coup de chapeau à https://stackoverflow.com/a/50285058/178959 pour avoir souligné ce point.

19voto

À partir de 2020, vous pouvez ajouter des styles de survol dans la requête média.

@media (hover: hover) and (pointer: fine) {
    /* css hover class/style */
}

Cette requête média indique que les styles fonctionneront sur les navigateurs qui n'émulent pas :hover ; ils ne fonctionneront donc PAS sur les navigateurs tactiles.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X