Adam Argyle's Sick Mouse-Out CSS Hover Effect

Avatar of Geoff Graham
Geoff Graham am

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

Ich habe mir die Zeit vertrieben, meinen CodePen-Feed nach Augenschmaus zu durchstöbern, und musste nicht weiter als bis zur ersten Seite gehen, bevor ich einen tollen CSS-Hover-Effekt von Adam Argyle entdeckte.

Ich muss 10 Minuten damit verbracht haben, einfach nur andächtig auf die Demo zu starren. Irgendetwas daran fühlt sich so App-ähnlich an. Ich glaube, es liegt daran, wie kontextbezogen es ist, dass die Hintergrundfarbe von links hereinrutscht und dann nach rechts hinausgeht. Es ist genau das Verhalten, das ich von einer Maus-rein-, Maus-raus-Interaktion erwarten würde.

Wie auch immer, ich habe einen neuen Pen gestartet und mich daran gemacht, ihn nachzubilden. Und es ist nichts allzu Komplexes, sondern eher eine clevere Nutzung von Übergängen und Transformationen, gepaart mit richtigen Offsets. Ziemlich elegant! Ich bin sogar ein wenig beschämt, wie lange es gedauert hat, bis ich verstanden habe, wie der Maus-raus-Teil funktioniert.

Hier ist, wie ich es angegangen bin, mit allen Ecken und Kanten.

„Ich wette, das verwendet einen Übergang auf einem background.“

Das war mein erster Gedanke. Definiere die background-color, setze die background-size und background-position, und dann animiere die background-position. So wurde diese "wachsende" Hintergrundfarbe in der Vergangenheit gemacht. Ich habe das selbst bei einigen Projekten gemacht, wie diesem

Wenn ich dasselbe tun könnte, nur von links nach rechts, dann bleibt nur noch das Maus-raus, oder? Nein. Das Problem ist, dass nichts wirklich dafür sorgen kann, dass die background-position von links nach rechts zu links nach rechts animiert wird. Ich könnte es entweder so oder so machen, aber nicht beides.

„Vielleicht ist es stattdessen eine transform.“

Mein nächster Versuch war, mich mit Transformationen zu beschäftigen. Die transform-Eigenschaft bietet eine Reihe von Funktionen, die sich für etwas komplexere Bewegungen zusammen animieren lassen. Zum Beispiel kann der background "wachsen" oder "schrumpfen", indem die scale() des Elements geändert wird. Oder in diesem Fall nur entlang der x-Achse mit scaleX().

Aber wie ich bereits erwähnt habe, gibt es keine Möglichkeit, den background des Elements zu isolieren, um das zu tun. Von scaleX(0) auf scaleX(1) zu gehen, skaliert das *gesamte* Element, so dass dies im Grunde den Link — Inhalt und alles — zu nichts zerquetscht und ihn dann wieder auf seine natürliche Größe dehnt, was ein völlig anderer Effekt ist. Außerdem bedeutet es, mit scaleX(0) zu beginnen, was das ganze verdammte Ding standardmäßig versteckt und es unbrauchbar macht.

Aber ein Pseudo-Element könnte funktionieren! Es spielt keine Rolle, ob das zerquetscht oder versteckt wird, da es nicht Teil des eigentlichen Inhalts ist. Ich muss den background stattdessen darauf legen und ihn direkt unter dem Link positionieren.

a {
  /* Keeps the pseudo-element contained to the element */
  position: relative;
}

a::before {
  background: #ff9800;
  content: "";
  inset: 0; /* Logical equivalent to physical offsets */
  position: absolute;
  transform: scaleX(0); /* Hide by default */
  z-index: -1; /* Ensures the link is stacked on top */
}

„Jetzt muss ::before bei Hover wechseln.“

Ich wusste, dass ich ::before von 0 auf 1 skalieren konnte, indem ich es an den :hover-Zustand des Link-Elements hänge.

a:hover::before {
  transform: scaleX(1)
}

Schön! Ich war auf dem richtigen Weg.

Ein wenig transition-Feenstaub darauf gestreut, und die Dinge beginnen zum Leben zu erwachen.

a::before {
  background: #ff9800;
  content: "";
  inset: 0;
  position: absolute;
  transform: scaleX(0);
  transition: transform .5s ease-in-out;
  z-index: -1;
}

„Hmm, der Übergang bewegt sich in *beiden* Richtungen.“

Auch hier war ich irgendwie festgefahren. Etwas in meinem Kopf klickte aus irgendeinem Grund nicht. Wie üblich, bin ich zum CSS-Tricks Almanac gegangen, um zu sehen, welche Eigenschaft ich vielleicht vergessen hatte.

Ah, ja. Das wäre transform-origin. Das erlaubt mir, festzulegen, wo die transform beginnt, was nicht völlig unähnlich dem Festlegen der background-position ist, wie ich es früher versucht habe. Die transform könnte von links beginnen, anstatt von der Standardposition 50% 50%.

a::before {
  background: #ff9800;
  content: "";
  inset: 0;
  position: absolute;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .5s ease-in-out;
  z-index: -1;
}

Ja, so:

Ich habe ::before bereits zu scaleX(1) bei Link-Hover animiert. Wenn ich transform-origin gleichzeitig von left auf right umkehre, dann geht der Hervorhebung vielleicht auf die entgegengesetzte Weise aus, wie sie herausging, wenn die Maus den Bereich verlässt?

a:hover::before {
  transform: scaleX(1);
  transform-origin: right;
}

🤞

Hoppla, verkehrt herum! Tauschen wir die Werte left und right. 🙃

Wunderschön. Danke, Adam, für die Inspiration!