该 HTML 文件本质是通过SVG 滤镜组合 与 CSS 交互逻辑,实现图片除雾 + 冰雪质感强化的视觉效果,同时搭配鼠标悬停光点、自定义雪花光标等交互,让除雾后的图片更贴合冰雪主题。
大家复制代码时,可能会因格式转换出现错乱,导致样式失效。建议先少量复制代码进行测试,若未能解决问题,私信回复源码两字,我会发送完整的压缩包给你。
演示效果


HTML&CSS
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
:root {
font-size: clamp(1.5rem, 2vw + 1rem, 2.5rem);
--clr-bg: #020617;
--clr-text: #fff;
--clr-primary: #fff;
}
body {
height: 100svh;
display: grid;
place-items: center;
background: var(--clr-bg);
color: var(--clr-text);
padding: 1rem;
overflow: hidden;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
[defs] {
position: absolute;
pointer-events: none;
opacity: 0;
}
nav {
max-width: 20rem;
position: relative;
display: flex;
border-radius: 1em;
overflow: hidden;
filter: url(#❄️);
}
img {
width: 100%;
filter: url(#pack-upper);
}
.hover-area {
position: absolute;
--p: 1em;
inset: calc(var(--p) * -1);
padding: var(--p);
z-index: 999;
display: grid;
grid-template-columns: repeat(var(--max-a), 1fr);
background: black;
filter: blur(19px) brightness(5) contrast(80);
mix-blend-mode: plus-lighter;
filter: blur(19px) brightness(5) contrast(80) invert(1) blur(5px) url("#gray-pack-2b") url("#pack-lower");
cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='120' viewport='0 0 100 100' style='fill:white;font-size:80px; opacity: .8;'><text y='50%'>❄</text></svg>") 45 35, auto;
}
i {
background: white;
opacity: 0;
transition: opacity 5s;
border-radius: 50%;
scale: 2;
&:is(:hover, :active) {
opacity: 1;
transition-duration: 0s;
}
}
</style>
</head>
<body>
<nav style="--max-a:30;"><img src="https://images.pexels.com/photos/5516061/pexels-photo-5516061.jpeg"
alt="cold image" />
<aside class="hover-area">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</aside>
</nav><svg defs height="0" width="0" viewBox="0 0 1 1" color-interpolation-filters="sRGB">
<filter id="❄️" primitiveUnits="userSpaceOnUse" x="0%" y="0%" width="120%" height="120%">
<feComponentTransfer result="SourceBackground" in="SourceGraphic">
<feFuncR type="discrete"
tableValues="0.000 0.016 0.032 0.048 0.063 0.079 0.095 0.111 0.127 0.143 0.159 0.175 0.190 0.206 0.222 0.238 0.254 0.270 0.286 0.302 0.317 0.333 0.349 0.365 0.381 0.397 0.413 0.429 0.444 0.460 0.476 0.492 0.508 0.524 0.540 0.556 0.571 0.587 0.603 0.619 0.635 0.651 0.667 0.683 0.698 0.714 0.730 0.746 0.762 0.778 0.794 0.810 0.825 0.841 0.857 0.873 0.889 0.905 0.921 0.937 0.952 0.968 0.984 1.000">
</feFuncR>
<feFuncG type="discrete"
tableValues="0.000 0.016 0.032 0.048 0.063 0.079 0.095 0.111 0.127 0.143 0.159 0.175 0.190 0.206 0.222 0.238 0.254 0.270 0.286 0.302 0.317 0.333 0.349 0.365 0.381 0.397 0.413 0.429 0.444 0.460 0.476 0.492 0.508 0.524 0.540 0.556 0.571 0.587 0.603 0.619 0.635 0.651 0.667 0.683 0.698 0.714 0.730 0.746 0.762 0.778 0.794 0.810 0.825 0.841 0.857 0.873 0.889 0.905 0.921 0.937 0.952 0.968 0.984 1.000">
</feFuncG>
<feFuncB type="discrete"
tableValues="0.000 0.016 0.032 0.048 0.063 0.079 0.095 0.111 0.127 0.143 0.159 0.175 0.190 0.206 0.222 0.238 0.254 0.270 0.286 0.302 0.317 0.333 0.349 0.365 0.381 0.397 0.413 0.429 0.444 0.460 0.476 0.492 0.508 0.524 0.540 0.556 0.571 0.587 0.603 0.619 0.635 0.651 0.667 0.683 0.698 0.714 0.730 0.746 0.762 0.778 0.794 0.810 0.825 0.841 0.857 0.873 0.889 0.905 0.921 0.937 0.952 0.968 0.984 1.000">
</feFuncB>
</feComponentTransfer>
<feBlend result="blend-0" in="SourceBackground" in2="none"></feBlend>
<feGaussianBlur result="gaussian-blur-6" in="blend-0" stdDeviation="10"></feGaussianBlur>
<feTurbulence result="turbulence-0" baseFrequency="0.420" type="fractalNoise" />
<feDisplacementMap result="displacement-map-0" in="gaussian-blur-6" in2="turbulence-0" scale="150"
xChannelSelector="R" yChannelSelector="G"></feDisplacementMap>
<feComponentTransfer result="SourceMask" in="SourceGraphic">
<feFuncR type="discrete"
tableValues="0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000">
</feFuncR>
<feFuncG type="discrete"
tableValues="0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000">
</feFuncG>
<feFuncB type="discrete"
tableValues="0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000">
</feFuncB>
</feComponentTransfer>
<feBlend result="SourceMask"></feBlend>
<feColorMatrix result="color-matrix-0" in="SourceMask"
values="0.761905 0.190476 0.047619 0 0 0.761905 0.190476 0.047619 0 0 0.761905 0.190476 0.047619 0 0 0 0 0 1 0">
</feColorMatrix>
<feColorMatrix result="color-matrix-1" in="color-matrix-0" type="luminanceToAlpha"></feColorMatrix>
<feGaussianBlur result="gaussian-blur-0" in="color-matrix-1" stdDeviation="0"></feGaussianBlur>
<feComposite result="composite-1" in="displacement-map-0" in2="gaussian-blur-0" operator="in"></feComposite>
<feMerge result="merge-0">
<feMergeNode in="blend-0"></feMergeNode>
<feMergeNode in="composite-1"></feMergeNode>
</feMerge>
</filter>
<filter id="gray-unpack-2b">
<feColorMatrix id="unpackMatrix" in="SourceGraphic" result="unpackedGray" type="matrix"
values="0.761905 0.190476 0.047619 0 0 0.761905 0.190476 0.047619 0 0 0.761905 0.190476 0.047619 0 0 0 0 0 1 0" />
</filter>
<filter id="gray-pack-2b">
<feComponentTransfer id="feComponentTransfer-1" result="packed" in="SourceGraphic">
<feFuncR id="feFuncR-1" type="discrete" tableValues="0 0.3333 0.6667 1"></feFuncR>
<feFuncG id="feFuncG-1" type="discrete"
tableValues="0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1" />
<feFuncB id="feFuncB-1" type="discrete"
tableValues="0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1 0 0.3333 0.6667 1">
</feFuncB>
<feFuncA type="identity"></feFuncA>
</feComponentTransfer>
</filter>
<filter id="unpack-lower">
<feComponentTransfer in="SourceGraphic" result="component-transfer-0">
<feFuncR type="discrete" id="unpack-lower-r"
tableValues="0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000">
</feFuncR>
<feFuncG type="discrete" id="unpack-lower-g"
tableValues="0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000">
</feFuncG>
<feFuncB type="discrete" id="unpack-lower-b"
tableValues="0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000 0.000 0.333 0.667 1.000">
</feFuncB>
</feComponentTransfer>
</filter>
<filter id="pack-upper">
<feColorMatrix type="matrix" id="pack-upper-quantize" result="quantized"
values="0.24705882352941178 0 0 0 0 0 0.24705882352941178 0 0 0 0 0 0.24705882352941178 0 0 0 0 0 1 0"
in="SourceGraphic"></feColorMatrix>
<feComposite in="quantized" operator="over" result="composited" in2="quantized"></feComposite>
<feColorMatrix in="composited" type="matrix" id="pack-upper-shift"
values="4 0 0 0 0 0 4 0 0 0 0 0 4 0 0 0 0 0 1 0" result="color-matrix-0"></feColorMatrix>
</filter>
<filter id="pack-lower">
<feColorMatrix type="matrix" id="pack-lower-matrix"
values="0.011764705882352941 0 0 0 0 0 0.011764705882352941 0 0 0 0 0 0.011764705882352941 0 0 0 0 0 1 0">
</feColorMatrix>
</filter>
<filter id="unpack-upper">
<feComponentTransfer in="SourceGraphic" result="component-transfer-0">
<feFuncR type="discrete" id="unpack-upper-r"
tableValues="0.000 0.016 0.032 0.048 0.063 0.079 0.095 0.111 0.127 0.143 0.159 0.175 0.190 0.206 0.222 0.238 0.254 0.270 0.286 0.302 0.317 0.333 0.349 0.365 0.381 0.397 0.413 0.429 0.444 0.460 0.476 0.492 0.508 0.524 0.540 0.556 0.571 0.587 0.603 0.619 0.635 0.651 0.667 0.683 0.698 0.714 0.730 0.746 0.762 0.778 0.794 0.810 0.825 0.841 0.857 0.873 0.889 0.905 0.921 0.937 0.952 0.968 0.984 1.000">
</feFuncR>
<feFuncG type="discrete" id="unpack-upper-g"
tableValues="0.000 0.016 0.032 0.048 0.063 0.079 0.095 0.111 0.127 0.143 0.159 0.175 0.190 0.206 0.222 0.238 0.254 0.270 0.286 0.302 0.317 0.333 0.349 0.365 0.381 0.397 0.413 0.429 0.444 0.460 0.476 0.492 0.508 0.524 0.540 0.556 0.571 0.587 0.603 0.619 0.635 0.651 0.667 0.683 0.698 0.714 0.730 0.746 0.762 0.778 0.794 0.810 0.825 0.841 0.857 0.873 0.889 0.905 0.921 0.937 0.952 0.968 0.984 1.000">
</feFuncG>
<feFuncB type="discrete" id="unpack-upper-b"
tableValues="0.000 0.016 0.032 0.048 0.063 0.079 0.095 0.111 0.127 0.143 0.159 0.175 0.190 0.206 0.222 0.238 0.254 0.270 0.286 0.302 0.317 0.333 0.349 0.365 0.381 0.397 0.413 0.429 0.444 0.460 0.476 0.492 0.508 0.524 0.540 0.556 0.571 0.587 0.603 0.619 0.635 0.651 0.667 0.683 0.698 0.714 0.730 0.746 0.762 0.778 0.794 0.810 0.825 0.841 0.857 0.873 0.889 0.905 0.921 0.937 0.952 0.968 0.984 1.000">
</feFuncB>
</feComponentTransfer>
</filter>
</svg>
</body>
</html>
HTML
- body:页面可视内容的根容器,所有需要渲染的元素(导航、图片、交互区域)均在此包裹。
- nav:语义化导航标签(此处实际为 "图片展示容器",用 nav 仅为结构划分),通过 style="--max-a:30"自定义 CSS 变量,控制后续交互区域的网格列数。
- img:展示冰雪主题图片(src 链接为 Pexels 免费图库资源),alt="cold image"为图片加载失败时的替代文本(提升可访问性)。
- aside:绝对定位在图片上方的 "鼠标交互层",内部嵌套大量 i 标签作为 "雪花光点" 的载体,通过网格布局铺满整个图片区域。
- i(多个):空标签,初始透明,鼠标悬停时显示为白色圆形光点(模拟雪花效果),数量由 nav 的--max-a 变量控制。
- svg defs:定义 SVG 滤镜(页面核心视觉效果的关键),defs 标签表示 "可复用的滤镜定义",height="0" width="0"使其不占用页面空间,pointer-events: none 避免拦截鼠标事件,opacity:0 使其不可见(仅作为滤镜资源被引用)。
CSS
- :root:定义全局 CSS 变量,方便后续统一修改主题(如换背景色只需改--clr-bg);
- clamp(min, val, max):响应式字体大小,确保在不同屏幕尺寸下字体不会过大或过小;
- 通配符*:重置所有元素的默认 margin/padding,避免浏览器默认样式差异导致的布局问题。
布局样式:居中与容器控制
css
body {
height: 100svh; /* 高度:等于屏幕可视高度(svh适配移动端安全区域) */
display: grid;
place-items: center; /* Grid布局:子元素(<nav>)水平+垂直居中 */
background: var(--clr-bg); /* 引用全局背景色变量 */
color: var(--clr-text); /* 引用全局文本色变量 */
padding: 1rem; /* 内边距:避免内容贴边 */
overflow: hidden; /* 隐藏溢出内容(防止滚动条出现) */
}
nav {
max-width: 20rem; /* 最大宽度:限制图片容器宽度(避免过大) */
position: relative; /* 相对定位:作为子元素(<aside>)绝对定位的参考 */
display: flex;
border-radius: 1em; /* 圆角:使容器边角圆润(增强冰雪主题的柔和感) */
overflow: hidden; /* 隐藏溢出:确保图片和滤镜不超出容器圆角 */
filter: url(#❄️); /* 引用SVG主滤镜:给容器整体添加冰雪扭曲效果 */
}
.hover-area {
position: absolute; /* 绝对定位:覆盖在图片上方 */
--p: 1em; /* 自定义变量:控制内边距 */
inset: calc(var(--p) * -1); /* 定位:上下左右均向外扩展1em(覆盖容器外边缘) */
padding: var(--p); /* 内边距:与inset配合,确保交互区域铺满容器 */
z-index: 999; /* 层级:高于图片(确保交互优先) */
display: grid;
grid-template-columns: repeat(var(--max-a), 1fr); /* 网格列数:引用<nav>的--max-a变量(此处30列),每列宽度平均分配 */
/* 以下为交互层视觉效果:黑色模糊+亮度增强+颜色反转,模拟冰雪发光层 */
background: black;
filter: blur(19px) brightness(5) contrast(80) invert(1) blur(5px) url("#gray-pack-2b") url("#pack-lower");
/* 自定义光标:雪花图标(SVG生成),45/35为光标热点位置(点击时的有效坐标) */
cursor: url("data:image/svg+xml;utf8,<svg...>❄</svg>") 45 35, auto;
}
- 100svh:相比 100vh,svh 会适配移动端的 "刘海屏""底部安全区",避免内容被遮挡;
- grid-template-columns: repeat(var(--max-a), 1fr):动态网格列数,通过 nav 的--max-a 变量控制,实现 "交互光点密度可调"(如改--max-a:20 则光点更稀疏)。
特殊样式:SVG 滤镜关联
CSS 中通过 filter: url(#滤镜 ID)引用 SVG 定义的滤镜,核心关联场景:
- nav 引用#❄️:容器整体添加冰雪扭曲效果;
- img 引用#pack-upper:图片添加灰度量化,降低饱和度;
- .hover-area 引用#gray-pack-2b 和#pack-lower:交互层添加颜色融合,增强发光效果。
视觉样式:图片与光点效果
css
img {
width: 100%; /* 宽度:占满父容器(<nav>) */
filter: url(#pack-upper); /* 引用SVG滤镜:给图片添加灰度量化效果(增强冰雪质感) */
}
i {
background: white; /* 光点背景色:白色(模拟雪花) */
opacity: 0; /* 初始状态:透明(不可见) */
transition: opacity 5s; /* 过渡动画:透明度变化持续5秒(光点消失时缓慢隐藏) */
border-radius: 50%; /* 圆形:使光点为圆形(雪花光点效果) */
scale: 2; /* 缩放:放大2倍(增强视觉效果) */
/* 鼠标悬停/点击时的状态:光点显示 */
&:is(:hover, :active) {
opacity: 1; /* 完全不透明(显示光点) */
transition-duration: 0s; /* 取消过渡:悬停时立即显示 */
}
}
- &:is(:hover, :active):CSS 嵌套语法(需配合 PostCSS 或现代浏览器),等价于.i:hover, .i:active,简化选择器写法;
- 光点交互逻辑:初始透明,鼠标悬停时立即显示(transition-duration:0s),鼠标离开后通过 transition: opacity 5s 缓慢透明(模拟雪花消失效果)。
各位互联网搭子,要是这篇文章成功引起了你的注意,别犹豫,关注、点赞、评论、分享走一波,让我们把这份默契延续下去,一起在知识的海洋里乘风破浪!