AI CSS Animations

Testimonial Card Hover

A customer quote card: the big quote mark swings into the accent color and the five stars pop in one after another. The star shape is a clip-path polygon, so there is no icon font.

Also known as: review card hover effect, quote card css, customer testimonial animation.

Setup took ten minutes, and support answered before my coffee cooled.
Jo Park Founder, Loop

HTML

<figure class="hfx-card-testimonial">
  <svg class="hfx-card-testimonial-quote" viewBox="0 0 32 24" aria-hidden="true"><path d="M0 24V14C0 6 4 1.2 12 0v5c-4 1-6 4-6 8h6v11zm18 0V14c0-8 4-12.8 12-14v5c-4 1-6 4-6 8h6v11z"/></svg>
  <div class="hfx-card-testimonial-stars" role="img" aria-label="Rated 5 out of 5">
    <span style="--i: 0"></span><span style="--i: 1"></span><span style="--i: 2"></span><span style="--i: 3"></span><span style="--i: 4"></span>
  </div>
  <blockquote>Setup took ten minutes, and support answered before my coffee cooled.</blockquote>
  <figcaption><span class="hfx-card-testimonial-avatar"></span><span><strong>Jo Park</strong> Founder, Loop</span></figcaption>
</figure>

CSS

.hfx-card-testimonial {
  --c: var(--hfx-color, #3b82f6);
  font-size: var(--hfx-size, 16px);
  width: 15em;
  border-radius: 0.75em;
  overflow: hidden;
  background: #fff;
  border: 1px solid color-mix(in srgb, #000 10%, transparent);
  color: #1f2937;
  font-family: system-ui, sans-serif;
  position: relative;
  box-sizing: border-box;
  width: 16em;
  margin: 0;
  padding: 1.1em 1.2em 1.1em;
  transition: transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1), box-shadow 0.35s ease;}
.hfx-card-testimonial:hover {
  transform: translateY(-0.2em);
  box-shadow: 0 0.9em 1.4em -0.9em color-mix(in srgb, #000 35%, transparent);
}
.hfx-card-testimonial-quote {
  position: absolute;
  top: 0.85em;
  right: 1.1em;
  width: 1.8em;
  fill: color-mix(in srgb, var(--c) 20%, transparent);
  transform-origin: 50% 60%;
  transition: fill 0.3s ease, transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.hfx-card-testimonial:hover .hfx-card-testimonial-quote {
  fill: var(--c);
  transform: translate(-0.1em, -0.05em) rotate(-10deg) scale(1.15);
}
.hfx-card-testimonial-stars {
  display: flex;
  gap: 0.18em;
  margin-bottom: 0.7em;
}
.hfx-card-testimonial-stars span {
  width: 0.85em;
  height: 0.85em;
  background: color-mix(in srgb, var(--c) 22%, transparent);
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.hfx-card-testimonial:hover .hfx-card-testimonial-stars span {
  background: var(--c);
  animation: hfx-card-testimonial-pop 0.45s calc(var(--i) * 70ms) cubic-bezier(0.34, 1.56, 0.64, 1) both;
}
.hfx-card-testimonial blockquote {
  margin: 0;
  font-size: 0.85em;
  line-height: 1.45;
  color: #374151;
}
.hfx-card-testimonial figcaption {
  display: flex;
  padding: 0;
  font-family: inherit;
  align-items: center;
  gap: 0.6em;
  margin-top: 0.8em;
  font-size: 0.72em;
  color: #6b7280;
}
.hfx-card-testimonial figcaption strong {
  display: block;
  color: #111827;
}
.hfx-card-testimonial-avatar {
  width: 2.4em;
  height: 2.4em;
  border-radius: 50%;
  background: linear-gradient(135deg, color-mix(in srgb, var(--c) 45%, #fff), var(--c));
}
@keyframes hfx-card-testimonial-pop {
  from { transform: scale(0.4) rotate(-40deg); background: color-mix(in srgb, var(--c) 22%, transparent); }
  to { transform: none; background: var(--c); }
}

@media (prefers-reduced-motion: reduce) {
  .hfx-card-testimonial, .hfx-card-testimonial *, .hfx-card-testimonial::before, .hfx-card-testimonial::after, .hfx-card-testimonial *::before, .hfx-card-testimonial *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

Customizing this snippet

  • Color: set --hfx-color on the element or a parent. Currently previewing #3b82f6.
  • Base size: set --hfx-size. Every other dimension is in em, so the whole thing scales together. Currently previewing 16px.
  • Speed: change the duration on the transition or animation shorthand. Staggered delays are relative, so they keep their rhythm.
  • Reduced motion: the rule at the end of the CSS turns the motion off for people who asked their OS for less of it. Keep it.

Similar hover effects