HTML&CSS:零门槛解锁红绿灯特效

257 阅读4分钟

这段代码创建了三个具有不同灯光效果的开关按钮。当用户点击开关时,可以触发不同的灯光动画。灯光效果通过 CSS 动画实现,包括闪烁和关闭动画。

演示效果

HTML&CSS

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>公众号关注:前端Hardy</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background: #212121;
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100vh;
        }

        .wrap {
            --black: #000000;
            --ch-black: #141414;
            --eer-black: #1b1b1b;
            --night-rider: #2e2e2e;
            --white: #ffffff;
            --af-white: #f3f3f3;
            --ch-white: #e1e1e1;
            font-family: Helvetica, sans-serif;
        }

        .main {
            display: flex;
        }

        .switch {
            display: block;
            position: relative;
            background-color: black;
            width: 70px;
            height: 70px;
            box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px var(--black),
                inset 0 2px 2px -2px var(--white), inset 0 0 2px 5px var(--night-rider),
                inset 0 0 2px 22px var(--black);
            border-radius: 50%;
            padding: 20px;
            margin: 5px;
        }

        .switch input {
            display: none;
        }

        .switch input:checked+.button .light {
            animation: flicker 0.2s infinite 0.3s;
        }

        .switch input:checked+.button .shine {
            opacity: 1;
        }

        .switch input:checked+.button .shadow {
            opacity: 0;
        }

        .switch .button {
            transition: all 0.3s cubic-bezier(1, 0, 1, 1);
            background-color: var(--night-rider);
            width: 55px;
            height: 55px;
            border-radius: 50%;
            position: relative;
            left: -0.1em;
            top: -0.5em;
            cursor: pointer;
        }

        .switch .light {
            opacity: 0;
            animation: light-off 1s;
            position: absolute;
            width: 100%;
            height: 100%;
            background-image: radial-gradient(var(--ch-white),
                    rgb(255, 0, 71) 70%,
                    transparent 72%);
        }

        .switch .dots {
            position: absolute;
            width: 100%;
            height: 100%;
            background-image: radial-gradient(transparent 30%, var(--black) 70%);
            background-size: 8px 8px;
            border-radius: 50%;
        }

        @keyframes flicker {
            0% {
                opacity: 1;
            }

            80% {
                opacity: 0.8;
            }

            100% {
                opacity: 1;
            }
        }

        @keyframes light-off {
            0% {
                opacity: 1;
            }

            80% {
                opacity: 0;
            }
        }

        .switch1 {
            display: block;
            position: relative;
            background-color: var(--black);
            width: 70px;
            height: 70px;
            box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px var(--black),
                inset 0 2px 2px -2px var(--white), inset 0 0 2px 5px var(--night-rider),
                inset 0 0 2px 22px var(--black);
            border-radius: 50%;
            padding: 20px;
            margin: 5px;
        }

        .switch1 input {
            display: none;
        }

        .switch1 input:checked+.button .light {
            animation: flicker 0.2s infinite 0.3s;
        }

        .switch1 input:checked+.button .shine {
            opacity: 1;
        }

        .switch1 input:checked+.button .shadow {
            opacity: 0;
        }

        .switch1 .button {
            transition: all 0.3s cubic-bezier(1, 0, 1, 1);
            background-color: var(--night-rider);
            width: 55px;
            height: 55px;
            border-radius: 50%;
            position: relative;
            left: -0.1em;
            top: -0.5em;
            cursor: pointer;
        }

        .switch1 .light {
            opacity: 0;
            animation: light-off 1s;
            position: absolute;
            width: 100%;
            height: 100%;
            background-image: radial-gradient(var(--ch-white),
                    rgb(255, 255, 0) 70%,
                    transparent 72%);
        }

        .switch1 .dots {
            position: absolute;
            width: 100%;
            height: 100%;
            background-image: radial-gradient(transparent 30%, var(--black) 70%);
            background-size: 10px 10px;
            border-radius: 50%;
        }

        .switch2 {
            display: block;
            position: relative;
            background-color: var(--black);
            width: 70px;
            height: 70px;
            box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.2), 0 0 1px 2px var(--black),
                inset 0 2px 2px -2px var(--white), inset 0 0 2px 5px var(--night-rider),
                inset 0 0 2px 22px var(--black);
            border-radius: 50%;
            padding: 20px;
            margin: 5px;
        }

        .switch2 input {
            display: none;
        }

        .switch2 input:checked+.button .light {
            animation: flicker 0.2s infinite 0.3s;
        }

        .switch2 input:checked+.button .shine {
            opacity: 1;
        }

        .switch2 input:checked+.button .shadow {
            opacity: 0;
        }

        .switch2 .button {
            transition: all 0.3s cubic-bezier(1, 0, 1, 1);
            background-color: var(--night-rider);
            width: 55px;
            height: 55px;
            border-radius: 50%;
            position: relative;
            left: -0.1em;
            top: -0.5em;
            cursor: pointer;
        }

        .switch2 .light {
            opacity: 0;
            animation: light-off 1s;
            position: absolute;
            width: 100%;
            height: 100%;
            background-image: radial-gradient(var(--ch-white),
                    rgb(162, 254, 4) 70%,
                    transparent 72%);
        }

        .switch2 .dots {
            position: absolute;
            width: 100%;
            height: 100%;
            background-image: radial-gradient(transparent 30%, var(--black) 70%);
            background-size: 10px 10px;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <div class="wrap">
        <div class="main">
            <label class="switch">
                <input type="radio" name="value-radio" />
                <div class="button">
                    <div class="light"></div>
                    <div class="dots"></div>
                </div>
            </label>
            <label class="switch1">
                <input type="radio" checked="" name="value-radio" />
                <div class="button">
                    <div class="light"></div>
                    <div class="dots"></div>
                </div>
            </label>
            <label class="switch2">
                <input type="radio" checked="" name="value-radio" />
                <div class="button">
                    <div class="light"></div>
                    <div class="dots"></div>
                </div>
            </label>
        </div>
    </div>

</body>

</html>

HTML 结构

  • wrap:定义了一个包含所有内容的容器,用于应用一些基本样式。
  • main:主容器,用于水平排列开关按钮。
  • switch:定义了一个开关按钮的标签,包含一个隐藏的复选框和显示部分。
  • value-radio:定义了一个单选按钮,用于在三个开关之间进行选择。
  • button:开关的显示部分,包含灯光和点状图案。
  • light:表示灯光效果的 div 元素。
  • dots:表示点状图案的 div 元素。

CSS 样式

  • body:设置页面的外边距、内边距、背景色、显示方式、对齐方式和高度。
  • .wrap:定义了容器的字体样式。
  • .main:定义了主容器的显示方式为 flex,以便水平排列开关按钮。
  • .switch、.switch1、.switch2:定义了开关按钮的基本样式,包括背景色、尺寸、阴影、圆角和内边距。
  • .switch input、.switch1 input、.switch2 input:隐藏了复选框的默认样式。
  • .switch input:checked+.button .light、.switch1 input:checked+.button .light、.switch2 input:checked+.button .light:当复选框被选中时,应用灯光效果的动画。
  • .switch .button、.switch1 .button、.switch2 .button:定义了开关按钮显示部分的样式,包括背景色、尺寸、圆角和位置。
  • .switch .light、.switch1 .light、.switch2 .light:定义了灯光效果的样式,包括透明度、动画和背景渐变。
  • .switch .dots、.switch1 .dots、.switch2 .dots:定义了点状图案的样式,包括背景渐变和尺寸。
  • @keyframes flicker:定义了一个关键帧动画,用于模拟灯光闪烁的效果。
  • @keyframes light-off:定义了一个关键帧动画,用于模拟灯光关闭的效果。