Moving Highlight

Avatar of Chris Coyier
Chris Coyier on

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

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:

  1. Wenn sich die Maus über den Bereich bewegt
  2. Mausposition erkennen
  3. Gradienten an der entsprechenden Position auf den Bereich anwenden
  4. 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 });
});

Demo ansehen   Dateien herunterladen