HTML&CSS:有趣的小铃铛

这个 HTML 文件实现了一个带有 3D 效果和动画的"小铃铛"页面,用户可以通过点击铃铛来触发动画效果。


大家复制代码时,可能会因格式转换出现错乱,导致样式失效。建议先少量复制代码进行测试,若未能解决问题,私信回复源码两字,我会发送完整的压缩包给你。

演示效果

HTML&CSS

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>
        * {
            box-sizing: border-box;
        }

        html,
        body {
            height: 100%;
            overflow: hidden;
        }

        body {
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
            justify-content: center;
            align-items: center;
            margin: 0;
            background: #000;

            font-size: calc(var(--_size) * 0.01);
            --_size: min(min(600px, 50vh), 50vw);
            --base-clr: #b7b5b4;
            --degofrot: 0.8;
        }

        .bell-container {
            width: 80em;
            height: 80em;
            opacity: 1;
            cursor: pointer;

            transform-origin: 50% -50vh;
            animation: 5s ease-in-out infinite bell;
        }

        @keyframes bell {
            0% {
                rotate: calc(1deg * var(--degofrot));
            }

            50% {
                rotate: calc(-1deg * var(--degofrot));
            }

            100% {
                rotate: calc(1deg * var(--degofrot));
            }
        }

        * {
            transition: filter 0.4s ease-in-out, box-shadow 0.4s ease-in-out,
                opacity 0.4s ease-in-out, color 0.4s ease-in-out, background 0.4s ease-in-out,
                text-shadow 0.4s ease-in-out;

            &::before,
            &::after {
                transition: filter 0.4s ease-in-out, box-shadow 0.4s ease-in-out,
                    opacity 0.4s ease-in-out, color 0.4s ease-in-out, background 0.4s ease-in-out,
                    text-shadow 0.4s ease-in-out;
            }
        }

        .bell-container,
        .bell-container * {
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            margin: auto;
        }

        .rope {
            height: 50vh;
            width: 2em;
            translate: 0 -52%;
            background: linear-gradient(90deg, #2d54744d 0%, #000b 30%, transparent 100%),
                repeating-linear-gradient(-70deg, #252525, #888 2%, #3a3a3a 3%);
        }

        .bell-top {
            width: 14%;
            height: 14%;
            border-radius: 50%;
            translate: 0 -28em;
            background: var(--base-clr);
            box-shadow: inset -1em -0.5em 2em 0.5em #fff, inset 1em -1em 2em 3em #000,
                0 -0.1em 0.4em 0.3em #c6eaffa8;
        }

        .bell-base {
            width: 50%;
            height: 50%;
            border-radius: 50%;
            translate: 0 -24%;
            background: var(--base-clr);
            box-shadow: 0 -0.1em 0.4em 0.2em #c6eaffa8;
        }

        .bell-base:before {
            content: "";
            background-image: radial-gradient(circle at -80% -12%,
                    transparent 50em,
                    var(--base-clr) 50em);
            position: absolute;
            translate: -18em 20em;
            width: 100%;
            height: 80%;
        }

        .bell-base:after {
            content: "";
            background-image: radial-gradient(circle at -80% -12%,
                    transparent 50.1em,
                    #cacaca 50.3em,
                    var(--base-clr) 50.5em);
            position: absolute;
            translate: 18em 20em;
            width: 100%;
            height: 80%;
            transform: rotateY(180deg);
        }

        .bell-base:nth-child(2) {
            filter: brightness(3) blur(1em);
            scale: 0.74 0.84;
            translate: 0em -11em;
        }

        .shadow-l1 {
            width: 30em;
            height: 42em;
            border-radius: 50%;
            rotate: 12deg;
            translate: -3em -6em;
            filter: blur(2em);
            background: #797a80;
        }

        .shadow-l2 {
            width: 130%;
            height: 90%;
            filter: blur(5em);
            translate: -6em 9em;
        }

        .shadow-l2::before {
            display: block;
            content: "";
            width: 68%;
            height: 64%;
            border-radius: 50%;
            rotate: -54deg;
            translate: -8em 2em;
            scale: 1;
            background: red;
            background: #000000;
        }

        .glow {
            width: 100%;
            height: 100%;
            filter: brightness(2) blur(2em);
        }

        .glow::before {
            clip-path: polygon(9% 83%,
                    12% 79%,
                    15% 74%,
                    18% 68%,
                    20% 62%,
                    22% 56%,
                    23% 50%,
                    24% 43%,
                    25% 38%,
                    25% 34%,
                    26% 29%,
                    26% 26%,
                    27% 22%,
                    29% 19%,
                    30% 15%,
                    32% 13%,
                    34% 10%,
                    37% 7%,
                    41% 5%,
                    44% 4%,
                    47% 3%,
                    51% 3%,
                    55% 3%,
                    58% 5%,
                    62% 6%,
                    73% 29%,
                    72% 25%,
                    70% 20%,
                    67% 16%,
                    63% 12%,
                    60% 9%,
                    58% 8%,
                    55% 7%,
                    52% 6%,
                    48% 6%,
                    44% 8%,
                    41% 9%,
                    37% 12%,
                    36% 14%,
                    33% 16%,
                    31% 20%,
                    30% 23%,
                    29% 26%,
                    28% 31%,
                    27% 36%,
                    27% 39%,
                    26% 44%,
                    26% 48%,
                    26% 52%,
                    25% 56%,
                    23% 61%,
                    22% 65%,
                    21% 69%,
                    19% 72%,
                    17% 75%,
                    15% 78%,
                    13% 81%);
            width: 100%;
            height: 80%;
            translate: 0 6em;
            scale: 0.94 0.94;
            background: #fff3;
            display: block;
            content: "";
        }

        .glow2 {
            width: 100%;
            height: 100%;
            filter: brightness(1) blur(0.3em);
            opacity: 0.1;
        }

        .glow2::before {
            clip-path: polygon(9.21% 83%,
                    12.28% 79%,
                    15.35% 74%,
                    18.41% 68%,
                    20.46% 62%,
                    22.51% 56%,
                    23.53% 50%,
                    24.55% 43%,
                    25.58% 34%,
                    26.6% 29%,
                    27.62% 22%,
                    29.16% 18.5%,
                    30.95% 15.75%,
                    32.74% 13%,
                    34.78% 10%,
                    37.85% 7%,
                    41.94% 5%,
                    45.01% 4%,
                    48.08% 3%,
                    52.17% 3%,
                    56.27% 3%,
                    64.01% 6.36%,
                    55.75% 4.5%,
                    47.83% 4.75%,
                    42.84% 5.88%,
                    39.51% 7.88%,
                    36.45% 10.38%,
                    33.38% 14.88%,
                    30.69% 19%,
                    29.67% 22.5%,
                    28.8% 26.72%,
                    28.21% 31.36%,
                    26.92% 38.44%,
                    26.57% 43.67%,
                    25.51% 48.34%,
                    25% 54.34%,
                    23.4% 60.69%,
                    21.23% 65.38%,
                    18.41% 71.5%,
                    16.88% 74.75%,
                    12.28% 80.5%);
            width: 100%;
            height: 84%;
            translate: -1em 8.4em;
            scale: 1;
            background: #fff3;
            display: block;
            content: "";
        }

        .left-glow {
            --lgc: #5d819666;
            width: 50%;
            height: 50%;
            border-radius: 50%;
            translate: 0 -24%;
            background: transparent;
            box-shadow: inset 1em 0em 1em 0.2em var(--lgc);
            clip-path: polygon(0 0, 100% 0, 100% 50%, 0 50%);
        }

        .left-glow2 {
            --lgc2: #5d819666;
            width: 49%;
            height: 50%;
            background-image: radial-gradient(circle at -80% -12%,
                    transparent 50em,
                    var(--lgc2) 50.3em,
                    transparent 52em);
            position: absolute;
            translate: -19em 10.35em;
            clip-path: polygon(0 0, 100% 0, 100% 78%, 0 78%);
        }

        .r-glow {
            --lgc: #fffaf680;
            width: 50%;
            height: 50%;
            border-radius: 50%;
            translate: 0 -24%;
            background: transparent;
            box-shadow: inset 1em 0em 1em 0.2em var(--lgc);
            clip-path: polygon(0 0, 100% 0, 100% 50%, 0 50%);
            transform: rotateY(180deg);
        }

        .r-glow2 {
            --lgc2: #fffaf680;
            width: 49%;
            height: 50%;
            background-image: radial-gradient(circle at -80% -12%,
                    transparent 50em,
                    var(--lgc2) 50.3em,
                    transparent 52em);
            position: absolute;
            translate: 18.2em 10.35em;
            clip-path: polygon(0 0, 100% 0, 100% 78%, 0 78%);
            transform: rotateY(180deg) rotateZ(-2deg);
        }

        .mid-ring.small {
            translate: 0.04em -8em;
            scale: 0.8 0.5;
        }

        .mid-ring {
            width: 64%;
            height: 10%;
            border-radius: 50%;
            translate: -0.1em 10em;
            box-shadow: inset -0.3em 1.3em 0.4em -1em #fff5,
                -0.2em -1.2em 0.4em -0.4em #505050, -0.1em -1.8em 0.4em -0.4em #fff5,
                0 -2.5em 0.4em -1em #000000;
            mix-blend-mode: hard-light;
            filter: brightness(0.8);
        }

        .mid-ring::before,
        .mid-ring::after {
            content: "";
            display: block;
            background: #000;
            width: 2em;
            height: 2em;
            top: 10%;
            border-radius: 50%;
            position: absolute;
        }

        .mid-ring::after {
            right: -2%;
        }

        .mid-ring::before {
            left: -2%;
        }

        .bell-buff-t {
            background: #fff2;
            width: 72%;
            height: 12%;
            border-radius: 50%;
            translate: 0 16em;
            filter: blur(1em);
        }

        .bell-buff {
            background: linear-gradient(90deg, black 40%, var(--base-clr) 90%);
            width: 88%;
            height: 20%;
            border-radius: 50% 50% 50% 50% / 50% 50% 30% 30%;
            translate: 0 20em;
            box-shadow: inset 1em 0 2em -1em #5d819666, inset -1em 0 2em -1em #fff;
        }

        .bell-btm {
            width: 88%;
            height: 18%;
            border-radius: 50%;
            translate: 0 23em;
            background: linear-gradient(90deg, black 40%, var(--base-clr) 90%);
        }

        .bell-btm2 {
            width: 74%;
            height: 12%;
            border-radius: 50%;
            translate: 0 24em;
            background: #fffff6;
            box-shadow: 0 0 1em 0.6em #ffe9d4, -0.8em 0.2em 2em 1em #cca37f,
                -5.4em -0.6em 3em -1em #ce6e1abb, 6em -0.6em 3em -1em #ce6e1abb,
                inset 0em 30.3em 0.3em -30em #c7962d, inset 0 -2em 2em -2em #ffe9d4,
                inset 0em -1em 2em 1em #ce6e1a66;
            filter: brightness(1);
        }

        .off .bell-btm2 {
            filter: brightness(0.02);
        }

        .bell-ring-container {
            width: 74%;
            height: 24%;
            border-radius: 50% 50% 50% 50% / 25% 25% 0% 0%;
            translate: 0 29.2em;
            overflow: hidden;
        }

        .bell-ring {
            width: 12em;
            height: 12em;
            background: #fff;
            border-radius: 50%;
            translate: 0 -6em;
            box-shadow: 0 0.8em 1em -0.3em #f8e1d0, inset 0 -6em 4em -4em #e3b695,
                inset 0 1em 3em 1em #fff4, inset 0 2em 3em 1em #fff,
                inset 0 100em 0 100em #2c2c2c;
        }

        .off .bell-ring {
            background: #000;
            box-shadow: 0 0.8em 1em -0.3em #f8e1d000, inset 0 -6em 4em -4em #e3b69500,
                inset 0 1em 3em 1em #fff0, inset 0 -2em 3em 1em #fff2,
                inset 0 100em 0 100em #000;
        }

        .bell-rays {
            mix-blend-mode: soft-light;
            box-shadow: inset 0 -21em 4em -20em #000;
            width: 100%;
            height: 140%;
            translate: 0 -4em;
            border-radius: 50%;
        }

        .bell-rays::before {
            content: "";
            display: block;
            width: 100em;
            height: 100em;
            transform-origin: 50% 50%;
            position: absolute;
            left: -21em;
            top: -77em;
            border-radius: 100%;
            filter: blur(0.6em);
            background: repeating-conic-gradient(at 50% 50%,
                    #fff2 0%,
                    transparent 0.6%,
                    #fff2 0.8%);
            animation: radiate 1s linear infinite;
        }

        .off .bell-rays {
            opacity: 0;
        }

        @keyframes radiate {
            0% {
                rotate: 0deg;
            }

            100% {
                rotate: 6deg;
            }
        }

        .volumetric {
            width: 98%;
            height: 224%;
            translate: 0 124em;
            opacity: 0.2;

            .vl {
                width: 100%;
                height: 100%;
                transform-origin: 50% 20em;
                rotate: 22deg;
                box-shadow: inset 40em 0 20em -20em #fff1;
            }

            .vr {
                width: 100%;
                height: 100%;
                transform-origin: 50% 20em;
                rotate: -22deg;
                box-shadow: inset -40em 0 20em -20em #fff1;
            }
        }

        .off .volumetric {
            opacity: 0;
        }

        .grain {
            z-index: 10;
            position: absolute;
            pointer-events: none;
            width: 100%;
            height: 100%;
            top: 0;
            bottom: 0;
            margin: auto;
            background: radial-gradient(circle at 50% 50%, #000, #0000),
                url("data:image/svg+xml,%3Csvg viewBox='0 0 600 600' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='2' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
            filter: contrast(100%) brightness(200%) grayscale(1) opacity(0.168);
            mix-blend-mode: screen;
        }

        .button {
            position: relative;
            font-size: 6em;
            font-family: monospace;
            background: #000;
            top: 8em;
            width: fit-content;
            height: fit-content;
            color: #fff;
            cursor: pointer;
            padding: 0.4em 1.2em;
            border-radius: 0.4em;
            text-shadow: 0 -1px 3px #fff0;
            box-shadow: inset 0 0.04em 0.06em 0 #fff, inset 0 1em 1em 0 #fff5,
                inset 0 0.2em 0.2em 0 #e3b695;
            animation: 5s ease-in-out infinite lumenbtn;

            &:hover {
                color: #fff;
                text-shadow: 0 -1px 3px #fff;
                transition: all 0.16s ease-in-out;
            }

            &::before,
            &::after {
                content: "";
                display: block;
                width: 100%;
                height: 54%;
                position: absolute;
                top: 6em;
                left: 0;
                right: 0;
            }

            &::before {
                background: #e3b695;
                scale: 2;
                z-index: -2;
                filter: blur(12px);
                border-radius: 100%;
                animation: 5s ease-in-out infinite lumen;
            }

            &::after {
                background: #000c;
                z-index: -1;
                filter: blur(0.3em);
                border-radius: 30%;
            }
        }

        @keyframes lumenbtn {
            0% {
                box-shadow: inset 0 0.04em 0.06em 0 #fff,
                    inset calc(-0.2em * var(--degofrot)) 1em 1em 0 #fff5,
                    inset calc(-0.2em * var(--degofrot)) 0.2em 0.4em 0 #e3b695;
            }

            50% {
                box-shadow: inset 0 0.04em 0.06em 0 #fff,
                    inset calc(0.2em * var(--degofrot)) 1em 1em 0 #fff5,
                    inset calc(0.2em * var(--degofrot)) 0.2em 0.4em 0 #e3b695;
            }

            100% {
                box-shadow: inset 0 0.04em 0.06em 0 #fff,
                    inset calc(-0.2em * var(--degofrot)) 1em 1em 0 #fff5,
                    inset calc(-0.2em * var(--degofrot)) 0.2em 0.4em 0 #e3b695;
            }
        }

        @keyframes lumen {
            0% {
                translate: calc(-0.8em * var(--degofrot));
            }

            50% {
                translate: calc(0.8em * var(--degofrot));
            }

            100% {
                translate: calc(-0.8em * var(--degofrot));
            }
        }

        .off+.button {
            opacity: 0;
            pointer-events: none;
        }
    </style>
</head>

<body>
    <div class="bell-container off" onclick="this.classList.toggle('off')">
        <div class="rope"></div>
        <div class="bell-top"></div>

        <div class="bell-base"></div>
        <div class="bell-base"></div>
        <div class="shadow-l1"></div>
        <div class="shadow-l2"></div>
        <div class="left-glow"></div>
        <div class="left-glow2"></div>
        <div class="r-glow"></div>
        <div class="r-glow2"></div>
        <div class="mid-ring"></div>
        <div class="mid-ring small"></div>

        <div class="glow"></div>
        <div class="glow2"></div>

        <div class="bell-buff-t"></div>
        <div class="bell-buff"></div>

        <div class="bell-btm"></div>
        <div class="bell-btm2"></div>

        <div class="bell-ring-container">
            <div class="bell-ring"></div>
            <div class="bell-rays"></div>
        </div>

        <div class="volumetric">
            <div class="vl"></div>
            <div class="vr"></div>
        </div>

    </div>
    <div class="button">Notify Me</div>
    <div class="grain"></div>
</body>

</html>

HTML

  • bell-container off:铃铛容器,初始状态为关闭(off),点击时切换 off 类。
  • 包含铃铛的各个部分,如绳子、铃铛顶部、底部、阴影、高光等。
  • button:一个按钮,显示"Notify Me"。
  • grain:一个覆盖整个页面的纹理层,用于增加视觉效果。

CSS

  • bell-container off:铃铛的主容器,初始状态为关闭(off),点击时切换 off 类。
  • rope:铃铛的绳子部分。
  • bell-top:铃铛的顶部。
  • bell-base:铃铛的底部,有两个相同的元素,一个用于显示,一个用于模糊效果。
  • shadow-l1 和 shadow-l2:铃铛的阴影部分。
  • left-glow 和 left-glow2:铃铛左侧的高光效果。
  • r-glow 和 r-glow2:铃铛右侧的高光效果。
  • mid-ring 和 mid-ring small:铃铛中间的环形部分。
  • glow 和 glow2:铃铛的发光效果。
  • bell-buff-t 和 bell-buff:铃铛的缓冲部分。
  • bell-btm 和 bell-btm2:铃铛的底部部分。
  • bell-ring-container:铃铛的铃铛部分,包含铃铛的主体和光线效果。
  • bell-ring:铃铛的主体。
  • bell-rays:铃铛的光线效果。
  • volumetric:铃铛的体积效果,包含两个子元素用于创建立体感。
  • vl 和 vr:用于创建立体感的左右部分。

各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!

相关推荐
掘金约基奇_9 分钟前
对css clip-path属性的理解,以及开发中的实际应用。
css
橙某人18 分钟前
🖼️照片展示新境界!等高不等宽自适应布局完整教程⚡⚡⚡
前端·javascript·css
尝尝你的优乐美22 分钟前
man!在console中随心所欲的打印图片和字符画
前端·javascript·vue.js
掘金012 小时前
Vue3 项目中实现特定页面离开提示保存功能方案
javascript·vue.js
余_弦2 小时前
区块链钱包开发(十九)—— 构建账户控制器(AccountsController)
javascript·区块链·以太坊
起这个名字2 小时前
Vue2/3 v-model 使用区别详解,不了解的来看看
前端·javascript·vue.js
ScottePerk2 小时前
css之再谈浮动定位float(深入理解篇)
前端·css·float·浮动布局·clear
sorryhc3 小时前
H5大视频上传治理
前端·javascript·性能优化
泡芙牛牛3 小时前
CSS动画:animation、transition、transform、translate的区别
前端·css