Ich habe kürzlich einen subtilen und schönen Effekt in der Benutzeroberfläche von Google Chrome bemerkt. Wenn man mit der Maus über inaktive Tabs fährt, leuchten sie ein wenig auf und haben einen Gradienten-Highlight, der der Maus folgt, während man sich darüber bewegt.

Die Jungs von DOCTYPE sagten mir, dass dies ihre Inspiration für die Navigation auf ihrer Website war. Sie machen es genauso, wie ich es gemacht hätte, mit CSS3-Gradients und jQuery. Also beschloss ich, ihren Code zu nehmen und damit herumzuspielen.
Radialer Gradient
Das Highlight selbst wird aus einem radialen Gradienten erstellt. Eine mögliche Methode dafür wäre, ein PNG-Bild mit transparenter Alpha-Ebene zu erstellen und dieses zu verwenden. Wir mögen es hier jedoch, hip und fortschrittlich zu sein. Radiale Gradienten können durch CSS3 erstellt werden, was uns eine Ressourcenanfrage spart und einfache Farbänderungen ermöglicht.
Webkit- und Mozilla-basierte Browser (nur) können radiale Gradienten erstellen. Die Syntax
background: -webkit-gradient(
/* radial, <point>, <radius>, <point>, <radius>, <stop>, [<stop>, ] <stop> */
radial, 500 25%, 20, 500 25%, 40, from(white), to(#ccc)
);
background: -moz-radial-gradient(
/* [<position>,] [<shape> || <size>,] <stop> [, <stop>], <stop> */
500px 25%, circle, white 20px, #ccc 40px
);

Mausposition per JavaScript
Jetzt wissen wir, wie man einen CSS3-Gradienten anwendet, aber der Sinn der Sache ist, den Gradienten-Highlight dort anzuwenden, wo sich die Maus befindet. CSS ist nicht in der Lage, uns Mausposition-Koordinaten zu liefern, dafür brauchen wir JavaScript. Hier ist der Plan:
- Wenn sich die Maus über den Bereich bewegt
- Mausposition erkennen
- Gradienten an der entsprechenden Position auf den Bereich anwenden
- Gradienten entfernen, wenn die Maus den Bereich verlässt
Wir werden jQuery verwenden.
var x, y;
$('#highlight-area').mousemove(function(e) {
x = e.pageX - this.offsetLeft;
y = e.pageY - this.offsetTop;
// apply gradient using these coordinates
}).mouseleave(function() {
// remove gradient
});
Probleme mit Vendor-Präfixen in Werten
Vendor-Präfixe als Eigenschaften sind in Ordnung. Wenn Sie etwas browserübergreifend drehen möchten (mit einem dynamischen JavaScript-Wert), müssen Sie -webkit-transform, -o-transform und -moz-transform verwenden. Wenn Sie dies mit jQuery tun müssen, könnten Sie Folgendes tun:
var angle = 30;
$(".rotate-me").css({
"-webkit-transform" : "rotate(" + angle + "deg)",
"-moz-transform" : "rotate(" + angle + "deg)"
"-o-transform" : "rotate(" + angle + "deg)"
});
Das funktioniert, weil jede der Eigenschaften unterschiedlich ist. Bei Verläufen ist die Eigenschaft immer dieselbe, nämlich die background-image-Eigenschaft. Also wird Folgendes nicht funktionieren:
$(".wont-make-purple").css({
"color" : "red",
"color" : "blue" // overrides previous
});
Das wird auch nicht funktionieren:
$("#highlight-area").css({
"background-image" : "-webkit-gradient(radial, " + xy + ", 0, " + xy + ", " + gradientSize + ", from(" + lightColor + "), to(rgba(255,255,255,0.0))), " + originalBG;
"background-image" : "-moz-radial-gradient(" + x + "px " + y + "px 45deg, circle, " + lightColor + " 0%, " + originalBGplaypen + " " + gradientSize + "px)"
});
Aber irgendwie, unerklärlicherweise (und zum Glück) funktioniert dies:
var bgWebKit = "-webkit-gradient(radial, " + xy + ", 0, " + xy + ", " + gradientSize + ", from(" + lightColor + "), to(rgba(255,255,255,0.0))), " + originalBGplaypen;
var bgMoz = "-moz-radial-gradient(" + x + "px " + y + "px 45deg, circle, " + lightColor + " 0%, " + originalBGplaypen + " " + gradientSize + "px)";
$(this)
.css({ background: bgWebKit })
.css({ background: bgMoz });
Es muss dort eine magische Intelligenz eingebaut sein, die nicht die zuvor gesetzten Werte überschreibt.
Hervorgehobene Tabs
Lasst uns also die eigentlichen Tabs erstellen, die wir hervorheben wollen. Nichts Besonderes im Markup.
<ul class="nav clearfix">
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li class="active"><a href="#">Clients</a></li>
<li><a href="#">Contact Us</a></li>
</ul>
Und der CSS, um sie tab-ähnlich zu machen.
.nav {
list-style: none;
border-bottom: 1px solid #a0a0a0;
padding: 10px 10px 0 10px;
}
.nav li { display: inline; }
.nav li.active a {
position: relative;
z-index: 1;
bottom: -2px;
margin-top: -2px;
background: #eee;
padding-top: 8px;
padding-bottom: 8px;
}
.nav li a {
float: right;
text-decoration: none;
position: relative;
padding: 7px 50px;
margin: 0 0 0 -8px;
color: #222;
background: #d8d7d8;
-webkit-border-top-right-radius: 20px 40px;
-webkit-border-top-left-radius: 20px 40px;
-moz-border-radius-topleft: 20px 40px;
-moz-border-radius-topright: 20px 40px;
-webkit-box-shadow: inset 1px 1px 0 white;
-moz-box-shadow: inset 1px 1px 0 white;
border: 1px solid #a0a0a0;
}
Nun ist jeder dieser Tabs der Bereich, in dem wir das Highlight anwenden wollen. Für jeden nicht aktiven Tab werden wir alle abgedeckten Dinge zusammenstellen.
var originalBG = $(".nav a").css("background-color");
$('.nav li:not(".active") a')
.mousemove(function(e) {
x = e.pageX - this.offsetLeft;
y = e.pageY - this.offsetTop;
xy = x + " " + y;
bgWebKit = "-webkit-gradient(radial, " + xy + ", 0, " + xy + ", 100, from(rgba(255,255,255,0.8)), to(rgba(255,255,255,0.0))), " + originalBG;
bgMoz = "-moz-radial-gradient(" + x + "px " + y + "px 45deg, circle, " + lightColor + " 0%, " + originalBG + " " + gradientSize + "px)";
$(this)
.css({ background: bgWebKit })
.css({ background: bgMoz });
}).mouseleave(function() {
$(this).css({ background: originalBG });
});

Die CSS-Vendor-Präfixe werden lächerlich verwirrend und lang. Codieren/Webarbeit kann frustrierend genug sein, ohne lange mathematische Algorithmen einzubringen. Was kommt als nächstes? { -webkit-triangle: Satz des Pythagoras geteilt durch Pi * 8 geteilt durch 0; }
Verläufe sind sicherlich eine dieser CSS3-Eigenschaft/Wert-Kombinationen, die verwirrend sein können. **Besonders** wenn die Syntax zwischen den verschiedenen Browsern so unterschiedlich ist. Aber bedenken Sie, was für eine komplexe Aufgabe das ist. Einen farbigen Verlauf mit all der Flexibilität zu beschreiben, die ein Designer jemals wollen würde, ist keine einfache Aufgabe. Je leistungsfähiger und flexibler Sie ihn gestalten, desto komplexer wird die Syntax (und die Leute beschweren sich darüber). Je einfacher Sie die Syntax gestalten, desto weniger leistungsfähig ist sie (und die Leute beschweren sich darüber).
Ich bin sicher, wenn Sie (oder ich oder irgendjemand anders) eine Idee hätten, wie man eine Syntax für Verläufe erstellt, die sowohl extrem leistungsfähig als auch extrem prägnant ist, würden die Leute zuhören.
Verwenden Sie Compass/Sass.. mehr muss nicht gesagt werden..
Schön. Ich habe gestern selbst eine Version davon erstellt, indem ich genau dieselben Techniken verwendet habe. Es ist interessant zu sehen, wie die Standardisierung von Dingen wie Verläufen und Schatten in CSS3 bedeutet, dass es immer mehr einen offensichtlichen "besten" Weg gibt, bestimmte Designelemente zu implementieren.
Das hier
funktioniert nicht, weil das, was wirklich an die jQuery.CSS-Methode gesendet wurde, dieses Objekt war:
was sich vom zweiten Beispiel unterscheidet, das funktioniert…
… denn wie wir sehen können, gibt es mehrere Aufrufe von .css(), sodass bgMoz nicht bgWebkit überschreibt. Ich habe das nicht überprüft, aber es scheint, dass jQuery versteht, dass „background-image“ mehrere -prefix-Werte haben kann.
Genau.
jQuery muss einfach wissen, dass bestimmte Eigenschaften mit bestimmten Werten, wie Verläufe, nicht unset werden. Denn wenn Sie dieselbe doppelte .css()-Idee mit einer Eigenschaft wie
colorversuchen würden, würde sie definitiv überschrieben werden.Eigentlich hat jQuery nichts damit zu tun. Am Ende ist es der Browser, der den Wert interpretiert und bestimmt, ob er ihn setzen oder ignorieren soll.
var elStyle = document.getElementById("hello").style;
// Dies setzt die Textfarbe auf Rot
elStyle.color = "red";
// "blah" wird nicht als gültige Farbe erkannt, daher wird diese Deklaration ignoriert
elStyle.color = "blah";
Beachten Sie das Wort *ignoriert*: Wenn ein ungültiger Wert angegeben wird, setzt der Browser nicht den aktuellen Wert der CSS-Eigenschaft auf den Standardwert zurück. Der Browser wendet das gleiche Prinzip auch auf CSS-Dateien an, weshalb Sie mit CSS-Hacks davonkommen können, die von einigen Browsern überschrieben und von anderen ignoriert werden. Wiederum werden sie nicht zurückgesetzt, sondern ignoriert!
Daher ist der einzige Grund, warum Ihr erster Versuch fehlgeschlagen ist, dass JavaScript-Objekte keine Eigenschaften mit demselben Namen haben können. Ein Mozilla-Browser weiß nicht, was
-webkit-gradientbedeutet, daher ignoriert er die gesamte Regel und behält einfach den aktuellen Wert fürbackground-imagebei. Wenn er jedoch-moz-radial-gradientals Wert erhält, wird er diebackground-image-Eigenschaft gerne überschreiben. Das gleiche Prinzip gilt für Webkit-Browser, der einzige Unterschied ist, dass sie die Eigenschaft mit der ersten Deklaration überschreiben und dann die zweite Deklaration ignorieren, während sie den aktuellen Wert beibehalten.jQuery leistet Erstaunliches, aber hier folgen die Browser den Spezifikationen. :-)
Benutzer von Windows Vista/7 werden mit dieser Technik ebenfalls vertraut sein. Derselbe Effekt tritt auf, wenn Sie mit der Maus über die Taskleistenelemente fahren. Es ist ein hübsches kleines Juwel.
Eine weitere coole Sache, die Windows Vista/7 tut, ist, dass es die Highlight-Farbe der Taskleistenelemente basierend auf den Farben im Icon ändert. Ich habe irgendwo gelesen, dass sie einen Algorithmus erstellt haben, der die auffälligste Farbe im Icon findet und diese als Highlight-Farbe festlegt. Zum Beispiel ist die Highlight-Farbe für Firefox Orange, weil die auffälligste Farbe das Orange auf dem Fuchs ist. Wäre toll, das mit Webtechnologien zu versuchen... *zwinker zwinker* :P
Das wird wirklich interessant sein, aber ich denke, es ist gleichzeitig wirklich schwierig zu implementieren, denn soweit ich weiß, gibt es keine native Möglichkeit, die Farben eines Bildes mit JavaScript zu lesen (ohne Canvas zu verwenden).
Man könnte also alles hartcodieren, indem man verschiedene Klassen und Skripte für jede gewünschte Farbe erstellt.
Hey, ich wollte das gerade anmerken und habe Strg + F gedrückt, um zu sehen, ob es jemand bemerkt hat.
Gleich und gleich gesellt sich gern... James :–)
Das ist alles schön und gut, aber was ist mit Browsern, die die Eigenschaften ohne Präfixe unterstützen (werden)? Sie lassen sie immer weg! Wenn Sie das tun, um Platz/Bytes zu sparen, würde ich sagen, dass Sie die wichtigsten Teile weglassen. Das ist der Code, der JETZT funktioniert und nichts mit Zukunftssicherheit zu tun hat.
Was würden Sie einbeziehen? Opera unterstützt noch keine Verläufe, und die beiden Browser, die es tun, tun es auf völlig unterschiedliche Weise. Ich würde niemals etwas implementieren, basierend auf der theoretischen Annahme, wie ein Browser etwas in Zukunft implementieren könnte (es sei denn, es ist der absolute Endstandard).
Zumindest box-shadow und border-radius in den CSS.
Ich schätze, es ist eine gängige bewährte Methode, eine nicht-präfixierte Version einer Regel nach den präfixierten hinzuzufügen, um sicherzustellen, dass Browser, die sie implementieren, sie verwenden.
Und übrigens ändert Webkit seine Gradienten-Syntax zugunsten der Standard-Syntax.
Wie wird die Standard-Syntax für Verläufe aussehen?
Es ist die, die Firefox implementiert.
http://dev.w3.org/csswg/css3-images/#gradients
Schöner Effekt, aber Sie sollten vielleicht den Fade-In-Effekt hinzufügen, wenn die Maus zum ersten Mal darüber fährt, sonst "ploppt" es einfach auf. Es ist in Chrome etwas subtiler :)
Ich habe lange daran gearbeitet, ich plante, eine Version zu integrieren, die das tut, es war nur WEITAUS komplizierter. Es erforderte die Hinzufügung eines zusätzlichen Elements nur für das Highlight, das speziell positioniert werden musste, und dann benötigte der Text ebenfalls ein weiteres Element, um ihn über dem Gradienten zu halten. Und es gab auch andere Probleme. Ich dachte, es würde das Tutorial zu sehr verkomplizieren, als dass es sich lohnen würde, aber ich stimme zu, mit einem Fade ist es viel schöner.
Hallo Chris –
Schöner Effekt –
es gibt einen Tippfehler in der Überschrift "JavaScript Mouse Postion"
Schöner subtiler Effekt; das ist genau die Art von Sache, die man in ein Design einbauen kann, ohne es jemandem zu erzählen, nur als zusätzliches Detail.
Fantastisches Tutorial. Ich wusste nicht, dass das mit CSS3-Gradients geht!
Danke, Chris
Wow, das ist so cool!
Ich mag dein Tutorial. Danke fürs Teilen.
wow es ist cool, es kann leicht sein…
danke^^
Ich wollte schon immer wissen, wie man das macht, und habe unzählige Male bei Google danach gesucht. Endlich hat jemand erklärt, wie es gemacht wird!
Danke!
Gut gemacht! Ich habe versucht, ein paar Variationen für meine Website zu erstellen, und diese hier wäre viel zu cool, um sie auszuprobieren, vielen Dank für die Veröffentlichung.
Nenn mich verrückt, aber ich habe diesen Effekt nie in Chrome gesehen und gerade extra danach gesucht, und er tritt definitiv nicht auf; weder unter Vista noch unter Ubuntu. Irgendwelche Ideen?
Das passiert auf der Windows 7 Taskleiste, wenn Sie das AEREO-Theme aktivieren.
Das Gleiche hier, ich benutze Windows 7 Enterprise mit Aero und Google Chrome Beta 9.0.597.45 ohne eigenes Theme oder Erweiterungen, und ich sehe diesen Effekt nicht; nur auf der Windows-Taskleiste (wie andere erwähnt haben).
Hm, ich bemerkte heute eine höhere Anzahl neuer Twitter-Follower und YouTube-Abonnenten. Danke für die Erwähnung! :) Jim hat diesen Code geschrieben, nicht ich, also Lob an ihn.
Es ist schön, stimme Pavel zu, dass es eine bewährte Methode ist, eine nicht-präfixierte Version einer Regel nach den präfixierten hinzuzufügen.
Hallo Chris,
Ich habe eine Frage, die nichts mit dem Beitrag zu tun hat, aber ich dachte, das sei der beste Weg, Sie zu kontaktieren, sorry dafür, aber ich habe das Lynda.com-Tutorial gemacht, das Sie gemacht haben und das ich übrigens jedem empfehle, und ich habe ein kleines Problem, wie ich die WordPress-Website nach dem Erstellen in Wamp veröffentlichen kann, ich meine den Pfad und die Datenbank, danke für Ihre Hilfe.
Sehr cool,
Das war eines der ersten Dinge, die mir an der Benutzeroberfläche von Google Chrome aufgefallen sind und ich habe mich gefragt, wie jemand das für das Web machen würde. Das ist ein so tolles Tutorial.
Ich denke, das Einzige, was fehlen würde, ist, den Highlight-Effekt ein- und auszublenden, anstatt ihn einfach erscheinen zu lassen, wenn man über die verschiedenen "Tabs" oder "Links" fährt, genau wie Chrome es tut. Dann wäre das makellos.
Tolles Tutorial; ich kann es kaum erwarten, es selbst auszuprobieren. Das ist ein großartiger subtiler Effekt mit vielfältigen Möglichkeiten.
Es tut mir sehr leid wegen meines frühen Beitrags, ich hatte einen der Beiträge nicht gelesen, der bereits das Ein- und Ausblenden angesprochen hat.
Es funktioniert nur, wenn Sie das Standard-Google-Chrome-v8-Theme installiert haben.
Das ist ein wirklich cooler Effekt. Ich werde das vielleicht bei zukünftigen Projekten ausprobieren. Ich lese gerne Ihre Beiträge, bei denen Sie etwas Interessantes sehen und es dann versuchen, es so einfach wie möglich für das Web nachzubauen. Sehr inspirierend.
Safari?
Bin ich der Einzige, oder brechen die Tabs (in der Live-Demo) in Chrome ab?
Die Hintergründe hinter den gebogenen Kanten sind weiß…
Tolle Demo – hat mich dazu gebracht, das für die Navigation unserer Website kopieren zu wollen – allerdings habe ich festgestellt, dass in Chrome 8 (nur auf PC) die gebogenen Kanten tatsächlich weiß sind. Gibt es dafür eine Umgehung?
Das ist etwas seltsam…
Entfernen Sie das -webkit-box-shadow: white 1px 1px 0px inset; und es funktioniert in Chrome 8… mal sehen, was das für die anderen Webkit-Browser bedeutet…
Hallo,
Danke für dieses nette Tutorial. Es hat mir sehr gut gefallen
Ich denke, eine Ergänzung würde dieses Highlight fantastischer machen, nämlich das Ausblenden des Highlights, wenn Sie zu einem anderen Tab wechseln :)
@Chris
Es ist der Box-Schatten, der weiß ist.
Sehr cool,
Das war eines der ersten Dinge, die mir an der Benutzeroberfläche von Google Chrome aufgefallen sind, und ich habe mich gefragt, wie jemand das für das Web machen würde. Das ist ein so tolles Tutorial.
Ihre Tutorials werden immer besser!
Schöner Effekt. Gibt es einen Grund, warum Sie e.layerX und e.layerY nicht verwendet haben? (e.pageX – this.offsetLef) kann falsch sein, wenn der Container nicht die Ränder berührt.
https://developer.mozilla.org/en/DOM/event.layerX
Ich versuche, diesen Code auf meiner Seite zu verwenden, aber der Gradient ist immer noch an der falschen Position.
Wenn ich e.layerX verwende, funktioniert es nur für das erste Listenelement, beim zweiten Element ist der Gradient wieder an der falschen Position.
Weiß jemand, wo ich falsch liege?
%nav
%ol
%li= link_to "link1", root_path
%li= link_to "link2", root_path
%li= link_to "link3", root_path
$('nav li').mousemove(function(e)....
Ich denke gerade darüber nach und google es. Danke für die Umsetzung!