从太阳的自然光到我们家中的人造光,离线世界中的光线无处不在。光线会影响我们的视觉能力,也可以用来创造美感。您可以使用 CSS 创建光效,从而提高网站的视觉吸引力。虽然网页没有光源,但我们可以利用 CSS 的一些属性和元素来创建模仿光线的视觉效果。本文将向你展示用 CSS 创建光效的五种方法。
霓虹灯或荧光灯
在现实世界中,霓虹灯是通过电流穿过气体而产生的。霓虹灯的亮度和色彩取决于气体的种类。因此,霓虹灯常用于装饰展示。
您可以使用 CSS 为阴影添加颜色,从而创建这种效果。您可以使用两个属性来创建阴影,即 box-shadow
和 text-shadow
。
box-shadow
属性会在元素周围添加阴影,而 text-shadow
则会在文字周围添加阴影。
这是我们正在使用的 HTML:
<div> <h1>Neon/Glowing Light</h1> <h3>Colored shadows create glowing light</h3> </div>
下面介绍如何使用 box-shadow
创建霓虹灯效果:
.content { box-shadow: 0px 0px 10px 10px #00c2cb; }
下面是如何使用 text-shadow
进行相同操作:
.content h1 { text-shadow: 0px 0px 10px #00c2cb, 0px 0px 20px #fff; }
下面是一张截图,显示了它的外观:
box-shadow
和 text-shadow
的样式类似。不同的是,文字阴影没有 spread
。
您可以添加多个阴影层并使用不同的颜色来创建这种效果。
下面是 CodePen 演示:
请注意,还有第三种为元素添加阴影的方法,那就是使用 CSS drop-shadow()
过滤器。该过滤器只适用于图像,非常适合为背景透明的图像添加阴影。
漫反射
漫反射是指光线从粗糙的表面反射出来,如水泥墙、地板、纸张和衣服。
为此,您将使用 :before
伪元素。您可以使用任何 HTML 元素,但在本例中我们将使用一些文本。
<div> <h1>Diffuse Reflection</h1> </div>
接下来,创建一个伪元素,其 background-color
和尺寸与文本相同:
.content h1 { position: relative; font-size: 3rem; font-weight: 600; color: #00c2cb; text-shadow: 0px 0px 10px #00c2cb, 0px 0px 20px #00c2cb; margin: 3px; } .content h1::before { content: ""; position: absolute; top: 80%; left: 0; height: 100%; width: 100%; background: #00c2cb; }
此时,你所拥有的只是一个普通的盒子。
为了让它看起来像光的反射,我们需要更多的属性,如 transform
, blur
, 和 opacity
。
.content h1::before { content: ""; position: absolute; top: 80%; left: 0; height: 100%; width: 100%; background: #00c2cb; transform: perspective(10px) rotateX(10deg) scale(1, 0.2); filter: blur(1em); opacity: 0.5; }
perspective()
函数是 Z 轴上的距离,可以产生深度的错觉;它就像你的视点。 rotateX()
函数可以水平旋转元素。最后,scale()
在 x 轴和 y 轴上缩放元素,使其看起来更大或更小。在本例中,我们将在 Y 轴上缩小元素。
下面是反射的截图:
您还可以添加更多功能,如悬停效果。
这是您可以与之互动的 CodePen:
镜子反射
如果没有光线,你就无法看到镜子中的自己。使用 CSS 创建镜面反射有两种方法:使用 box-reflect
属性或伪元素。
box-reflect
属性对浏览器的支持有限。它只能在 Chrome、Edge 和 Opera 上使用 -webkit-
前缀。火狐浏览器不支持。
box-reflect: <position> <offset> <mask>;
在本例中,我们将使用一张图片。
<div> <img src="1.jpg" alt="" /> </div>
然后,应用 box-reflect
属性并指定反射的位置。
.content img { -webkit-box-reflect: below; }
下面是此时您将看到的截图:
它是图像的复制品。然后,你可以在图像和倒影之间添加一个间隙。我们可以使用渐变透明的 linear-gradient
蒙版。
.content img { -webkit-box-reflect: below 5px linear-gradient(transparent 50%, #22232e20); }
下面是结果截图。
下面是 CodePen 演示:
同样,只有在支持 -webkit-
前缀的浏览器上才能看到这种效果,即使在 CodePen 上查看也是如此。
您还可以将此效果应用于文本。这就是使用相同代码所获得的效果:
由于 box-reflect
反映的是 HTML 元素周围的 “box”,因此图像和反射之间有很大的差距。
您可以调整偏移量来减小间隙。
-webkit-box-reflect: below -30px linear-gradient(transparent 20%, #22232e20);
接着是伪元素。使用该方法为文本添加倒影的一种方法是输入伪元素的 content
属性。
.content h1::before { content: "Mirror Reflection"; position: absolute; top: 60%; left: 0; height: 100%; width: 100%; transform: rotate(180deg) scaleX(-1); opacity: 0.1; filter: blur(2px); }
要添加淡出效果,可添加与 :before
元素大小相同的 :after
伪元素,并为其添加渐变 background
,从透明渐变为与父元素背景相同的颜色。
.content h1::after { content: ""; position: absolute; top: 60%; left: 0; height: 100%; width: 100%; background: linear-gradient(transparent, #22232e 80%); }
另外,在使用伪元素为文本添加反射时,也可以使用 data-text
HTML 属性。
<div> <h1 data-text="Mirror Reflection">Mirror Reflection</h1> </div>
然后,您可以使用 CSS 进行样式调整:
.content h1::before { content: attr(data-text); position: absolute; top: 60%; left: 0; height: 100%; width: 100%; transform: rotate(180deg) scaleX(-1); opacity: 0.2; }
这就是如何为文本添加镜像效果。所有现代浏览器都支持伪元素。
下面是 CodePen 演示:
对于图片,您需要使用 background-image
属性,而不是图片本身。
下面是 HTML:
<section id="main"> <div class="image"></div> </section>
然后,您可以在 div
中添加一个 background-image
,其类名为 image
。
.image { background-image: url(/1.jpg); background-size: cover; background-position: center; background-repeat: no-repeat; background-color: red; width: 350px; height: 200px; position: relative; }
然后,添加伪元素,它将具有与主元素相同的大部分属性。transform
属性将旋转和反转反射图像。
.image::before { content: ""; position: absolute; top: 102%; left: 0; width: 350px; height: 200px; background-color: red; background-image: url(/1.jpg); background-size: cover; background-position: center; background-repeat: no-repeat; transform: scaleY(-1); opacity: 0.2; }
最后,添加第二个伪元素,完成反射效果。
.image::after { content: ""; position: absolute; top: 102%; left: 0; width: 350px; height: 200px; background-image: linear-gradient(transparent, #22232e 50%); }
为了避免重复,可以简化 CSS 代码。
.image { background: url(/1.jpg) center / cover no-repeat; width: 350px; height: 200px; position: relative; } .image::before, .image::after { content: ""; position: absolute; top: 102%; left: 0; width: 350px; height: 200px; } .image::before { transform: scaleY(-1); opacity: 0.2; background: url(/1.jpg) center / cover no-repeat; } .image::after { background-image: linear-gradient(transparent, #22232e 50%); }
下面的 CodePen 演示了这种效果:
水面倒影
您将按照与镜面反射几乎相同的步骤使用伪元素来获得这种效果。不同之处在于添加了 feTurbulence
和 feDisplacementMap
这两个 SVG 滤镜基元来创建水波效果。
您将在 HTML 文档的 body
中添加 SVG。SVG 滤镜与 HTML <filter>
元素配合使用,CSS filter
属性将通过 id
引用该元素。
下面是一个 SVG 语法示例:
<svg> <filter id=""> <!--Add filter primitives--> </filter> </svg>
我们从 feTurbulence
过滤器原型开始。
<svg> <filter id="water"> <feTurbulence id="turbulence" type="turbulence" numOctaves="1" result="WAVES" ></feTurbulence> </filter> </svg>
当应用于图像时,会产生噪点效果。下面是它的截图:
该基元包含两个属性: numOctaves
和 baseFrequency
,用于控制失真程度。
接下来,添加 feDisplacementMap
原始元素。这将把一个元素的纹理应用到另一个元素上。在本例中,它将把 feTurblance
创建的变形(以 result
或名称 WAVES
表示)应用到 sourceGraphic
(即伪元素反射)上。
<svg> <filter id="wavy"> <feTurbulence id="turbulence" type="turbulence" numOctaves="1" result="NOISE" ></feTurbulence> <feDisplacementMap in="SourceGraphic" in2="NOISE" scale="50" ></feDisplacementMap> <animate xlink:href="#turbulence" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1" values="0.01 0.02;0.1 0.2;0.01 0.02" repeatCount="indefinite" ></animate> </filter> </svg>
<animate>
元素定义了 SVG 动画的行为。它包含一个链接,指向我们要应用动画的基元的 id
。它还包含了我们要应用动画的属性名称,即 baseFrequency
。接着,设置动画的持续时间和 keyTimes
,其功能类似于 CSS 动画中的 @keyframes
。然后,在每个停止点添加动画属性 values
和迭代。
下面的 CodePen 演示了这种效果:
聚光灯悬停效果
您需要使用 JavaScript onmousemove
事件监听器来创建此效果。
我们将从 HTML 开始,HTML 将是一张带有一些文字的简单卡片。
<section> <div class="content" style="--light: #00c2cb;"> <h1>Spotlight Effect</h1> <h3>Hover on this card to see the magic</h3> </div> </section>
它包含一个 CSS 自定义属性 --light
,即灯光的颜色。
接下来,使用 CSS 创建样式。
section { display: flex; justify-content: center; align-items: center; gap: 50px; flex-wrap: wrap; } .content { position: relative; width: 600px; height: 400px; border-radius: 20px; background: rgba(31,32,39,1); overflow: hidden; display: flex; justify-content: center; align-items: center; flex-direction: column; z-index: 1; } .content h1{ font-size: 3rem; color: #00c2cb; z-index: 3; } .content h3{ font-size: 20px; color: #e0ffff; z-index: 3; }
现在在卡片上创建一个 :before
伪元素。
.content::before{ content: ''; position: absolute; background: radial-gradient(var(--light),transparent,transparent); width: 600px; height: 600px; }
background
将作为聚光灯,它是一个radial-gradient
,使用 HTML 中指定的自定义颜色。
下面是你应该得到的截图:
let content = document.querySelectorAll('.content'); content.forEach(card => { card.onmousemove = function (e) { let x = e.pageX - card.offsetLeft; let y = e.pageY - card.offsetTop; card.style.setProperty('--x', x + 'px'); card.style.setProperty('--y', y + 'px'); }; });
onmousemove
事件监听器会计算鼠标指针相对于元素的 X 和 Y 坐标,并将自定义属性 --x
和 --y
设置为这些坐标。
接下来,将此应用于 :before
伪元素。
.content::before{ content: ''; position: absolute; top: var(--y); left: var(--x); transform: translate(-50%,-50%); background: radial-gradient(var(--light),transparent,transparent); width: 600px; height: 600px; opacity: 0; transition: 0.5s, top 0s, left 0s; } .content:hover::before{ opacity: 1; }
我们还将不透明度设置为 0
,使聚光灯在悬停在卡片上时可见。
此时,您可以决定添加 :after
伪元素。
.content::after{ content: ''; position: absolute; inset: 2px; border-radius: 18px; background-color: rgba(31,32,39,0.7); z-index: 2; }
与 :before
元素相比,该元素的背景略微透明,并且有一个 inset
,因此看起来就像卡片有边框一样。
下面是一个代码段,显示了您可以与之交互的最终结果:
小结
你刚刚学会了用 CSS 创建光效的五种不同方法。首先,我们为两个阴影属性添加了颜色,以创建霓虹灯光。然后,我们使用 :before
和 :after
伪元素以及 box-reflect
CSS 属性,介绍了几种反射类型。最后,我们使用 onmousemove
JavaScript 事件监听器创建了聚光灯效果。
灯光在离线环境下有很多用途,在在线环境下也可以增加网站的视觉吸引力。
评论留言