一,效果
二,代码
1,搭个框架
主题是一个圆角矩形,其中有垂直、水平居中的文字。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>霓虹灯卡片 - 步骤1</title><style>.card {width: 200px;height: 300px;background-color: #191c29;display: flex;justify-content: center;align-items: center;color: white;font-family: sans-serif;}</style>
</head>
<body><div class="card">Magic Card</div>
</body>
</html>
- 卡片尺寸设置为固定的200x300像素。
- 使用
display: flex
和justify-content
、align-items
使文字元素在弹性盒子中沿水平主轴和垂直主轴上剧中。
效果:
2,实现交互效果
鼠标悬停效果增加交互性,为用户提供视觉反馈。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>霓虹灯卡片 - 步骤2</title><style>body {display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;background-color: #212534;}.card {width: 200px;height: 300px;background-color: #191c29;display: flex;justify-content: center;align-items: center;color: rgba(88, 199, 250, 0);font-family: cursive;border-radius: 6px;cursor: pointer;transition: color 0.5s;}.card:hover {color: rgba(88, 199, 250, 1);}</style>
</head>
<body><div class="card">Magic Card</div>
</body>
</html>
- 为body添加了样式,使卡片在页面中居中。
- 给 .card 添加了
border-radius
来创建圆角。 - 设置
cursor: pointer
,提示用户卡片是可点击的。 - 初始文字颜色设置为透明,添加
transition
指定过度效果。 - 在
:hover
状态下改变文字颜色,结合过渡效果实现从字体透明到不透明的变化。
效果:
3,添加基本的霓虹边框效果
添加一个标色的边框不太好实现,,但用一个为元素来添加一个被遮住的变色元素确实相对容易的。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>霓虹灯卡片 - 步骤3</title><style>body {display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;background-color: #212534;}.card {width: 200px;height: 300px;background-color: #191c29;display: flex;justify-content: center;align-items: center;color: rgba(88, 199, 250, 0);font-family: cursive;border-radius: 6px;cursor: pointer;transition: color 0.5s;position: relative;}.card:hover {color: rgba(88, 199, 250, 1);}.card::before {content: "";position: absolute;top: -2px;left: -2px;right: -2px;bottom: -2px;background: linear-gradient(45deg, #5ddcff, #3c67e3, #4e00c2);z-index: -1;border-radius: 8px;}</style>
</head>
<body><div class="card">Magic Card</div>
</body>
</html>
- 给.card添加了
position: relative
,为绝对定位的伪元素做准备。 - 伪元素
::before
被用作卡片的装饰性边框。通过background: linear-gradient(45deg, #5ddcff, #3c67e3, #4e00c2);
,这个伪元素创建了一个带有渐变色的背景。 - 伪元素用
position: absolute;
和四个方向的top: -2px; left: -2px; right: -2px; bottom: -2px;
设置,让这个伪元素略微超出了卡片的边界,形成了一个围绕卡片的视觉边框效果。 - 伪元素设置了
z-index: -1;
,使其背景在主卡片内容(文字)下方显示,从而增强了卡片的层次感和立体感。
伪元素的作用总结:
- 视觉效果: 通过伪元素实现了卡片周围的动态渐变边框和发光效果,增强了视觉吸引力。
- 分离内容与装饰: 使用伪元素可以将装饰性元素与实际内容分离,避免在 HTML 中添加冗余的结构元素。
- 简化代码: 不需要在 HTML 中额外添加元素就能实现复杂的效果,使代码更简洁、更易维护。
效果:
4,添加旋转动画
既然卡片元素后面是一个伪元素,那么就可以通过转动这个伪元素来实现灯光流转。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>霓虹灯卡片 - 步骤4</title><style>@property --rotate {syntax: "<angle>";initial-value: 132deg;inherits: false;}body {display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;background-color: #212534;}.card {width: 200px;height: 300px;background-color: #191c29;display: flex;justify-content: center;align-items: center;color: rgba(88, 199, 250, 0);font-family: cursive;border-radius: 6px;cursor: pointer;transition: color 0.5s;position: relative;}.card:hover {color: rgba(88, 199, 250, 1);}.card::before {content: "";position: absolute;top: -2px;left: -2px;right: -2px;bottom: -2px;background: linear-gradient(var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2);z-index: -1;border-radius: 8px;animation: spin 2.5s linear infinite;}@keyframes spin {0% {--rotate: 0deg;}100% {--rotate: 360deg;}}</style>
</head>
<body>
<div class="card">Magic Card</div>
</body>
</html>
- 我们定义了一个新的CSS属性
--rotate
,使用@property
规则。这允许我们在动画中平滑地过渡角度值。 - 在 .card::before 伪元素中,我们将
linear-gradient
的第一个参数改为var(--rotate)
。这意味着渐变的角度现在由--rotate
变量控制。 - 我们为 .card::before 添加了
animation: spin 2.5s linear infinite;
。这开启了一个名为 “spin” 的动画,持续2.5秒,线性变化,无限循环。 - 定义了
@keyframes spin
,它在动画过程中将--rotate
从 0 度变化到 360 度。
@property --rotate
是一种用于定义自定义 CSS 属性(也称为 CSS 变量)的声明。这是一个较新的 CSS 特性,称为 CSS Properties and Values API,它允许你为自定义属性定义类型、安全值、继承行为和初始值等信息。
这里详细解释一下:
@property --rotate {syntax: "<angle>";initial-value: 132deg;inherits: false;
}syntax:
- 定义了这个自定义属性所接受的值的类型。这里的 <angle> 指定 --rotate 变量应该接受一个角度值(如 45deg、90deg 等)。
- 这种类型约束可以防止错误的值被赋给该变量。initial-value:
- 定义了 --rotate 变量的初始值。如果该变量在某个元素中没有被设置,那么它将默认使用这个初始值。
- 在这个例子中,--rotate 的初始值是 132deg。inherits:
- 决定这个自定义属性是否应该从父元素继承。默认情况下,CSS 自定义属性是继承的。
- 这里设置为 false,意味着子元素不会自动继承这个变量的值。
@keyframes spin {0% {--rotate: 0deg;}100% {--rotate: 360deg;}
}定义动画: @keyframes spin 定义了名为 spin 的动画,描述了从动画开始 (0%) 到动画结束 (100%) 的变化过程。关键帧的定义:
- 0% 表示动画的起点。
- 100% 表示动画的终点。
- 在这个动画中,--rotate 变量从 0deg 增加到 360deg,也就是说,整个动画会让线性渐变旋转一整圈。
5,添加发光效果
通过添加一个发光效果来进一步增强霓虹灯的视觉冲击力。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>霓虹灯卡片 - 步骤5</title><style>@property --rotate {syntax: "<angle>";initial-value: 132deg;inherits: false;}body {display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;background-color: #212534;}.card {width: 200px;height: 300px;background-color: #191c29;display: flex;justify-content: center;align-items: center;color: rgba(88, 199, 250, 0);font-family: cursive;border-radius: 6px;cursor: pointer;transition: color 0.5s;position: relative;}.card:hover {color: rgba(88, 199, 250, 1);}.card::before,.card::after {content: "";position: absolute;top: -2px;left: -2px;right: -2px;bottom: -2px;background: linear-gradient(var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2);z-index: -1;border-radius: 8px;animation: spin 2.5s linear infinite;}.card::after {filter: blur(50px);}@keyframes spin {0% {--rotate: 0deg;}100% {--rotate: 360deg;}}</style>
</head>
<body>
<div class="card">Magic Card</div>
</body>
</html>
- 我们添加了一个新的伪元素 .card::after,它与 .card::before 具有相同的基本样式。
- 在 .card::after 中,我们添加了
filter: blur(50px);
,将模糊或颜色偏移等图形效果应用于元素,这创建了一个模糊效果,模拟霓虹灯的发光。 - 两个伪元素都使用相同的动画,创造出同步旋转的效果。
伪元素 ::before
和 ::after
都是用于在 HTML 元素内容之前或之后插入内容的 CSS 工具。它们在功能和用法上非常相似,但有一些关键的区别。
1. 插入内容的位置
::before:- ::before 用于在元素内容的前面插入内容。- 插入的内容位于元素内容的最前面,也就是元素的实际内容之前。
::after:- ::after 用于在元素内容的后面插入内容。- 插入的内容位于元素内容的最后面,也就是元素的实际内容之后。2. 使用场景
::before:- 通常用于在元素之前添加装饰性内容、图标、引号等。例如,可以用来添加项目符号、引导符号等。- 例如,给一个段落添加一个引号:p::before {content: "“";}
::after:- 常用于在元素后添加内容,或者与 ::before 一起配合创建更复杂的效果,如在元素前后添加装饰性线条、边框等。- 例如,给一个段落添加一个引号结束符号:p::after {content: "”";}3. 显示优先级
- 层叠顺序:- 通常,::before 和 ::after 伪元素的层叠顺序由其定义的位置决定。- ::before 在 ::after 之前显示。如果 ::before 和 ::after 的内容有重叠,::before 的内容会在 ::after 的内容下方显示。4. 典型用法示例:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Before and After Example</title><style>.box {position: relative;padding: 20px;background-color: #f0f0f0;border: 2px solid #000;width: 200px;text-align: center;}.box::before {content: "Before: ";color: red;}.box::after {content: " :After";color: blue;}</style>
</head>
<body><div class="box">Content</div>
</body>
</html>
- 效果:- 在 Content 前面会显示红色的文本 Before: ,在 Content 后面会显示蓝色的文本 :After。5. 共同点
- 内容插入: ::before 和 ::after 都可以通过 content 属性插入文本、图像或其他内容。
- 样式控制: 两者都可以像普通元素一样应用样式,例如设置颜色、背景、边框等。
- 定位: 通常,它们和原始元素一起使用 position: relative;,而 ::before 和 ::after 通常设置为 position: absolute; 来进行精确定位。总结:
- ::before 用于在元素内容的前面插入内容。
- ::after 用于在元素内容的后面插入内容。
- 它们通常配合使用来在元素的前后插入装饰性或功能性内容,但顺序不同:::before 的内容在元素内容前显示,::after 的内容在元素内容后显示。
三,继续优化
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>霓虹灯卡片 - 最终版</title><style>@property --rotate {syntax: "<angle>";initial-value: 132deg;inherits: false;}:root {--card-height: 65vh;--card-width: calc(var(--card-height) / 1.5);}body {min-height: 100vh;background: #212534;display: flex;align-items: center;flex-direction: column;padding-top: 2rem;padding-bottom: 2rem;box-sizing: border-box;}.card {background: #191c29;width: var(--card-width);height: var(--card-height);padding: 3px;position: relative;border-radius: 6px;justify-content: center;align-items: center;text-align: center;display: flex;font-size: 1.5em;color: rgb(88 199 250 / 0%);cursor: pointer;font-family: cursive;}.card:hover {color: rgb(88 199 250 / 100%);transition: color 1s;}.card:hover:before, .card:hover:after {animation: none;opacity: 0;}.card::before {content: "";width: 104%;height: 102%;border-radius: 8px;background-image: linear-gradient(var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2);position: absolute;z-index: -1;top: -1%;left: -2%;animation: spin 2.5s linear infinite;}.card::after {position: absolute;content: "";top: calc(var(--card-height) / 6);left: 0;right: 0;z-index: -1;height: 100%;width: 100%;margin: 0 auto;transform: scale(0.8);filter: blur(calc(var(--card-height) / 6));background-image: linear-gradient(var(--rotate), #5ddcff, #3c67e3 43%, #4e00c2);opacity: 1;transition: opacity .5s;animation: spin 2.5s linear infinite;}@keyframes spin {0% {--rotate: 0deg;}100% {--rotate: 360deg;}}@media screen and (max-width: 600px) {:root {--card-height: 50vh;}}</style>
</head>
<body>
<div class="card">Magic Card</div>
</body>
</html>
-
添加了
<meta name="viewport">
标签,确保页面在移动设备上正确显示。 -
使用 CSS 变量(
:root
)定义卡片尺寸,使其相对于视口高度。这样可以在不同大小的屏幕上保持合适的比例。 -
将固定的像素值替换为相对单位(如 vh 和 %)。
-
添加了媒体查询,在小屏幕设备上调整卡片大小。
@media screen and (max-width: 600px) {:root {--card-height: 50vh;} }
-
优化了悬停效果,使动画在悬停时停止,减少不必要的 CPU 使用。
.card:hover:before, .card:hover:after {animation: none;opacity: 0; }1,animation: none; - 当鼠标悬停在卡片上时,这行代码会停止伪元素(:before 和 :after)的动画。 - 原本这些伪元素有一个持续运行的旋转动画(spin 2.5s linear infinite)。 - 停止动画可以减少 CPU 的使用,因为浏览器不需要继续计算和渲染动画帧。2,opacity: 0; - 这行代码在鼠标悬停时使伪元素变为完全透明。 - 虽然这不直接关联到 CPU 使用,但它确实减少了需要渲染的内容,可能会略微提高性能。
效果: