我 最近注意到 Google Chrome UI 中的一个微妙而漂亮的效果。 当您将鼠标悬停在非活动标签上时,它们会稍微亮起来,并且还会有一个跟随您鼠标在它们上面移动的渐变高亮。
来自 DOCTYPE 的家伙告诉我这是他们网站导航的灵感来源。 他们 正在做 我会做的事情,使用 CSS3 渐变和 jQuery。 因此,我决定获取他们的代码并试着玩一下。
径向渐变
高亮本身将由径向渐变创建。 一种可能的方法是创建一个 alpha 透明的 PNG 图片并使用它。 但我们喜欢在这里保持时尚和进步。 径向渐变可以通过 CSS3 创建,这为我们节省了一个资源请求并允许更轻松地更改颜色。
基于 Webkit 和 Mozilla 的浏览器(仅)可以执行径向渐变。 语法
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
);
JavaScript 鼠标位置
现在我们知道如何应用 CSS3 渐变,但这样做是为了在鼠标所在的位置应用渐变高亮。 CSS 无法提供鼠标位置坐标,我们需要 JavaScript 来实现。 因此,计划如下
- 当鼠标移到该区域时
- 检测鼠标位置
- 将渐变应用于该位置的区域
- 当鼠标离开时移除渐变
我们将使用 jQuery。
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
});
供应商前缀在值中的麻烦
供应商前缀作为属性是可以的。 您想跨浏览器旋转某个东西(使用动态 JavaScript 值),您需要使用 -webkit-transform
、-o-transform
和 -moz-transform
。 如果您需要使用 jQuery 来完成它,您可以这样做
var angle = 30;
$(".rotate-me").css({
"-webkit-transform" : "rotate(" + angle + "deg)",
"-moz-transform" : "rotate(" + angle + "deg)"
"-o-transform" : "rotate(" + angle + "deg)"
});
这有效是因为每个属性都不同。 对于渐变,属性始终相同,即 background-image
属性。 因此,就像这样不起作用
$(".wont-make-purple").css({
"color" : "red",
"color" : "blue" // overrides previous
});
这也将不起作用
$("#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)"
});
但不知何故,无法解释(并且值得庆幸的是)这样做有效
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 });
一定有一些神奇的智能功能集成在其中,它不会覆盖之前设置的值。
高亮标签
因此,让我们给自己一些实际的标签来进行高亮。 标记中没有什么特别之处
<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>
以及使其看起来像标签的 CSS
.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;
}
所以现在每个标签都是我们计划应用高亮的区域。 对于每个非活动标签,我们将把我们已经涵盖的所有内容整合在一起
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 });
});
CSS 供应商前缀越来越混乱和冗长。 编码/网络工作本身已经够令人沮丧的了,而不需要加入长长的数学算法。 接下来是什么?{ -webkit-triangle: 毕达哥拉斯定理除以 Pi 乘以 8 再除以 0; }
渐变无疑是那些让人感觉混乱的 CSS3 属性/值之一。 尤其是当不同浏览器之间的语法差异如此之大时。 但请考虑这实际上是一项多么复杂的任务。 用设计师可能想要的所有灵活性来描述一个彩色渐变并非易事。 你让它越强大和灵活,语法就越复杂(人们就会抱怨)。 你让语法越简单,它的功能就越弱(人们也会抱怨)。
我相信,如果你(或者我,或者任何其他人)有想法让渐变的语法既强大又简洁,人们会听的。
使用 compass/sass... 不用多说...
不错。 我昨天自己也创建了一个使用完全相同技术的版本。 看到像 CSS3 中的渐变和阴影这样的标准化,意味着越来越多的设计元素有明显的“最佳”实现方式,这很有趣。
这个
不起作用是因为,真正发送给 jQuery.CSS 方法的是这个对象
这与第二个有效的示例不同...
... 因为正如我们所看到的,对 .css() 的调用是多次的,因此 bgMoz 没有覆盖 bgWebkit。 我没有检查这一点,但似乎 jQuery 理解“background-image”可以具有多个 -prefix- 值。
没错。
jQuery 肯定只是知道不要使用某些值(如渐变)来取消设置某些属性。 因为如果您尝试使用像
color
这样的属性进行相同的双重 .css() 操作,它肯定会遭到覆盖。实际上,jQuery 与此无关。 最终,是浏览器解释了该值并决定是否应该设置或忽略它。
var elStyle = document.getElementById(“hello”).style;
// 这会将文本颜色设置为红色
elStyle.color = “red”;
// “blah” 无法识别为有效的颜色,因此此声明被忽略
elStyle.color = “blah”;
请注意“忽略”这个词:当给出无效值时,浏览器不会将 CSS 属性的当前值重置为默认值。 浏览器对 CSS 文件也应用相同的原则,这就是为什么您可以使用某些浏览器会覆盖而另一些浏览器会忽略的 CSS hack。 再次说明,它们不是被重置,而是被忽略了!
因此,您第一次尝试失败的唯一原因是因为 JavaScript 对象不能具有相同名称的属性。 Mozilla 浏览器不知道
-webkit-gradient
的含义,因此它会忽略整个规则,并保留background-image
的当前值。 但是,当它收到-moz-radial-gradient
作为值时,它将很乐意覆盖background-image
属性。 Webkit 浏览器也遵循相同的原则,唯一的区别是它们会使用第一个声明来覆盖该属性,然后会忽略第二个声明,同时保留当前值。jQuery 做了很多很棒的事情,但在这里,它只是浏览器在遵循规范。 :-)
使用 Windows Vista/7 的用户也会熟悉这种技术。 当您将鼠标悬停在任务栏项目上时,也会出现相同的效果。 这真是个很棒的小技巧。
Windows Vista/7 做的另一件很酷的事情是,它会根据图标中的颜色更改任务栏项目的突出显示颜色。 我在某处读到,他们创建了一个算法来查找图标中最突出的颜色,并将其设置为突出显示颜色。 例如,Firefox 的突出显示颜色是橙色,因为狐狸身上最突出的颜色是橙色。 使用网络技术来尝试实现这种功能将会很酷… *眨眨眼* :P
这将会非常有趣,但我认为同时实现它非常困难,因为据我所知,目前还没有使用 JavaScript 读取图像颜色(不使用 canvas)的原生方法。
因此,您可以通过为要使用的每种颜色创建不同的类和脚本,将整个过程硬编码。
嗨,我正要指出这一点,并做了 ctrl + f 来看看是否有人已经指出了这一点。
伟大的思想... James : – )
这很好,但是那些(将会)支持没有前缀的属性的浏览器怎么办? 你总是省略它们! 如果你这样做是为了节省空间/字节,我想说你省略了最重要的部分。 这段代码现在可以使用,而且离未来兼容性还很远。
你会包含什么? Opera 还不支持渐变,而这两个支持它的浏览器使用的语法完全不同。 我绝不会基于对浏览器未来可能如何实现某个功能的理论假设来实现某些功能(除非它是绝对最终的规范)。
至少在 CSS 中使用 box-shadow 和 border-radius。
我想这是一个常见的最佳实践,在使用前缀的规则之后包含一个没有前缀的规则版本,以确保实现它的浏览器使用它。
顺便说一句,webkit 正在改变其渐变语法,转而支持标准语法。
渐变的标准语法是什么?!
是 Firefox 实现的语法。
http://dev.w3.org/csswg/css3-images/#gradients
不错的效果,但是你可能需要在鼠标最初悬停时添加淡入效果,否则它会突然出现。在 Chrome 中,它会更加微妙一点 :)
我研究了很久,我打算包含一个实现这个效果的版本,只是它太复杂了。它涉及添加一个额外的元素专门用于突出显示,这个元素必须被特殊定位,然后文本还需要另一个元素来保持它在渐变之上。还有其他问题。我认为它使教程过于复杂,不值得这样做,但我同意,淡入效果更漂亮。
嘿,Chris -
不错的效果 -
标题“JavaScript Mouse Postion”有一个错别字。
不错的微妙效果;这是在设计中添加一些细节,而不告诉任何人的完美方法。
很棒的教程。以前不知道 CSS3 渐变的这个特性!
谢谢,Chris。
哇,太酷了!
我喜欢你的教程。感谢分享。
哇,很酷,可以稍微淡一点...
谢谢^^
我一直想知道怎么做这个,并且在 Google 上搜索了很多次,试图找到它。终于有人解释了它是如何做到的!
谢谢!
很棒!我一直试图在我的网站上做出一些变化,而这个效果太酷了,无法尝试,非常感谢你发布它。
别笑我,但我从未在 Chrome 中见过这种效果,并且专门寻找过,它绝对没有发生;在 Vista 或 Ubuntu 上都没有。有什么想法吗?
如果启用 AEREO 主题,它会在 Windows 7 任务栏上出现。
我也是,我在使用 Aero 的 Windows 7 Enterprise 上运行 Google Chrome Beta 9.0.597.45,没有使用任何自定义主题或扩展程序,我没有看到那个效果;只有在 Windows 任务栏上(正如其他人提到的)。
嗯,我今天注意到 Twitter 新粉丝和 YouTube 订阅者数量有所增加。感谢你的推荐!:) 实际上是 Jim 写了那段代码,而不是我,所以一定要感谢他。
很不错,同意 Pavel 的说法,在使用前缀的规则之后包含一个没有前缀的规则版本是最佳实践。
嗨,Chris,
我有一个与这篇文章无关的问题,但我认为这是联系你的最佳方式,抱歉,但我做了你做的 Lynda.com 教程,顺便说一句,我推荐给所有人,我有一个小问题,如何在 WAMP 中构建 WordPress 网站之后发布它,我的意思是路径和数据库,感谢你的帮助。
非常酷,
这是我第一次注意到 Google Chrome 的 UI,并且想知道有人会如何为网页实现它。这是一个很棒的教程。
我认为唯一缺少的是让突出显示效果淡入淡出,而不是像 Chrome 一样只在悬停在不同的“选项卡”或“链接”上时才出现。然后它就完美了。
很棒的教程;迫不及待地想自己尝试一下。这是一个具有多种可能性且非常微妙的效果。
对于我之前的帖子表示歉意,我没有阅读之前已经提到了淡入淡出的帖子。
只有安装了标准 Google Chrome v8 主题才能使用。
这是一个非常酷的效果。我可能在不久的将来尝试在一些项目中使用它。我喜欢阅读你看到了一些有趣的东西,然后尽力为网页尽可能简单地重现它的帖子。非常有启发性。
Safari 呢?
只有我一个人,还是 Chrome 中的选项卡(在实时演示中)坏了?
弯曲边缘后面的背景是白色的...
很棒的演示 - 让我想复制到我们网站的导航中 - 但是我注意到在 Chrome 8(仅限 PC)中,弯曲边缘实际上是白色的。有没有解决方法?
有点奇怪...
删除 -webkit-box-shadow: white 1px 1px 0px inset; 然后它在 Chrome 8 中就可以工作了... 不过还需要看看这对其他 webkit 浏览器有什么影响...
嗨,
感谢这个很棒的教程。我真的很喜欢它。
我认为添加一个淡出效果可以让这个突出显示效果更棒,当你在另一个选项卡上移动时,它会淡出 :)。
@Chris
是 box-shadow 是白色的。
非常酷,
这是我第一次注意到 Google Chrome 的 UI,并且想知道有人会如何为网页实现它。这是一个很棒的教程。
你的教程越来越好了!
不错的效果。你没有使用 e.layerX 和 e.layerY 的原因是什么?(e.pageX - this.offsetLef) 如果容器没有接触边缘,可能会出错。
https://mdn.org.cn/en/DOM/event.layerX
我尝试在我的页面上使用这段代码,但渐变仍然始终处于错误的位置。
当我使用 e.layerX 时,它只对第一个列表元素起作用,在第二个元素上,渐变再次处于错误的位置。
有人知道我哪里出错了?
%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)....
我只是想了一下,并在 Google 上搜索了一下。感谢你的提醒!