涟漪按压

从按下的位置扩散出一圈柔和的圆形并逐渐消失,让按钮在被点击的地方给出回应。

  • CSS
  • 按钮
  • 点击
  • 收录于

AI 提示词

用 CSS 为 React 按钮制作按压涟漪效果。在 pointerdown 时,读取指针相对按钮的位置,并在该位置插入一个 <span>(position absolute,12px 圆形,translate -50% -50%,背景为 25% 不透明度的 currentColor)。用 CSS keyframe 在 600ms 内从 scale(0)、opacity 1 过渡到 scale(24)、opacity 0,缓动为 cubic-bezier(0.16, 1, 0.3, 1),并在 animationend 时移除该 span。按钮需要 overflow: hidden 和 position: relative。在 prefers-reduced-motion 下,用 120ms 的背景色变化代替涟漪。按钮文字为“保存修改”。

源代码

Demo.tsx
'use client'

import s from './demo.module.css'

export default function RipplePress({ labels }: { labels: Record<string, string> }) {
  const onDown = (e: React.PointerEvent<HTMLButtonElement>) => {
    const r = e.currentTarget.getBoundingClientRect()
    const dot = document.createElement('span')
    dot.className = s.ripple
    dot.style.left = `${e.clientX - r.left}px`
    dot.style.top = `${e.clientY - r.top}px`
    dot.addEventListener('animationend', () => dot.remove())
    e.currentTarget.appendChild(dot)
  }

  return (
    <button type="button" className={s.button} onPointerDown={onDown}>
      {labels.cta}
    </button>
  )
}
demo.module.css
.button {
  position: relative;
  overflow: hidden;
  height: 52px;
  padding: 0 32px;
  border: 0;
  border-radius: var(--radius-sm);
  background: var(--stage-accent);
  color: var(--stage-accent-ink);
  font: 500 var(--text-base) / 1 var(--font-body);
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-micro) var(--ease-out);
}

.button:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}

.ripple {
  position: absolute;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.25;
  translate: -50% -50%;
  pointer-events: none;
  animation: ripple 600ms var(--ease-out) forwards;
}

@keyframes ripple {
  from { transform: scale(0); opacity: 0.25; }
  to { transform: scale(24); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .ripple { display: none; }
  .button:active { background: var(--stage-accent-hover); }
}

投稿创意

看到想收录的动效或主题?简单描述一下,会打开一个预先填好的 GitHub Issue,确认后即可提交。

你想投稿的是?

需要 GitHub 账号,投稿内容会公开。