5202

ein Blog über technische Fragen zu Blogger

Menü mit "negativem" Hover

von
Manchmal habe ich nur Blödsinn im Kopf - gestern Abend etwa ein Menü mit 'negativem' Hover.

Wenn man mit einer Mouse über ein HTML-Element fährt und damit eine Veränderung auslöst, ist das der 'Hover'. Was aber wäre, statt dieses einen Elements, alle anderen Elemente zu verändern? Das ist dann der 'negative' oder umgekehrte Hover. Der Effekt ist frisch und [für Blogger] neu.

jQuery

Wie wird's gemacht? Im Grunde sehr simpel mit einem kleinen jQuery Script, das beim drüberfahren mit der Mouse allen Links außer dem aktuellen Link eine neue Klasse gibt. Den gleichen ähnlichen Effekt könntet ihr auch mit purer CSS erreichen - mit jQuery wird's aber 'ruhiger', weniger flackrig.

HTML

Das ist eine Navigation - wir sind inzwischen in HTML5 angekommen, semantisch richtig kommt das also zwischen <nav> ...</nav> Tags. Die Links selber sind A-Elemente.
<nav> <a href="">smooth</a><a href="">amazing</a> ...
</nav>

Script

Das Script ist - wie gesagt - super simpel. Ich benützte die relativ neue 'hover' Funktion von jQuery - falls ihr also eine Asbach Uralt Version vom jQuery Framework verwendet, könnte ein Update hilfreich sein :=)!
<script type="text/javascript">
 $(document).ready(function(){
  $("nav a").hover(
  function(){$("nav a").not(this).addClass('hover')},
  function(){$("nav a").removeClass('hover')}
    ); 
});
</script>

CSS

Kommen wir zum spannenden Teil, nämlich der CSS. Wir haben jetzt ein Klasse nav a für das Menü im 'Ausgangszustand', die Klasse nav a:hover für das Element, über dem die Mouse gerade liegt und last not least die Klasse nav .hover für alle Elemente, über dem die Mouse aktuell _nicht_ liegt.

Konzept verstanden? Das Script gibt uns eine neue Klasse .hover, mit dem wir alle-nicht-gehoverten Elemente beeinflussen können.
Ausgangszustand
Geben wir dem Menü zunächst a bisserl Grundstyling:
nav a {
font-family:'Chelsea Market', cursive;
color: #fff0aa;
margin: 0 40px 0 0;
display: inline-block;
}
'Chelsea Market' ist ein Google Web-Font.
Klasse .hover
Die Klasse .hover bekommt eine schwarze Schrift und die Hälfte der 'Durchsichtigkeit' - außerdem verkleinere ich die A-Elemente mit der CSS3-Funktion scale in Webkit und IE10 um eine winzige Kleinigkeit.
nav .hover {
color: rgba(0, 0, 0, 0) !important;
opacity: 0.5;
-webkit-transform: scale(0.9);
   -moz-transform: scale(1);
    -ms-transform: scale(0.9);
     -o-transform: scale(1);
        transform: scale(0.9);
}
In Firefox und Opera wird scale sehr schlecht unterstützt, deswegen bleiben die beiden Browser außen vor.
Klasse nav a:hover
Noch mal zur Grundüberlegung vom 'negativem' Hover - die Links sollen ja eigentlich beim hovern im Ausgangszustand bleiben. Ich habe trotzdem in Webkit-Browser und im IE10 eine kleine Skalierung gelegt. Außerdem braucht es für die transition Funktion eine Farbe und eine 'Durchsichtigkeit'.
nav a:hover {
olor: #fff0aa;
opacity: 1;
-webkit-transform: scale(1.1);
   -moz-transform: scale(1);
    -ms-transform: scale(1.1);
     -o-transform: scale(1);
        transform: scale(1.1);
}
So - im Grunde ist es fertig, der ganze Rest dreht sich nur noch darum, das Menü 'smooth' zu bekommen.

Transition

Die CSS3 transition Funktion lässt sich sehr fein steuern. Ich habe für opacity, color, scale jeweils einen eigenen Code geschrieben. Ich habe dabei folgende transition Eigenschaften verwendet:
  • transition-property = CSS-Eigenschaft, die man verändert
  • transition-duration = Dauer
  • transition-timing-function = Art der Animation
  • transition-delay = Verzögerung beim Start
Dazu kommen noch die verschieden Vendor-Prefixe für die verschiedenen Browser. Ich gebe zuerst die gesamte CSS im Überblick:
nav a {
font-family:'Chelsea Market', cursive;
color: #fff0aa;
margin: 0 40px 0 0;
display: inline-block;
-webkit-transition-property: opacity, color, scale;
   -moz-transition-property: opacity, color, scale;
    -ms-transition-property: opacity, color, scale;
     -o-transition-property: opacity, color, scale;
        transition-property: opacity, color, scale;
-webkit-transition-duration: .5s, 1s, 1s;
   -moz-transition-duration: .5s, 1s, 1s;
    -ms-transition-duration: .5s, 1s, 1s;
     -o-transition-duration: .5s, 1s, 1s;
        transition-duration: .5s, 1s, 1s;
-webkit-transition-timing-function: linear, ease-in, ease;
   -moz-transition-timing-function: linear, ease-in, ease;
    -ms-transition-timing-function: linear, ease-in, ease;
     -o-transition-timing-function: linear, ease-in, ease;
        transition-timing-function: linear, ease-in, ease;
 -webkit-transition-delay: .2s, .3s, .2s;
    -moz-transition-delay: .2s, .3s, .2s;
     -ms-transition-delay: .2s, .3s, .2s;
      -o-transition-delay: .2s, .3s, .2s;
         transition-delay: .2s, .3s, .2s;
 -webkit-backface-visibility: hidden
opacity: 1;
}
nav .hover {
color: rgba(0, 0, 0, 0) !important;
-webkit-transition-property: opacity, color, scale;
   -moz-transition-property: opacity, color, scale;
    -ms-transition-property: opacity, color, scale;
     -o-transition-property: opacity, color, scale;
        transition-property: opacity, color, scale;
-webkit-transition-duration: 0s, .2s, .2s;
   -moz-transition-duration: 0s, .2s, .2s;
    -ms-transition-duration: 0s, .2s, .2s;
     -o-transition-duration: 0s, .2s, .2s;
        transition-duration: 0s, .2s, .2s;
-webkit-transition-timing-function: linear, ease-in, ease;
   -moz-transition-timing-function: linear, ease-in, ease;
    -ms-transition-timing-function: linear, ease-in, ease;
     -o-transition-timing-function: linear, ease-in, ease;
        transition-timing-function: linear, ease-in, ease;
 -webkit-transition-delay: .2s, .3s, .2s;
    -moz-transition-delay: .2s, .3s, .2s;
     -ms-transition-delay: .2s, .3s, .2s;
      -o-transition-delay: .2s, .3s, .2s;
         transition-delay: .2s, .3s, .2s;
-webkit-transform: scale(0.9);
   -moz-transform: scale(1);
    -ms-transform: scale(0.9);
     -o-transform: scale(1);
        transform: scale(0.9);
-webkit-backface-visibility: hidden
    opacity: 0.5;
}
nav a:hover {
color: #fff0aa;
-webkit-transition-property: opacity, color, scale;
   -moz-transition-property: opacity, color, scale;
    -ms-transition-property: opacity, color, scale;
     -o-transition-property: opacity, color, scale;
        transition-property: opacity, color, scale;
-webkit-transition-duration: 0s, .2s, .3s;
   -moz-transition-duration: 0s, .2s, .3s;
    -ms-transition-duration: 0s, .2s, .3s;
     -o-transition-duration: 0s, .2s, .3s;
        transition-duration: 0s, .2s, .3s;
-webkit-transition-timing-function: linear, ease-in, ease;
   -moz-transition-timing-function: linear, ease-in, ease;
    -ms-transition-timing-function: linear, ease-in, ease;
     -o-transition-timing-function: linear, ease-in, ease;
        transition-timing-function: linear, ease-in, ease;
 -webkit-transition-delay: .2s, .3s, .2s;
    -moz-transition-delay: .2s, .3s, .2s;
     -ms-transition-delay: .2s, .3s, .2s;
      -o-transition-delay: .2s, .3s, .2s;
         transition-delay: .2s, .3s, .2s;
-webkit-transform: scale(1.1);
   -moz-transform: scale(1);
    -ms-transform: scale(1.1);
     -o-transform: scale(1);
        transform: scale(1.1);
-webkit-backface-visibility: hidden
    opacity: 1;
}
Im einzelnen will ich das gar nicht alles erklären ... es geht bei den unterschiedlichen Zeitangaben immer darum, den Effekt möglichst 'weich' und ohne hektisches Geflacker zu bekommen - deswegen etwa die 'Verzögerung' um .2s/.3s beim Start. Wer das nachbauen will, kann sich ja mal selber an den Zeiten austoben - die Zeiten sind aus try/error entstanden.

Eine hilfreiche [und unbekannte] Funktion ist -webkit-backface-visibility: hidden - die verhindert in Webkit Browser das kurze 'blink' am Ende einer transition.

Anmerkungen, Fragen

Das ist nur eine Spielerei - nix praktisches. Wenn sich jemand dran versucht und was schönes aus dem Effekt macht, würde mich das aber schon interessieren ...