CSS小玩意儿:霓虹灯卡片

一,效果

二,代码

1,搭个框架

主题是一个圆角矩形,其中有垂直、水平居中的文字。

html 复制代码
<!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>
  1. 卡片尺寸设置为固定的200x300像素。
  2. 使用display: flexjustify-contentalign-items使文字元素在弹性盒子中沿水平主轴和垂直主轴上剧中。

效果:

2,实现交互效果

鼠标悬停效果增加交互性,为用户提供视觉反馈。

html 复制代码
<!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>
  1. 为body添加了样式,使卡片在页面中居中。
  2. 给 .card 添加了border-radius来创建圆角。
  3. 设置cursor: pointer,提示用户卡片是可点击的。
  4. 初始文字颜色设置为透明,添加transition指定过度效果。
  5. :hover状态下改变文字颜色,结合过渡效果实现从字体透明到不透明的变化。

效果:

3,添加基本的霓虹边框效果

添加一个标色的边框不太好实现,,但用一个为元素来添加一个被遮住的变色元素确实相对容易的。

html 复制代码
<!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>
  1. 给.card添加了position: relative,为绝对定位的伪元素做准备。
  2. 伪元素 ::before 被用作卡片的装饰性边框。通过 background: linear-gradient(45deg, #5ddcff, #3c67e3, #4e00c2);,这个伪元素创建了一个带有渐变色的背景。
  3. 伪元素用position: absolute; 和四个方向的 top: -2px; left: -2px; right: -2px; bottom: -2px; 设置,让这个伪元素略微超出了卡片的边界,形成了一个围绕卡片的视觉边框效果。
  4. 伪元素设置了 z-index: -1;,使其背景在主卡片内容(文字)下方显示,从而增强了卡片的层次感和立体感。

伪元素的作用总结:

  • 视觉效果: 通过伪元素实现了卡片周围的动态渐变边框和发光效果,增强了视觉吸引力。
  • 分离内容与装饰: 使用伪元素可以将装饰性元素与实际内容分离,避免在 HTML 中添加冗余的结构元素。
  • 简化代码: 不需要在 HTML 中额外添加元素就能实现复杂的效果,使代码更简洁、更易维护。

效果:

4,添加旋转动画

既然卡片元素后面是一个伪元素,那么就可以通过转动这个伪元素来实现灯光流转。

html 复制代码
<!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>
  1. 我们定义了一个新的CSS属性 --rotate,使用 @property 规则。这允许我们在动画中平滑地过渡角度值。
  2. .card::before 伪元素中,我们将 linear-gradient 的第一个参数改为 var(--rotate)。这意味着渐变的角度现在由 --rotate 变量控制。
  3. 我们为 .card::before 添加了 animation: spin 2.5s linear infinite;。这开启了一个名为 "spin" 的动画,持续2.5秒,线性变化,无限循环。
  4. 定义了 @keyframes spin,它在动画过程中将 --rotate 从 0 度变化到 360 度。

@property --rotate 是一种用于定义自定义 CSS 属性(也称为 CSS 变量)的声明。这是一个较新的 CSS 特性,称为 CSS Properties and Values API,它允许你为自定义属性定义类型、安全值、继承行为和初始值等信息。

这里详细解释一下:

css 复制代码
@property --rotate {
    syntax: "<angle>";
    initial-value: 132deg;
    inherits: false;
}


syntax:
- 定义了这个自定义属性所接受的值的类型。这里的 <angle> 指定 --rotate 变量应该接受一个角度值(如 45deg、90deg 等)。
- 这种类型约束可以防止错误的值被赋给该变量。

initial-value:
- 定义了 --rotate 变量的初始值。如果该变量在某个元素中没有被设置,那么它将默认使用这个初始值。
- 在这个例子中,--rotate 的初始值是 132deg。

inherits:
- 决定这个自定义属性是否应该从父元素继承。默认情况下,CSS 自定义属性是继承的。
- 这里设置为 false,意味着子元素不会自动继承这个变量的值。
css 复制代码
@keyframes spin {
    0% {
        --rotate: 0deg;
    }
    100% {
        --rotate: 360deg;
    }
}

定义动画: @keyframes spin 定义了名为 spin 的动画,描述了从动画开始 (0%) 到动画结束 (100%) 的变化过程。

关键帧的定义:
- 0% 表示动画的起点。
- 100% 表示动画的终点。
- 在这个动画中,--rotate 变量从 0deg 增加到 360deg,也就是说,整个动画会让线性渐变旋转一整圈。

5,添加发光效果

通过添加一个发光效果来进一步增强霓虹灯的视觉冲击力。

html 复制代码
<!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>
  1. 我们添加了一个新的伪元素 .card::after ,它与 .card::before 具有相同的基本样式。
  2. .card::after 中,我们添加了 filter: blur(50px);,将模糊或颜色偏移等图形效果应用于元素,这创建了一个模糊效果,模拟霓虹灯的发光。
  3. 两个伪元素都使用相同的动画,创造出同步旋转的效果。

伪元素 ::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 的内容在元素内容后显示。

三,继续优化

html 复制代码
<!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>
  1. 添加了 <meta name="viewport"> 标签,确保页面在移动设备上正确显示。

  2. 使用 CSS 变量(:root)定义卡片尺寸,使其相对于视口高度。这样可以在不同大小的屏幕上保持合适的比例。

  3. 将固定的像素值替换为相对单位(如 vh 和 %)。

  4. 添加了媒体查询,在小屏幕设备上调整卡片大小。

    css 复制代码
    @media screen and (max-width: 600px) {
        :root {
            --card-height: 50vh;
        }
    }
  5. 优化了悬停效果,使动画在悬停时停止,减少不必要的 CPU 使用。

    css 复制代码
    .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 使用,但它确实减少了需要渲染的内容,可能会略微提高性能。

效果:

相关推荐
wjs04064 小时前
用css实现一个类似于elementUI中Loading组件有缺口的加载圆环
前端·css·elementui·css实现loading圆环
刻刻帝的海角1 天前
CSS 颜色
前端·css
python算法(魔法师版)2 天前
html,css,js的粒子效果
javascript·css·html
LBJ辉2 天前
1. 小众但非常实用的 CSS 属性
前端·css
学不完了是吧2 天前
html、js、css实现爱心效果
前端·css·css3
Zaly.2 天前
【前端】CSS实战之音乐播放器
前端·css
孤客网络科技工作室2 天前
不使用 JS 纯 CSS 获取屏幕宽高
开发语言·javascript·css
m0_748247552 天前
【HTML+CSS】使用HTML与后端技术连接数据库
css·数据库·html
肖老师xy3 天前
css动画水球图
前端·css
LBJ辉3 天前
2. CSS 中的单位
前端·css