Das nervige Problem mit dem doppelten Tippen auf Links auf Mobilgeräten

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Vor ein paar Tagen hatten wir auf ShopTalk eine Frage zu ganz normalen Anker-Links auf iOS, und einer seltsamen Situation, in der man sie nicht einfach einmal antippen konnte, um zum Link zu gelangen, sondern man musste den Link zweimal antippen. Ich habe das selbst erlebt und war ziemlich ratlos.

Mein erster Gedanke war, dass irgendetwas Seltsames und Unerwartetes mit JavaScript passiert. Vielleicht ein Click-Handler mit preventDefault() beim ersten Klick, der dann entfernt wird. Ich konnte jedoch nichts Derartiges finden. Ich bin sicher, ich habe noch ein paar Dinge ausprobiert, aber letztendlich aufgegeben und FastClick verwendet, um sicherzustellen, dass diese Link-Klicks funktionieren. FastClick war nicht dazu gedacht, dieses Problem zu lösen, sondern eher die 300-ms-Verzögerung beim Tippen auf Links zu beheben, die einige mobile Browser auferlegen, damit sie warten können, um zu sehen, ob Sie doppelt tippen (Hinweis: kein so großes Problem mehr wie früher). Nicht ganz das richtige Werkzeug für die Aufgabe, aber es hat funktioniert.

Die Sache ist, es war überhaupt kein JavaScript-Problem, sondern ein CSS-Problem.

Nicholas C. Zakas hat dies vor langer Zeit dokumentiert

Hier haben die Leute bei Apple vielleicht ein bisschen zu schlau gedacht. Sie erkannten, dass viele Web-Funktionen auf Hover-Zuständen basierten, und fanden daher einen Weg, damit in Safari für iOS umzugehen. Wenn Sie einen Gegenstand auf einer Webseite berühren, wird zuerst ein Hover-Zustand ausgelöst und dann der „Klick“. Das Endergebnis ist, dass Sie für eine Sekunde Stile sehen, die mit :hover angewendet wurden, bevor die Klick-Interaktion stattfindet. Es ist ein wenig beunruhigend, aber es funktioniert. Safari unter iOS achtet also sehr auf Ihre Stile, die :hover im Selektor haben. Sie werden nicht einfach ignoriert.

(Danke an Pete Droll, der mich darauf aufmerksam gemacht hat.)

Hier sind zwei Zeilen CSS, die das Problem verursachen

a::after {
  display: none;
  content: "pseudo block!";
}
a:hover::after {
  display: inline;
}

Auf einem Browser mit einem Cursor-Zeiger sehen Sie das Pseudoelement, das bei :hover angezeigt wird

Aber das Anklicken dieses Links verhindert nicht, dass der Link aufgerufen wird. Unter iOS wird beim Tippen auf den Link nur das Pseudoelement angezeigt. Es erfordert einen zweiten Tipp, um tatsächlich zum Link zu gelangen.

Android scheint das nicht zu tun. Es zeigt das Pseudoelement schnell an, aber ruft den Link auch normal auf.

Diese Sache mit dem Hinzufügen eines Pseudoelements zu einem Link... nicht sehr üblich, oder? Ich würde sagen, das stimmt, es ist nicht sehr verbreitet. Was erklärt, warum dies nicht so bekannt ist, wie wir denken, und nur ab und zu Leute erwischt.

Ich habe gesehen, wie Leute Pseudoelemente für ästhetische Zwecke verwendet haben, wie z. B. das Hinzufügen einer besser kontrollierten Unterstreichung zu Text. Wenn das also nur bei :hover passiert, blammo, ist das Problem da. Es scheint übrigens nur bei Hover aufzutreten, nicht bei Focus oder Active.

Update Dezember 2019: Beim Testen der Demo hier in Safari/iOS 13 scheint das Pseudoelement kurz aufzutauchen, dann wird der Link aufgerufen, ohne dass ein Doppeltippen erforderlich ist. Ich habe noch keine tiefergehenden Tests auf mobilen Plattformen durchgeführt.

Es sind nicht nur Pseudoelemente

Das gilt für jedes Kind-Element. Denken Sie daran, dass der Gedanke dahinter Situationen waren, in denen zusätzliche Inhalte nur bei Hover angezeigt wurden. Wahrscheinlich ist es üblicher, dass ein tatsächliches Element verwendet wird.

Zum Beispiel:

...
<li>
  
  <a href="#0">I'm a thing in a list</a>

  <span class="controls">
    <button>Do Something</button>
  </span>

</li>
...
li .controls {
  visibility: hidden;
}
li:hover .controls {
  visibility: visible; 
}

Wenn über das Listenelement gehovert wird, werden einige Steuerelemente angezeigt. Da ein *Elternelement* nun einen Hover-Zustand hat, der Inhalte anzeigt, wird der Anker-Link daran gehindert, mit einem einzigen Tippen zu funktionieren.

Es muss nicht der Elter sein, es kann der Link selbst sein

<a href="http://link.com">
  Link
  <span>Extra Stuff</span>
</a>
a span {
  display: none;
}
a:hover span {
  display: inline-block;
}

Hilfe durch Media Queries

Es ist verlockend, zu denken... OK, ich werde diese Hovers nur auf „Desktop“-Websites anwenden und eine Media Query wie diese verwenden...

@media (min-width: 500px) {
  a span {
    display: none;
  }
  a:hover span {
    display: inline-block;
  }
}

...was in einfachen Tests funktioniert, aber die Breite des Browserfensters ist nicht die beste Methode, um zu testen, ob Sie einen Cursor und „normale“ Hovers zur Verfügung haben.

Glücklicherweise gibt es eine Media Query für Zeiger, die für uns nützlich sein könnte

@media (pointer: fine) {
  a span {
    display: none;
  }
  a:hover span {
    display: inline-block;
  }
}

Cool.

Es gibt auch eine Spezifikation für eine direkte Hover-Media-Query

@media (hover) {

}

Beide Arten von Media Queries funktionierten bei mir in Chrome und Safari, aber nicht in Firefox (Support-Level-Diagramm), was sie ein bisschen zu riskant zu verwenden macht, vielleicht. Selbst JavaScript-Methoden zur Erkennung von Touch sind fragwürdig, höre ich, und werden immer seltsam falsch sein auf Geräten, die beides unterstützen.

UPDATE März 2019: Firefox 64 wurde im Dezember 2018 veröffentlicht und enthielt Unterstützung für Hover-Media-Queries, wodurch die Support-Übersicht für diese erheblich verbessert wurde. Das ist wahrscheinlich die beste Lösung.

Es ist wahrscheinlich am besten, sich einfach nicht darauf zu verlassen, dass Hover etwas anzeigt

Die Technologie, um dies zu umgehen, ist noch nicht ganz ausgereift.

Gestalten Sie Ihre Website im Zweifelsfall so, dass Klicks oder Taps erforderlich sind, um andere Dinge anzuzeigen, aber machen Sie dies so offensichtlich wie möglich und sperren Sie keine normalen, unfreiwilligen Links innerhalb dieser Elemente.

Trent Walton hatte wahrscheinlich recht vor sechs Jahren

Letztendlich denke ich, dass das Verschwinden von Hover-Zuständen das Web zu einem besseren Ort machen wird. Es gab noch nie einen Ersatz für prägnante Inhalte, klare Interaktion und einfaches Design. Wenn wir uns auf Kernelemente konzentrieren, die das Surfen im Web großartig machen, werden unsere Websites unabhängig davon, wie Menschen sie nutzen, ordnungsgemäß funktionieren.

Demo

Hier ist eines zum Spielen.