About this snippet

A confirmation panel where the circle draws itself, the tick draws in after it, then the heading and message fade up below. It all runs on load with no JavaScript.

The drawing effect is the stroke-dasharray trick. Each stroke gets a dash the same length as the path and an equal dashoffset, which hides it completely, then the animation pulls that offset to zero and the line appears to draw. The circle uses 252, which is its circumference at radius 40 rounded up.

Sequencing is done entirely with delays. Each animation shorthand carries two time values, duration first and delay second, which is how the circle waits 0.2s, the tick 0.7s, then the text 1s and 1.2s. Shifting one step means shifting the ones after it too. If you swap the tick for a different path, measure it with getTotalLength and feed that number to both the dasharray and the dashoffset.

Size
2.1 KB
Uses
HTML, CSS
Loads
Nothing external
Views
934
<div class="success-wrapper">
  <div class="icon-wrap">
    <svg class="success-svg" viewBox="0 0 100 100" width="120" height="120">
      <circle class="success-circle" cx="50" cy="50" r="40" fill="none" stroke="#10b981" stroke-width="6" stroke-linecap="round"></circle>
      <polyline class="success-check" points="35 50 45 60 65 40" fill="none" stroke="#10b981" stroke-width="6" stroke-linecap="round" stroke-linejoin="round"></polyline>
    </svg>
  </div>
  <h2>Payment Successful</h2>
  <p>Your receipt has been sent via email.</p>
</div>
*, *::before, *::after {
  box-sizing: border-box;
}

body {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  margin: 0;
  background: #f8fafc;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

.success-wrapper {
  background: #ffffff;
  padding: 50px;
  border-radius: 24px;
  box-shadow: 0 20px 40px -10px rgba(0, 0, 0, 0.1);
  text-align: center;
  width: 100%;
  max-width: 400px;
}

.icon-wrap {
  margin-bottom: 20px;
  transform: scale(0);
  animation: pop-in 0.6s cubic-bezier(0.34, 1.56, 0.64, 1.3) forwards;
}

@keyframes pop-in {
  0% { transform: scale(0); }
  80% { transform: scale(1.1); }
  100% { transform: scale(1); }
}

.success-circle {
  stroke-dasharray: 252;
  stroke-dashoffset: 252;
  animation: draw-circle 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s forwards;
}

/* Mathematical exact length of the checkmark path */
.success-check {
  stroke-dasharray: 50;
  stroke-dashoffset: 50;
  animation: draw-check 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) 0.7s forwards;
}

@keyframes draw-circle {
  to { stroke-dashoffset: 0; }
}

@keyframes draw-check {
  to { stroke-dashoffset: 0; }
}

.success-wrapper h2 {
  margin: 0 0 10px 0;
  color: #0f172a;
  font-size: 1.75rem;
  opacity: 0;
  transform: translateY(10px);
  animation: fade-up 0.5s ease 1s forwards;
}

.success-wrapper p {
  color: #64748b;
  margin: 0;
  font-size: 1.1rem;
  opacity: 0;
  transform: translateY(10px);
  animation: fade-up 0.5s ease 1.2s forwards;
}

@keyframes fade-up {
  to { opacity: 1; transform: translateY(0); }
}
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save