The Rule: Same Function, Same Point Count

For clip-path transitions to animate smoothly, both the start and end states must use the same shape function with the same number of coordinate points. You can transition a polygon with 4 points to another polygon with 4 points, but not from 4 points to 6 points โ€” the browser won't interpolate.

CSS
/* This works โ€” same function, same point count */
.card {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  transition: clip-path 0.4s ease;
}
.card:hover {
  clip-path: polygon(5% 5%, 95% 0, 100% 95%, 0 100%);
}

/* This does NOT animate โ€” different point counts */
.bad {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%); /* 4 points */
}
.bad:hover {
  clip-path: polygon(50% 0, 100% 38%, 82% 100%, 18% 100%, 0 38%); /* 5 points */
}

The workaround for different point counts is to add duplicate points to the simpler shape. For example, to transition a square to a triangle, use a "triangle" that has 4 points with two of them at the same position.

Circle Reveal Effect

One of the most popular clip-path animations is the circle reveal โ€” expanding a circle from a point to reveal content underneath.

CSS
.reveal {
  clip-path: circle(0% at 50% 50%);
  transition: clip-path 0.6s ease-out;
}
.reveal.visible {
  clip-path: circle(75% at 50% 50%);
}

/* Reveal from click position using JS */
.reveal-from-cursor {
  clip-path: circle(0% at var(--x, 50%) var(--y, 50%));
  transition: clip-path 0.5s cubic-bezier(0.25, 0, 0, 1);
}
.reveal-from-cursor.active {
  clip-path: circle(150% at var(--x, 50%) var(--y, 50%));
}

Combined with a little JavaScript to set --x and --y CSS variables based on mouse position, you get a smooth reveal from wherever the user clicks.

Shape-Shifting Hover Effects

You can transition between any two polygons to create morphing shapes on hover. The key is ensuring both shapes have the same number of points.

CSS
/* Diamond to square morph */
.morph {
  clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
  transition: clip-path 0.3s ease;
}
.morph:hover {
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
}

/* Diagonal slice reveal */
.slice {
  clip-path: polygon(0 0, 0 0, 0 100%, 0 100%);
  transition: clip-path 0.5s ease;
}
.slice.active {
  clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
}

Keyframe Animations

For continuous animations, use @keyframes. This blob animation creates an organic, morphing shape:

CSS
@keyframes blob {
  0%, 100% {
    clip-path: polygon(
      30% 0%, 70% 0%, 100% 30%, 100% 70%,
      70% 100%, 30% 100%, 0% 70%, 0% 30%
    );
  }
  50% {
    clip-path: polygon(
      20% 10%, 80% 5%, 95% 35%, 90% 75%,
      75% 95%, 25% 90%, 5% 65%, 10% 25%
    );
  }
}
.blob { animation: blob 4s ease-in-out infinite; }

Performance Tips

Clip-path animations are GPU-accelerated in most browsers, but a few things to keep in mind. Avoid animating clip-path on large elements during scroll โ€” use will-change: clip-path to hint at the browser. Keep polygon point counts reasonable (under 20 points). For complex shapes, consider SVG clip paths with SMIL animation instead.

Design your starting shapes with our CSS Clip Path Generator โ€” drag points, pick presets and copy the code. Then add transitions in your stylesheet.