CSS Clip Path

The clip-path property cuts an element into a custom shape. Everything outside the clipping region becomes invisible — the content still exists in the DOM, it just does not render outside the shape. No image editor needed.

How Clipping Works

DIAGRAM — Clipping a rectangle to a circle:

Before clip-path:           After clip-path: circle(50%):

┌──────────────────┐              ╭──────────╮
│                  │            ╱              ╲
│   Photo content  │           │  Photo (round) │
│                  │           │                │
└──────────────────┘            ╲              ╱
                                  ╰──────────╯
Corners are invisible — the image is still there,
just hidden outside the circle boundary.

clip-path: circle()

Creates a circular clip. The value is the radius as a percentage or length, and optionally a center point.

.avatar {
  clip-path: circle(50%);
  /* Clips to a circle at the center of the element */
}

/* With a custom center point */
.bubble {
  clip-path: circle(40% at 30% 50%);
  /* 40% radius, centered at 30% left, 50% top */
}

clip-path: ellipse()

Creates an ellipse clip with separate horizontal and vertical radii.

.oval {
  clip-path: ellipse(60% 40% at center);
}

/* rx = horizontal radius, ry = vertical radius */

clip-path: polygon()

Creates any multi-sided shape using a list of x/y coordinate pairs. Each point is a vertex of the shape.

clip-path: polygon(x1 y1, x2 y2, x3 y3, ...);

Triangle

.triangle {
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
DIAGRAM — Triangle polygon:

Point 1: 50% 0%  (top center)
Point 2: 0% 100% (bottom left)
Point 3: 100% 100% (bottom right)

        ▲  ← top center
       ╱ ╲
      ╱   ╲
     ╱_____╲  ← bottom-left to bottom-right

Parallelogram

.parallelogram {
  clip-path: polygon(10% 0%, 100% 0%, 90% 100%, 0% 100%);
}
DIAGRAM — Parallelogram:

   10%─────────────100%
  ╱                   ╲
0%───────────────────90%
(slanted left and right sides)

Arrow Shape

.arrow {
  clip-path: polygon(
    0% 20%, 60% 20%, 60% 0%,
    100% 50%, 60% 100%, 60% 80%, 0% 80%
  );
}
DIAGRAM — Arrow pointing right:

┌──────╮
│       ▶
└──────╯

Pentagon

.pentagon {
  clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
}

Star

.star {
  clip-path: polygon(
    50% 0%,
    61% 35%,
    98% 35%,
    68% 57%,
    79% 91%,
    50% 70%,
    21% 91%,
    32% 57%,
    2% 35%,
    39% 35%
  );
}

clip-path: inset()

Clips to a rectangle with optional rounded corners. All four sides inset from the element's edges.

/* inset(top right bottom left) */
.cropped {
  clip-path: inset(10px 20px 10px 20px);
}

/* With rounded corners */
.rounded-crop {
  clip-path: inset(10% round 20px);
}
DIAGRAM — inset(20px):

Before:           After inset(20px):
┌──────────┐       ┌────────┐
│          │       │ (20px  │
│  content │  →    │  gap   │
│          │       │ all    │
└──────────┘       └sides───┘

clip-path: path()

Uses SVG path syntax for completely custom shapes — curves, bezier arcs, complex outlines.

.custom {
  clip-path: path("M 0 50 Q 50 0 100 50 Q 50 100 0 50");
  /* A diamond-like curved shape */
}

Animating clip-path

You can animate clip-path between two shapes as long as they have the same number of points. The browser interpolates each vertex.

.btn {
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  transition: clip-path 0.4s ease;
}

.btn:hover {
  clip-path: polygon(10% 0%, 100% 0%, 90% 100%, 0% 100%);
  /* Rectangle morphs to a parallelogram on hover */
}
DIAGRAM — Animated clip-path on hover:

Normal:        ┌──────────┐
               └──────────┘

On hover:       ╱──────────╮
                ╲──────────╯
(parallelogram — same 4 points, different positions)

Reveal Animation with clip-path

A common technique to reveal elements as they enter the screen:

@keyframes revealFromLeft {
  from {
    clip-path: inset(0 100% 0 0);  /* fully hidden (right side closed) */
  }
  to {
    clip-path: inset(0 0% 0 0);    /* fully visible */
  }
}

.reveal {
  animation: revealFromLeft 0.6s ease-out forwards;
}

clip-path vs overflow: hidden vs border-radius

DIAGRAM — Three ways to clip corners:

border-radius: 50%;     → circle, but limited to ellipses
overflow: hidden;       → clips to the rectangular box, no shape control
clip-path: polygon(...) → any shape — triangles, hexagons, stars, custom

Common Clip Path Shapes

Shapeclip-path value
Circlecircle(50%)
Ovalellipse(70% 50%)
Triangle (up)polygon(50% 0%, 0% 100%, 100% 100%)
Chevron rightpolygon(0 0, 75% 0, 100% 50%, 75% 100%, 0 100%, 25% 50%)
Rhombuspolygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)
Slanted bottompolygon(0 0, 100% 0, 100% 80%, 0 100%)

Browser Support Note

All modern browsers support clip-path with circle(), ellipse(), polygon(), and inset(). The path() value has broader support in recent browsers. Add -webkit-clip-path for older Safari support.

.shape {
  -webkit-clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
  clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}

clip-path unlocks shapes that are impossible with borders alone. Use it for stylized hero sections, unique image frames, diagonal section dividers, and hover reveal effects — all with pure CSS.

Leave a Comment

Your email address will not be published. Required fields are marked *