CSS小玩意儿:霓虹灯卡片

一,效果

在这里插入图片描述

二,代码

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>
  1. 卡片尺寸设置为固定的200x300像素。
  2. 使用display: flexjustify-contentalign-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>
  1. 为body添加了样式,使卡片在页面中居中。
  2. 给 .card 添加了border-radius来创建圆角。
  3. 设置cursor: pointer,提示用户卡片是可点击的。
  4. 初始文字颜色设置为透明,添加transition指定过度效果。
  5. :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>
  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,添加旋转动画

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

<!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,它允许你为自定义属性定义类型、安全值、继承行为和初始值等信息。
这里详细解释一下:

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

三,继续优化

<!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. 添加了媒体查询,在小屏幕设备上调整卡片大小。

    @media screen and (max-width: 600px) {
        :root {
            --card-height: 50vh;
        }
    }
    
  5. 优化了悬停效果,使动画在悬停时停止,减少不必要的 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 使用,但它确实减少了需要渲染的内容,可能会略微提高性能。
    

效果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值