与渐晕作伴的旅程 (That Doesn’t Get Very Far)

Avatar of Chris Coyier
Chris Coyier

DigitalOcean 为您的旅程各个阶段提供云产品。立即开始使用 $200 免费积分!

老 Trent 在 使用内嵌 box-shadow 发布了一篇关于简单而优雅效果的快速技巧文章。其中一项技术最终在图像顶部产生了渐晕效果。就像这样

是的,您可以在 Photoshop 中做到这一点,但通过 CSS 完成它意味着 1) 它是非破坏性的 2) 可以通过编程方式更改 3) 非常一致

当我第一次看到这个示例时,我想,嘿,这很酷,但为什么要用包装 div 呢?浏览器允许在 <img> 元素上使用 box-shadow,所以为什么不直接在它上面使用内嵌 box-shadow 呢。这样 HTML 会更简洁。

<img src="amazinglandscape.jpg" alt="ooooh ahhhh" class="vignette">
.vignette {
	-webkit-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
	-moz-box-shadow:    inset 0px 0px 85px rgba(0,0,0,0.4);
	box-shadow:         inset 0px 0px 85px rgba(0,0,0,0.4);
}

事实证明,您可以在图像上使用内嵌 box-shadow,只是浏览器将其设置在图像后面,这意味着如果您使用完全不透明的图像(如果您想对其进行渐晕,这很可能),您根本看不到阴影。Trent 说

虽然这看起来很没用,但当您考虑其他类型的内容时,它确实是有道理的。例如,如果您内嵌阴影,您可能不希望它遮盖其中的文本。

我还同意 Trent 的另一个观点:也许 box-shadow 的官方规范应该更改,以便在直接应用于图像时,阴影应该在顶部。遗憾的是,规范和实现都没有这样做。

然后我想,等等,我们先不要使用包装元素。毕竟,保持我们的 HTML 免于非语义包装器是一个崇高的目标。为什么不在图像上使用伪元素,我们可以强制它位于顶部并与图像完全相同的大小,然后在该元素上设置内嵌 box-shadow 呢?

.vignette:after {
	-webkit-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
	-moz-box-shadow:    inset 0px 0px 85px rgba(0,0,0,0.4);
	box-shadow:         inset 0px 0px 85px rgba(0,0,0,0.4);

	position: absolute;
	top: 0; left: 0; bottom: 0; right: 0;
	content: "";
}

当我正在为此制作演示时,它一直无法正常工作,把我搞得晕头转向。有一分钟,我想,我想知道 :before 和 :after 伪元素是否在内联元素* 上不起作用,但 我证明了它们在 span 上起作用,因此可以排除。

然后我 Nicholas Gallagher 那里得知

没有具有“空”内容模型的元素支持通过伪元素生成的 内容

Nicholas 基本上是指任何没有 innerHTML 的元素。想想

<br />
<br />
<input />
<img />

这显然是因为 规范没有解释如何处理这种类型的元素。

就像内嵌 box-shadow 一样,它有一定的道理。您可以将 :before 伪元素视为在标签内,但在其他内容之前,将 :after 伪元素视为在标签内,但在其他内容之后。

<div>
   <!-- :before pseudo element -->
   Hi! I'm content!
   <!-- :after pseudo element -->
</div>

<img /> <!-- Where would pseudo content go? -->

对于 jQuery 用户,Tim Wright 解释说

它是 :after 更像 jQuery 的 .append() 而不是 .after(),所以您不能将某个东西塞到 <img> 的中间

如果您在想,伙计,只要将伪元素放在该元素的 AFTER 或 BEFORE 就可以了,您并不孤单。问题是这与它在其他元素上的工作方式不一致,并且规范没有涵盖它。为了使事情变得更复杂,这实际上是 Opera 的做法。

总之……关于如何干净地完成它的想法就这些了。我们只要使用包装 div 就可以了

<div class="vignette">
	<img src="handsomepeople.jpg" alt="ooooh ahhhh">
</div>
.vignette {
	-webkit-box-shadow: inset 0px 0px 85px rgba(0,0,0,0.4);
	-moz-box-shadow:    inset 0px 0px 85px rgba(0,0,0,0.4);
	box-shadow:         inset 0px 0px 85px rgba(0,0,0,0.4);
	
	line-height: 0;         /* ensure no space between bottom */
		
	display: inline-block;  /* don't go wider than image */
}
.vignette img {
	position: relative; 
	z-index: -1;            /* position beneath */
}

一个可能是理想的、也可能很烦人的副作用?使用 div 覆盖,您无法右键单击保存图像或将其拖动到桌面。非常原始的图像保护。

查看演示

相关

  • 另一种技术 由 Dudley Storey 提供,它让您将图像作为渐晕元素的背景图像。可能更适合一次性使用,但对于只需要在任何地方使用它而无需一直更改 CSS 的网站来说,更难使用。

* 顺便说一下,我在阅读 Introducing HTML5 时,了解了一个有趣的观点。在 HTML5 中,内联元素和块元素之间实际上没有区别。所有元素都是内联的,除非由浏览器或用户样式表另行指定。