导读:本期聚焦于美园和花创作的《如何用 CSS 创建充满水的平面圆形,并模拟水的涟漪效果?》,敬请观看详情。想让页面上出现一个“装满水的圆形容器”,水位还能随百分比变化,点击时泛起一圈圈涟漪?其实纯 CSS 就能做到。本文会介绍如何利用 border-radius 画圆、借助 overflow hidden 裁剪水面、通过定位和旋转技巧模拟倾斜水面,再配合 keyframes 动画让水面产生上下起伏的波动。文中还会讲解用伪元素和 animation-delay 实现涟漪从点击处扩散的效果,以及利用多元素错位叠加让波形更自然的方法。无论是做加载进度球、饮水打卡组件还是交互反馈特效,这些技巧都能直接套用,代码均在文中完整给出,拿来即用。

在一些数据展示或打卡类页面里,经常能看到一种“水球”效果:一个圆形容器里装着水,水面微微晃动,水位随着进度上涨,点击时还会泛起涟漪。这种效果看似需要 Canvas 或 SVG,其实只用 CSS 就能实现,核心思路是利用 border-radius 画出圆形容器,用 overflow: hidden 把超出边界的水面裁掉,再通过旋转和动画让水面看起来在波动。下面从圆形容器搭建、水面制作、波动动画到涟漪扩散,一步步拆解实现方案。

如何用 CSS 创建充满水的平面圆形,并模拟水的涟漪效果?

一、搭建圆形容器:画一个“玻璃杯”

第一步是画出圆形的外框。这一步非常简单,一个正方形的 div 加上 border-radius: 50% 即可。为了让它更像一个装水的容器,通常会加上边框、内阴影和淡淡的背景色,营造出玻璃球的质感。

.water-ball {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  border: 4px solid #2a9d8f;
  background: rgba(42, 157, 143, 0.1);
  position: relative;
  overflow: hidden; /* 关键:裁剪超出圆形的水面 */
  box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
}

这里有个细节要特别注意:overflow: hidden 是整个效果的灵魂。水面元素本质上是一个比容器大得多的矩形,靠这个属性把它裁剪成圆形。如果不加,水面会以方形的样子溢出,效果立刻穿帮。

另外,如果希望水位是可变的(比如表示 60% 的进度),建议用行内样式或者 CSS 变量控制水面的位置,方便 JS 动态更新。可以定义一个 --percent 变量,后面所有和水位的计算都围绕它展开。

二、制作会倾斜的水面

水面是整个效果里最巧妙的部分。做法是:创建一个很宽的矩形(宽度至少是容器的两倍),给它设置圆角让上边缘呈弧形,然后旋转一个小角度(比如 5 度),再定位到容器中。旋转之后,这个矩形看起来就像一个斜面,配合外层容器的圆形裁剪,视觉上就是“一杯斜着的水”。

<div class="water-ball">
  <div class="water"></div>
  <div class="water water2"></div>
</div>
.water {
  position: absolute;
  width: 400px;               /* 比容器宽一倍,保证旋转后仍能覆盖 */
  height: 400px;
  border-radius: 40%;         /* 上边缘形成弧线 */
  background: rgba(42, 157, 143, 0.8);
  left: 50%;
  top: 60%;                   /* 水位:数值越小水越多 */
  transform: translateX(-50%) rotate(0deg);
}
.water2 {
  background: rgba(42, 157, 143, 0.5);
  top: 62%;                   /* 略低于第一层,形成叠加层次 */
}

水位控制的关键在 top 属性。假设容器高 200px,想让水面停在 60% 高度处,就把 top 设为 60%(水面元素自身的坐标原点在水面上沿)。两层水叠加,一层深一层浅,会有明显的水体通透感。

这里要提醒一个常见误区:border-radius: 40%50% 的区别很大。40% 会形成更扁的椭圆弧,转起来像水波;50% 接近正圆,旋转时上边缘几乎不产生起伏。做水波效果时选 35% 到 45% 之间通常观感最好。

三、让水面动起来:波动动画

静态的水没有生命力,接下来给两层水加上旋转动画。注意旋转的是水面元素本身,而不是容器。因为水面是带圆角的矩形,绕自身中心旋转时,上边缘的弧线会周期性地抬起和压下,看起来就是水在晃动。

@keyframes wave {
  from { transform: translateX(-50%) rotate(0deg); }
  to   { transform: translateX(-50%) rotate(360deg); }
}

.water {
  animation: wave 6s linear infinite;
}
.water2 {
  animation: wave 9s linear infinite; /* 速度不同,叠加出自然的波形 */
}

两层水使用不同的动画时长(比如 6 秒和 9 秒),它们的波峰波谷会不断错开又重合,产生类似真实水面的干涉效果。如果两层速度一样,波形会完全同步,看起来像一块塑料片在转,非常假。

还可以在水面元素上加一点模糊或透明度渐变,让水更柔和。比如给第二层水设置 filter: blur(1px),或者用 linear-gradient 做背景,从上到下颜色逐渐加深,模拟水的深度感。这些小细节能显著提升真实度。

四、模拟点击涟漪扩散效果

水球效果里最出彩的是涟漪:点击后从触点处扩散出一圈一圈的水纹。纯 CSS 做涟漪有两种常见方案,一种是 Material Design 风格的缩放圆,一种是描边圆环扩散,这里用第二种,更贴近水纹的观感。

<div class="water-ball" id="ball">
  <div class="water"></div>
  <div class="water water2"></div>
</div>
const ball = document.getElementById('ball');
ball.addEventListener('click', function (e) {
  // 计算点击点相对容器的坐标
  const rect = ball.getBoundingClientRect();
  const x = e.clientX - rect.left;
  const y = e.clientY - rect.top;

  // 创建多个涟漪圈,错开延迟形成一圈圈扩散
  for (let i = 0; i < 3; i++) {
    const ripple = document.createElement('span');
    ripple.className = 'ripple';
    ripple.style.left = x + 'px';
    ripple.style.top = y + 'px';
    ripple.style.animationDelay = (i * 0.25) + 's';
    ball.appendChild(ripple);
    // 动画结束后移除节点,避免堆积
    ripple.addEventListener('animationend', () => ripple.remove());
  }
});
.ripple {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.8);
  transform: translate(-50%, -50%) scale(1);
  animation: ripple-grow 1.2s ease-out forwards;
  pointer-events: none;
}

@keyframes ripple-grow {
  from {
    transform: translate(-50%, -50%) scale(1);
    opacity: 0.9;
  }
  to {
    transform: translate(-50%, -50%) scale(18);
    opacity: 0;
  }
}

这个方案的原理是:点击时动态创建若干个空白的描边圆环,把它们定位到点击坐标上,然后播放放大加淡出的动画。三个涟漪通过 animation-delay 依次触发,看起来就是一圈接一圈往外扩散。由于外层容器有 overflow: hidden,涟漪扩散到圆形边缘时会被自动裁掉,效果非常自然,不需要额外计算裁剪路径。

要注意 pointer-events: none 这个属性,它防止涟漪元素挡住后续的点击事件。如果没有它,涟漪还飘在半空时再点一次,点击可能落在涟漪元素上导致坐标计算错乱。另外记得在动画结束后移除节点,否则点击几十次后 DOM 里会堆积大量残留元素,影响性能。

五、性能与兼容性建议

整套效果用到的属性包括 transform、border-radius、opacity 和 animation,全部是 GPU 加速友好的属性,即使页面上放多个水球也不会明显掉帧。需要避免的是用 topleft 做波动动画,那会触发重排,性能差距很大。上文代码里动画只改 transform,水位变化才改 top,这是有意为之的分工。

如果要做水位从 0% 涨到目标值的动画,可以配合 CSS 变量加一个补间:JS 每隔一小段时间更新 --percent,或者直接用 Web Animations API 驱动 top 的过渡。再加上水面上的百分比文字(用一个绝对定位的元素盖在水球上即可),一个完整的“水球进度”组件就成型了。把这套结构封装成 Web Component 或者 Vue、React 组件,就能在任意项目里复用。

CSS水波纹涟漪动画border-radius修改时间:2026-09-06 03:32:42

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260906/51312.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。