Vor einiger Zeit haben wir eine coole „Hover“-Technik von Doug Neiner behandelt, bei der ein informatives Popup angezeigt wurde, wenn man mit der Maus über ein Bild fuhr. Beim *ersten* Überfahren gab es eine Verzögerung. Dies sollte versehentliche oder vorbeifliegende Mauszeiger verhindern, im Gegensatz zum bewussten Fokussieren auf ein bestimmtes Bild. *Nachfolgende* Überfahrten zeigten das Popup sofort an. Die Idee war, dass man sich bereits in diesem Erkundungsmodus befindet.
Doug verwendete jQuery für die Animationen und einige ausgeklügelte Tricks, um den Hover-Zustand und sein Verhalten zu verfolgen. Wir machen das nun etwas anders, indem wir CSS-Übergänge mit Verzögerungen verwenden und dann nur einen Hauch von jQuery, um den Zustand zu verfolgen.
Anwendungsfall
Nehmen wir an, Sie haben eine Reihe von Funktionsschaltflächen. Benutzer können die Schaltfläche anklicken oder einen Tastaturbefehl verwenden, der die Funktion auslöst. Power-User lieben Tastaturbefehle, müssen sie aber zuerst lernen und brauchen manchmal Erinnerungen. Also entscheiden Sie sich für eine Art Popup, das den Befehl anzeigt, wenn die Schaltfläche angefahren wird.
*Aber mobile Geräte haben keinen Hover!!* Korrekt, oder Tastaturen, sodass Tastaturbefehle in diesem Anwendungsfall nützlich wären.
Titel-Attribut?
Eine Möglichkeit wäre ein Titel-Attribut.
<a href="#" class="function button" title="⌘G">Do Thing</a>
Dies ist eine völlig akzeptable Vorgehensweise. Sie erhalten ein standardmäßiges Titel-Popup wie dieses, wenn Sie mit der Maus darüber fahren

Tatsächlich ist das Standardverhalten des Titel-Attributs genau wie beschrieben. Das erste Überfahren dauert ein wenig, um das Popup anzuzeigen, aber andere schnell angefahrene Links werden sofort angezeigt, bis genügend Zeit vergeht, damit das aktive Popup vollständig ausgeblendet ist.
Schön. Aber… keine Designkontrolle (komm schon, Shadow DOM!), keine spezifische Funktionskontrolle und, wie Sie gleich sehen werden, kein generierter Inhalt erlaubt.
Manuell
Stattdessen rollen wir dieses Ding von Hand. Wir packen den Befehl direkt in den Markup
<nav>
<a href="#" class="button">
Cut
<span class="command">
<span class="screen-reader-text">Keyboard Command:</span>
<span class="mod">X</span>
</span>
</a>
...
</nav>
So werden wir
- Für Mobilgeräte nur den Button anzeigen
- Den Tastaturbefehl bei Hover für Desktop anzeigen können
- Ankündigen, was der zufällige Buchstabe tut (es ist ein Tastaturbefehl) für Screenreader
- Die richtige Modifikatortaste anwenden, ohne den Markup zu ändern
- Es einigermaßen semantisch halten
Übergangsverzögerung: Verzögerung beim Einblenden / sofortiges Ausblenden
Nachdem wir Markup zum Arbeiten haben, können Sie das Aussehen der Popup-Informationen nach Belieben gestalten.
.button {
/* Button styling */
position: relative;
}
.command {
/* Popup styling */
position: absolute;
opacity: 0; /* Not shown by default */
}

Funktional werden wir eine einsekündige Verzögerung anwenden, bevor das Popup angezeigt wird (um die Nervigkeit zu reduzieren), aber das Popup sofort entfernen, wenn der Mauszeiger wegfährt. Das haben wir alles schon einmal gelernt.
.command {
transition: opacity 0.2s 0 ease; /* Mouse leave: immediate */
}
.button:hover .command {
transition: opacity 0.2s 1s ease; /* Mouse enter: delay */
}
Das Obige ist ungeprefixst, aber denken Sie daran, -webkit-, -moz-, -ms- und -o- für Übergänge zu verwenden. Oder verwenden Sie Compass und tun Sie @include transition(opacity 0.2s 0 ease);
Übergangsverzögerung: Verzögerung; nur sofortiges Einblenden, wenn fokussiert
Das obige CSS bringt uns zur Hälfte ans Ziel, aber es wendet die Verzögerung auf jeden angefahrenen Button an. Das bedeutet, dass das Erkunden aller Tastenkombinationen langsam, mühsam und beleidigend für unser schneller denkendes Gehirn ist. Wir wollen die Verzögerung *entfernen*, sobald wir bewiesen haben, dass wir uns lange genug mit der Maus im Navigationsbereich befunden haben.
Mithilfe von jQuery wenden wir Klassen auf das Nav-Element an, je nachdem, wie es sich verhalten soll. Beim Betreten des Navigationsbereichs warten wir eine Sekunde und wenden dann eine Klasse namens „immediate“ an. Beim Verlassen entfernen wir diese Klasse.
$("nav").hover(function() {
/* Mouse enter */
var nav = $(this);
setTimeout(function() {
nav.addClass("immediate");
}, 1000);
}, function() {
/* Mouse leave */
$(this).removeClass("immediate");
});
nav.immediate .command {
transition-delay: 0s !important;
}
Wir müssen nur noch ein bisschen schicker werden, indem wir eine „out“-Klasse anwenden und entfernen. Das dient dazu, dass, wenn ein Benutzer für eine halbe Sekunde hinein- und wieder herausfährt, der Timeout trotzdem ausgelöst wird und die „immediate“-Klasse anwendet, aber die „out“-Klasse sie negiert. Hier ist der vollständige JS-Code
$("nav").hover(function() {
/* Mouse enter */
var nav = $(this).removeClass("out");
setTimeout(function() {
nav.addClass("immediate");
}, 1000);
}, function() {
/* Mouse leave */
$(this)
.addClass("out")
.removeClass("immediate");
});
Mit der „out“-Klasse wird die Verzögerung wiederhergestellt
nav.out .command {
transition-delay: 1s !important;
}
Demo und Download
Ich habe die Demo auf CodePen gelegt. Wenn Sie eine Kopie herunterladen möchten, können Sie auf die Schaltfläche Teilen klicken und „Export as .zip“ auswählen.
Notizen
Die CodePen-Demo enthält das kleine JavaScript, das die Klasse „mac“ oder „pc“ anwendet, die den Modifikator anwendet. Warnung: grottige UA-Tests. Aber gibt es irgendeinen anderen Weg, das zu tun?
Es gibt einen Fehler (oder es scheint mir ein Fehler zu sein) in OS X Voice Over, der die Schaltflächen liest als
⌘ Cut Keyboard Command:X
anstatt als
Cut Keyboard Command: ⌘X
Wo das Pseudo-Element spezifisch angewendet wird. Noch besser wäre es
Cut [kurze Pause] [leise Stimme]Keyboard Command: ⌘X[/Ende leise Stimme]
Vielleicht, jedenfalls.
Man könnte auch
transition-delay: 0smit einem Selektornav.immediate:not(.out) .commandsetzen, damit man die Verzögerung nicht für die.outKlasse wieder setzen muss, und man könnte dieses.outDing sogar komplett weglassen, wenn man den Timeout beim Verlassen zurücksetzt, glaube ich :)Übrigens, in der Demo ist die Taste für Windows **CTRL**+X/C/V, nicht ALT ;-)
Wollte ich auch gerade sagen. :)
Wenn es doch nur einen Zustand des HTML-Elements gäbe, der durch 2s+iges Hovern ausgelöst und über die Pseudoklasse
:long-hoveredzugänglich wäre…Stellen Sie sich vor
:P
Schön.
Ich bin nur daran interessiert, wie Voice Over ⌘ liest
Sehr schön, Nick… Ich habe es gerade ausprobiert und es hat einwandfrei funktioniert! Lob an Sie, dass Sie Ihr Wissen mit uns teilen…
Das ist ziemlich großartig, danke fürs Teilen.
Man muss sich nicht mit der
out-Klasse herumschlagen.Brechen Sie einfach den Timeout bei mouseleave ab: http://codepen.io/JosephSilber/pen/2/2
Sehr schön. Danke fürs Teilen…
ease-in-out hat das Attraktivste, nicht wahr?
Sehr schön, schade nur, dass so viel Markup erforderlich ist.
Der Markup war spezifisch für diesen Anwendungsfall, aber das „Zustands“-Konzept würde mit jeder Hover/Reveal-Situation funktionieren.
Ich weiß nicht, warum mein vorheriger Link zu CodePen 404 war, aber hier ist ein neuer: http://codepen.io/JosephSilber/pen/2/2
Es ist schade, dass wir Kommentare hier nicht bearbeiten können, Chris. Fühlen Sie sich frei, meine beiden Kommentare zu kombinieren (Sie könnten auch meinen Tippfehler korrigieren: mouseleave, mit einem ‚e‘).
Die Animationen, die mit CSS3 und jQuery erreicht werden können, sind fantastisch. Zu denken, dass man vor nicht allzu langer Zeit alles in Flash usw. machen musste, wenn man eine niedliche Animation wollte! Selbst ein einfaches Gradient musste ein Bild sein. CSS3 sind die Übersetzungen mit dem Besten der letzten Jahre.
Ich musste kürzlich mit HTML5 und CSS3 testen, die Übersetzungen und Transformationen haben mir das Leben gerettet.
Mit freundlichen Grüßen.
Es gibt absolut keinen Grund, für diesen Effekt JavaScript zu verwenden; er kann vollständig in CSS umgesetzt werden! Sehen Sie mein Beispiel codepen (http://codepen.io/telic/details/1/1)
Sehr cool, gute Arbeit.
Danke – sehr cool
was ist mit Transition Delay Delay Delays?:)
Absolut tolle Arbeit!!! Daumen hoch!!!
Was ist der Zweck des
!importantMarkers in Ihrem Beispiel?