多种CSS技巧实现霓虹灯和灯光效果

多种CSS技巧实现霓虹灯和灯光效果

从太阳的自然光到我们家中的人造光,离线世界中的光线无处不在。光线会影响我们的视觉能力,也可以用来创造美感。您可以使用 CSS 创建光效,从而提高网站的视觉吸引力。虽然网页没有光源,但我们可以利用 CSS 的一些属性和元素来创建模仿光线的视觉效果。本文将向你展示用 CSS 创建光效的五种方法。

霓虹灯或荧光灯

在现实世界中,霓虹灯是通过电流穿过气体而产生的。霓虹灯的亮度和色彩取决于气体的种类。因此,霓虹灯常用于装饰展示。

您可以使用 CSS 为阴影添加颜色,从而创建这种效果。您可以使用两个属性来创建阴影,即 box-shadowtext-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;
}

下面是一张截图,显示了它的外观:

CSS霓虹灯或荧光灯效果图

box-shadow 和 text-shadow 的样式类似。不同的是,文字阴影没有 spread

box-shadow 和 text-shadow 的样式类似

您可以添加多个阴影层并使用不同的颜色来创建这种效果。

下面是 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;
}

此时,你所拥有的只是一个普通的盒子。

普通的盒子效果

为了让它看起来像光的反射,我们需要更多的属性,如 transformblur, 和 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”,因此图像和反射之间有很大的差距。

 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 演示了这种效果:

水面倒影

您将按照与镜面反射几乎相同的步骤使用伪元素来获得这种效果。不同之处在于添加了 feTurbulencefeDisplacementMap 这两个 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>

当应用于图像时,会产生噪点效果。下面是它的截图:

产生噪点效果

该基元包含两个属性: numOctavesbaseFrequency ,用于控制失真程度。

接下来,添加 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 事件监听器创建了聚光灯效果。

灯光在离线环境下有很多用途,在在线环境下也可以增加网站的视觉吸引力。

评论留言