404表情脸(可复制源代码)

404表情脸(可复制源代码)

站长可乐
3天前发布

效果演示

640.gif

源代码

<!DOCTYPE html>
<html lang="zh-CN">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>404表情脸</title>
        <style>
            * { border: 0; box-sizing: border-box; margin: 0; padding: 0; } :root { --hue: 223; --sat: 10%; --light: hsl(var(--hue), var(--sat), 95%); --dark: hsl(var(--hue), var(--sat), 5%); --trans-dur: 0.3s; color-scheme: light dark; font-size: clamp(1rem, 0.95rem + 0.25vw, 1.25rem); } body { background-color: light-dark(var(--light), var(--dark)); color: light-dark(var(--dark), var(--light)); font: 1em / 1.5 sans-serif; display: grid; place-items: center; height: 100vh; transition: background-color var(--trans-dur), color var(--trans-dur); } main { padding: 1.5em 0; } .face { display: block; width: 12em; height: auto; } .face__eyes, .face__eye-lid, .face__mouth-left, .face__mouth-right, .face__nose, .face__pupil { animation: eyes 1s 0.3s cubic-bezier(0.65, 0, 0.35, 1) forwards; } .face__eye-lid, .face__pupil { animation-duration: 4s; animation-delay: 1.3s; animation-iteration-count: infinite; } .face__eye-lid { animation-name: eye-lid; } .face__mouth-left, .face__mouth-right { animation-timing-function: cubic-bezier(0.33, 1, 0.68, 1); } .face__mouth-left { animation-name: mouth-left; } .face__mouth-right { animation-name: mouth-right; } .face__nose { animation-name: nose; } .face__pupil { animation-name: pupil; } @keyframes eye-lid { from, 40%, 45%, to { transform: translateY(0); } 42.5% { transform: translateY(17.5px); } } @keyframes eyes { from { transform: translateY(112.5px); } to { transform: translateY(15px); } } @keyframes pupil { from, 37.5%, 40%, 45%, 87.5%, to { stroke-dashoffset: 0; transform: translate(0, 0); } 12.5%, 25%, 62.5%, 75% { stroke-dashoffset: 0; transform: translate(-35px, 0); } 42.5% { stroke-dashoffset: 35; transform: translate(0, 17.5px); } } @keyframes mouth-left { from, 50% { stroke-dashoffset: -102; } to { stroke-dashoffset: 0; } } @keyframes mouth-right { from, 50% { stroke-dashoffset: 102; } to { stroke-dashoffset: 0; } } @keyframes nose { from { transform: translate(0, 0); } to { transform: translate(0, 22.5px); } }
        </style>
    </head>
    <body>
        <main>
            <svg class="face" viewBox="0 0 320 380" width="320px" height="380px" aria-label="404 数字变成一张脸,左右张望并眨眼,嘴角画出微笑。">
                <g fill="none" stroke="currentcolor" stroke-linecap="round" stroke-linejoin="round" stroke-width="25">
                    <g class="face__eyes" transform="translate(0, 112.5)">
                        <g transform="translate(15, 0)">
                            <polyline class="face__eye-lid" points="37,0 0,120 75,120" />
                            <polyline class="face__pupil" points="55,120 55,155" stroke-dasharray="35 35" />
                        </g>
                        <g transform="translate(230, 0)">
                            <polyline class="face__eye-lid" points="37,0 0,120 75,120" />
                            <polyline class="face__pupil" points="55,120 55,155" stroke-dasharray="35 35" />
                        </g>
                    </g>
                    <rect class="face__nose" rx="4" ry="4" x="132.5" y="112.5" width="55" height="155" />
                    <g stroke-dasharray="102 102" transform="translate(65, 334)">
                        <path class="face__mouth-left" d="M 0 30 C 0 30 40 0 95 0" stroke-dashoffset="-102" />
                        <path class="face__mouth-right" d="M 95 0 C 150 0 190 30 190 30" stroke-dashoffset="102" />
                    </g>
                </g>
            </svg>
        </main>
    </body>
</html>

实现思路拆分

404 表情脸是怎么画出来的?
404 表情脸用单个 SVG 把数字「404」变成一张会动的人脸:两个「4」上滑变眼睛,中间的「0」下滑变鼻子,嘴角描边动画拼出微笑;全程纯 CSS,无 JavaScript。

说白了就三件事

HTML:一个 ,polyline / rect / path 分组为眼、鼻、嘴。
CSS:translateY 把 404 布局拆成五官位置;stroke-dashoffset 画嘴线与瞳孔。
动效:先 0.3s 延迟后五官归位,再循环眨眼、左右看、嘴线展开。
改节奏动 keyframes 百分比与 delay,改配色动 currentColor 与 light-dark 背景。

颜色为啥长这样

背景 / 描边:light-dark() 灰阶,跟随系统深浅色
SVG 统一 stroke="currentcolor",随主题反色
线条粗 stroke-width="25",卡通线稿感
无填充,纯描边结构

动起来是啥感觉

页面中央一张线稿脸,初始布局像「404」三字。
1.0.3 秒后两个「4」上滑变成双眼,中间「0」下滑成鼻子
2.左右嘴角描边从外向内画出,拼成微笑
3.瞳孔左右移动并配合眨眼(眼睑压下)
4.约 4 秒一轮循环,表情生动不闹
5.屏幕阅读器通过 aria-label 获知动画含义

怎么一层层画出来

SVG 结构

1..face__eyes:两组 polyline(眼睑 + 瞳孔竖线)。
2..face__nose:圆角 rect,从 0 的位置下移。
3..face__mouth-left/right:贝塞尔 path + dashoffset 画嘴角。

CSS 动画

1.eyes:整组 eyes 从 y=112.5 移到 y=15。
2.nose:translateY(22.5px) 下挪。
3.mouth-left/right:dashoffset 从 ±102 到 0 画嘴。
4.pupil:translateX 左右看 + 眨眼时 dashoffset。
5.eye-lid:translateY 快速压扁模拟眨眼。源码获取

© 版权声明
THE END
喜欢就支持一下吧
点赞 0 分享 收藏
评论 抢沙发
OωO
取消