A guide to CSS animations using clip-path()
Tags: css, webdev
Published: 2021-07-07 19:00:16

**Written by [Habdul Hazeez](https://blog.logrocket.com/author/habdulhazeez/)** ✏️

This article explains in detail what CSS animation is all about using the CSS `clip-path()` property. By the end of it, you will have a thorough understanding of CSS animation and how to manipulate any `clip-path()` code you might come across.

## What is CSS animation?

CSS animation allows you to animate the value of CSS properties over a specific period of time using [keyframes](https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes). Keyframes are among the many building blocks of understanding CSS animations.

Two main building blocks allow CSS animations to take effect. They are:

*   `@keyframes`
*   `animation` properties

## Using `@keyframes` in CSS

`@keyframes` is an at-rule in CSS. It is used to define the stages and styles of the animation. It comprises the name of the animation, the keyframe block, and the stages of the animation.

### 1. Name of the animation

You specify the name of the animation after `@keyframes`. It's also called the keyframes name.

Let's create an animation that allows text to pop in called `popIn`.

```css
@keyframes popIn {}
```

### 2. The keyframe block

This encapsulates the entire code of the animation.

```css
@keyframes popIn {
    /* This is the keyframes block */
```

### 3. Stages of the animation

The stages of animation — also called the keyframe selector — contain the CSS code that dictates the behavior of the animation. This CSS code is situated in a pair of `from` or `to` blocks, comma-separated percentage values, or a combination of both.

```css
@keyframes popIn {
   0% {
       transform: scale(0.1);
       opacity: 0;
  }

   60% {
       transform: scale(1.2);
       opacity: 1;
  }

   100% {
       transform: scale(1);
  }
}
```

You can also combine the `from` or `to` block with the comma-separated percentage values, meaning you can write the previous code block as such:

```css
@keyframes popIn {
   from {
       transform: scale(0.1);
       opacity: 0;
  }

   60% {
       transform: scale(1.2);
       opacity: 1;
  }

   to {
       transform: scale(1);
  }
}<
```

Why? That is because `from` is equivalent to `0%` and `to` is equivalent to `100%`.

Mind you, if you write `60%` in the previous code block as `60`, the browser will ignore the animation at that stage, which can lead to hard-to-trace bugs.

Now that you've created the keyframes, you'll use animation properties to add the keyframes to the element(s) you wish to animate.

## Animation properties in CSS

These properties assign the `@keyframes` to the elements you wish to animate, and they also define how the element is animated. They are necessary for the animation to function.

Although there are nine properties, the following two are necessary for the animation to occur:

*   `animation-name`: this is the animation name defined in the keyframes
*   `animation-duration`: this tells the animation how long it will occur for and is specified in seconds or milliseconds.

At this juncture, you have almost everything you'll need to create an animation. Read on.

### Animation example: `popIn`

Now we have to determine the element to animate, which, of course, is an HTML element. You can grab this HTML element via your suitable selector from CSS, but here I'll use a class selector.

Before proceeding, create the following:

1.  A project folder
2.  Boilerplate HTML file
3.  CSS file
4.  Link the HTML file with the CSS file
5.  Copy and paste the `popIn` animation to your CSS file

In your HTML file, type the next code block between the opening and closing `body` tags.

```html
<div>
   <p class="hello-world">Hello World!!!</p>
</div>
```

In addition to the `@keyframes` you have in the CSS file, type the following:

```css
.hello-world {
   animation-name: popIn;
   animation-duration: 3s;
}
```

That's it. Save your files and test them out in your browser. The phrase "Hello world!!!" should pop in.

In addition, you can write the previous code block like this:

```css
.hello-world {
   animation: popIn 3s;
}
```

This is possible because the `animation` property is shorthand for all other animation properties listed in the next section (excluding the `animation` property itself).

### Additional CSS animation properties

Listed below are the remaining animation properties.

1.  `animation`
2.  `animation-delay`
3.  `animation-direction`
4.  `animation-fill-mode`
5.  `animation-iteration-count`
6.  `animation-play-state`
7.  `animation-timing-function`

The functions of these properties are explicit from their name, but I think they are best explained when you see them in action. Later, we'll use the `clip-path()` property to create some cool effects.

Before that, though, you need to know about the `clip-path()` property.

## What is CSS `clip-path()`?

CSS `clip-path()` is a property that allows you to create a clipping region from an element. The region within this clipped part is shown, while the rest are hidden.

At first, `clip-path()` might be daunting to understand, but once you understand the geometry behind it, it becomes easy to use.

### The CSS `clip-path()` coordinate system

In CSS, `clip-path()` allows you to create clipping regions of shapes when you specify their shape and position on a coordinate system.

The coordinate system uses coordinates to determine the position of the points in a given space. Here's an example.

![Rectangle Plotted On A Graph](https://blog.logrocket.com/wp-content/uploads/2021/06/coordinate-system-rectangle.jpeg)

From the image above, the starting point of the coordinate is `x0, y0`. When you move clockwise, the final position would still be `x0, y0`.

Armed with this knowledge, you can use `CSS clip-path()` to create and position shapes on this coordinate system. This is possible thanks to its array of accepted values.

## CSS `clip-path()` accepted values

CSS `clip-path()` accepted values are functions that accept parameters. These parameters dictate the appearance and position of the clipped region.

The functions are listed below:

*   `inset()`
*   `circle()`
*   `ellipse()`
*   `path()`
*   `polygon()`

### `inset()`

The `inset()` function allows you to clip an element from all four sides of the coordinate system. The result is a visible rectangle.

The way you assign values to `inset()` is similar to the way you assign values to the `margin` or `padding` property.

This means:

*   A single value applies to all four sides
*   Two values apply to the top and bottom, right and left
*   Three values apply to the top, right and left, bottom (in that order)
*   All four values apply to individual sides

As an example, the image below shows a blue box occupying its entire parent width.

![Blue Box](https://blog.logrocket.com/wp-content/uploads/2021/06/clip-path-blue-box.png)

The next code block clips the box from all four sides of its parent.

```css
.selector {
   clip-path: inset(20px 30px 35px 20px);
}
```

Now, you have this:

![Blue Box With White Padding](https://blog.logrocket.com/wp-content/uploads/2021/06/blue-box-white-padding.png)

Meanwhile, `inset()` comes with additional powers! You can specify the border-radius as one of its parameters. You'll have to use the `round` keyword followed by the `border-radius` value, as depicted in the next code block.

```css
.selector {
   clip-path: inset(20px 30px 35px 20px round 20px);
}
```

![Blue Rectangle With Round Corners And White Padding](https://blog.logrocket.com/wp-content/uploads/2021/06/blue-rectangle-round-corners.png)

You can also limit the rounded corners to two sides by specifying two values after the `round` keyword.

When you do this, the first value is assigned to the top left corner and bottom right corner, while the second value is assigned to the top right corner and the bottom left corner.

```css
.selector {
   clip-path: inset(20px 30px 35px 20px round 20px 50px);
}
```

![Rectangle With Round Corners On Top Right Corner And The Bottom Left Corner](https://blog.logrocket.com/wp-content/uploads/2021/06/rectangle-top-bottom-corners-rounder.png)

### `circle()`

Its name says it all. It allows you to draw a circle on the coordinate system using the circle radius and its position.

```css
.selector {
   clip-path: circle(100px at 40%)
}
```

From the previous code block, the circle radius is `100px` and its position is `40%` on the x- and y-axis.

![Blue Circle In Rectangle](https://blog.logrocket.com/wp-content/uploads/2021/06/blue-circle-in-rectangle.png)

### `ellipse()`

This allows you to create an oval-shaped clipping. Its parameter is the width, the height (followed by the `at` keyword), then the clipping position.

The position can be specified by keyword values such as `center` or `percentage`. In the next code block, `50% 50%` is equivalent to the `center` keyword.

```css
.selector {
   clip-path: ellipse(80px 60px at 50% 50%);
}
```

![Blue Oval In Rectangle ](https://blog.logrocket.com/wp-content/uploads/2021/06/blue-oval-rectangle.png)

### `path()`

If using Scalable Vector Graphics (SVG) is your thing, you'll need the `path()` function, which allows you to use an SVG path to create a clipping region.

The browser support is inconsistent, as shown in the [Can I use...](https://caniuse.com/) image below.

![Can I Use Page With The Query Path()](https://blog.logrocket.com/wp-content/uploads/2021/06/can-i-use-path.png)

To get around this, you can declare an inline SVG in your HTML file. In your CSS, you'll use the `url()` function as the value of `clip-path()`.

```html
<div class="myClip">
   <svg>
       <clipPath id="clipPath">
           <path d="M10,10 q60,60 100,0 q50,50 50,50 l40,0 l-40,40 l-100,-20"/>
       </clipPath>
   </svg>
</div>
```

Then, in your CSS:

```css
.myClip {
   background-color: #1560bd;
   clip-path: url("#clipPath");
}
```

The next image is the result in a modern browser.

![Blue Abstract Shape In Rectangle](https://blog.logrocket.com/wp-content/uploads/2021/06/abstract-shape-rectangle.png)

### `polygon()`

With the `polygon()` value, you can create complex shapes. Here is what we'll do: I will walk you through the process of plotting some shapes on the coordinate system. Afterward, you'll pass these coordinates as parameters to the `polygon()` function in your CSS file.

Here are the shapes we'll cover:

1.  Parallelogram
2.  Downward-facing caret
3.  Pentagon
4.  Diamond

#### Parallelogram

If you would like to create a parallelogram, you'll use the following approximate points in a clockwise manner on the coordinate system:

1.  `x20, y0`
2.  `x80, y0`
3.  `x70, y100`
4.  `x10, y100`
5.  `x20, y0`

![Trapezoid Graphed On A Coordinate System](https://blog.logrocket.com/wp-content/uploads/2021/06/trapezoid-graphed-coordinate-system.jpeg)

I drew this to show you how to locate the points on the coordinate system.

You can customize it when you put the coordinates in the `polygon()` function with one tiny but crucial modification: the percentage sign (%).

```css
.selector {
   background-color: #1560bd;
   clip-path: polygon(20% 0%, 80% 0%, 70% 100%, 10% 100%);
}
```

Below is the result when viewed in a modern web browser.

![Blue Trapezoid In Rectangle With White Padding](https://blog.logrocket.com/wp-content/uploads/2021/06/blue-trapezoid-rectangle.png)

#### Downward-facing caret

Plotting the downward-facing caret is less complicated than a parallelogram. Here are the coordinates:

1.  `x0, y0`
2.  `x100, y0`
3.  `x50, y100`
4.  `x0, y0`

![Downward Triangle Graphed On Coordinate System](https://blog.logrocket.com/wp-content/uploads/2021/06/downward-triangle-graphed-coordinate-system.jpeg)

In CSS:

```css
.selector {
   background-color: #1560bd;
   clip-path: polygon(0% 0%, 100% 0%, 50% 100%);
}
```

The result in a modern browser is shown below.

![Blue Downward Facing Triangle In Rectangle](https://blog.logrocket.com/wp-content/uploads/2021/06/downward-triangle-rectangle.png)

#### Pentagon

![Pentagon Graphed On A Coordinate System](https://blog.logrocket.com/wp-content/uploads/2021/06/pentagon-graphed-coordinate-system.jpeg)

This time, I did not include the coordinates. I'll leave that to you 😇, or, you can check the previous image or the next CSS code block.

The CSS:

```css
.selector {
   background-color: #1560bd;
   clip-path: polygon(50% 0%, 100% 45%, 80% 100%, 20% 100%, 0% 45%);
}
```

In your browser, it should look similar to the image below.

![Blue Pentagon In Rectangle With White Padding](https://blog.logrocket.com/wp-content/uploads/2021/06/blue-pentagon-rectangle.png)

#### Diamond

Hopefully, this is easy for you to do now. Here's what it looks like.

![Diamond Graphed On Coordinate System](https://blog.logrocket.com/wp-content/uploads/2021/06/diamond-graphed-coordinate-system.jpeg) And here's the CSS.

```css
.selector {
   background-color: #1560bd;
   clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%);
}
```

As seen in a modern browser:

![Blue Diamond in Rectangle With White Padding](https://blog.logrocket.com/wp-content/uploads/2021/06/blue-diamond-rectangle.png)

Now, you might ask yourself: what more can I do?

Well, with the `polygon()` function, you are only limited by your imagination 😊.

Now, It's time to create some cool effects by combining animations and CSS `clip-path()`.

## CSS animations and CSS `clip-path()`

When you animate an element, you use `clip-path()` to create a clipping region during the stages of the animation, creating the illusion that the element is indeed changing its shape.

You can clip the element both before and when you animate it.

Let's look at some examples. Throughout this process, you'll write plenty of CSS code, but I'll explain the code for the animation and `clip-path()` property exclusively. The rest are considered cosmetics.

Listed below are the animations you'll create using `clip-path()`.

1.  Infinite circles
2.  Dancing squares
3.  Flipping shapes
4.  Multi-shapes image animation

### Creating infinite circles in CSS

This infinite circle is achieved by passing different values to `circle()` at different stages of the animation. When you add it to the element you wish to animate, you ensure the animation is running at all times.

How is that possible? Because you leverage one of the animation properties, namely `animation-iteration-count`, and specify its value as `infinite`.

Before that, use the following HTML:

```html
<main>
   <div class="circles"></div>
</main>
```

The CSS code is listed in the next code block.

```css
main {
    display: grid;
    place-items: center;
    padding: 2em;
}
​
.circles {
    background: #1a1a1a;
    clip-path: circle(80px at 50% 50%);
    height: 200px;
    width: 200px;
    border-radius: 50%;
    animation-name: infiniteCircle;
    animation-duration: 3s;
    animation-timing-function: ease-in;
    animation-iteration-count: infinite;
}
​
@keyframes infiniteCircle {
    from {
        background: #f00;
        clip-path: circle(50%);
    }
​
    50% {
        background: #ffd700;
        clip-path: circle(35%);
    }
​
    to {
        background: #f0f;
        clip-path: circle(75%);
    }
}
```

The output in a modern browser is depicted in the GIF below.

![Gif Of Growing/Shrinking Color Changing Circle](https://blog.logrocket.com/wp-content/uploads/2021/06/clip-path-growing-circle.gif)

### Dancing squares

The name once again says it all: squares that literally dance. First, plot the initial square on the coordinate system with `polygon()`, then plot varieties of shapes closely related to the square at different stages of the animation.

Finally, make the animation run infinitely. For the HTML, you can use the one from the previous section with a slight modification: change the class name of the `div` inside `main` to `squares`.

The CSS code is below:

```css
main {
   display: grid;
   place-items: center;
   padding: 2em;
}
​
.squares {
    width: 250px;
    height: 250px;
    background-image: linear-gradient(to right, #000000, #e74c3c);
    clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
    animation-name: dancingSquares;
    animation-duration: 4s;
    animation-direction: alternate-reverse;
    animation-iteration-count: infinite;
}
​
@keyframes dancingSquares {
    25% {
        background-image: linear-gradient(to right, #f0c27b, #4b1248);
        clip-path: polygon(20% 0%, 100% 40%, 70% 100%, 10% 100%);
    }
    50% {
        background-image: linear-gradient(to right, #c21500, #ffc500);
        clip-path: polygon(0% 45%, 100% 20%, 50% 75%, 0% 100%);
}

    75% {
        background-image: linear-gradient(to right, #00d2ff, #3a7bd5);
        clip-path: polygon(100% 38%, 100% 38%, 66% 100%, 0% 53%);
   }
}
```

Here's the output as a GIF.

![Gif Of Animating Shapes Changing Into Each Other](https://blog.logrocket.com/wp-content/uploads/2021/06/clip-path-changing-shapes.gif)

### Flipping shapes

The idea behind this animation is to create a shape with `clip-path()` around an element, and afterward, flip it into another shape during the animation stages.

For this example, the element is an image.

Here is the HTML:

```html
<main>
   <img src="path-to-your-image" alt="The image all text" />
</main>
```

And the CSS:

```css
main {
    display: grid;
    place-items: center;
    padding: 2em;
}
​
img {
    width: 600px;
    clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
    animation-name: flippingShapes;
    animation-duration: 3s;
    animation-iteration-count: infinite;
}
​
@keyframes flippingShapes {
    from {
        clip-path: polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%);
    }
​
    50% {
        clip-path: polygon(50% 50%, 90% 88%, 80% 10%, 20% 10%, 8% 90%);
    }

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

The result is shown in the GIF below.

![Snow Leopards With Changing Boarders](https://blog.logrocket.com/wp-content/uploads/2021/06/clip-path-snow-leopards.gif)

### Multi-shape image animation

In this animation, you'll create your desired shape around an element using `clip-path()`. During the animation stages, you'll create more desired shapes.

Finally, when you attach the animation to the element, you set its `animation-iteration-count` to infinite.

You'll use the following HTML:

```html
<main>
    <div class="container">
        <img src="multi.jpg" alt="Two brown Tiger cubs">
    </div>
</main>
```

The CSS is listed in the next code block. Take note that the keywords `from` and `to` are mixed with comma-separated percentage values.

```css
main {
    display: grid;
    place-items: center;
    padding: 2em;
}
​
img {
    max-width: 100%;
}
​
.container {
    width: 30em;
    clip-path: polygon(20% 0%, 80% 0%, 100% 100%, 0% 100%);
    animation-name: changeShapes;
    animation-duration: 5s;
    animation-iteration-count: infinite;
}
​
@keyframes changeShapes {
    from {
        clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
    }

   50% {
        clip-path: polygon(25% 0%, 75% 0%, 100% 50%, 75% 100%, 25% 100%, 0% 50%);
   }

   75% {
      clip-path: polygon(0% 15%, 15% 15%, 15% 0%, 85% 0%, 85% 15%, 100% 15%, 100% 85%, 85% 85%, 85% 100%, 15% 100%, 15% 85%, 0% 85%);
  }
​
to {
      clip-path: polygon(25% 0%, 100% 0%, 75% 100%, 0% 100%);
  }
}
```

The result in a modern browser is illustrated in the next GIF.

![Snow Leopards With Shifting Shapes](https://blog.logrocket.com/wp-content/uploads/2021/06/clip-path-snow-leopards-shifting-shapes.gif)

## Important tips to consider when animating in CSS

### Browser and CPU speed

You likely have access to a high-end system with fast CPU speed, so you may not notice the memory consumption of your animations. Keep in mind your users might have a system with less CPU speed.

This is illustrated in the next GIF. In the GIF, before the animation starts, the CPU utilization of Firefox was `3.3%`, and when the animation runs for 10 seconds, the CPU utilization increases to `24.5%`.

![Inspect Tool Displaying CPU Consumption Of CSS Animations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ca5uh38q4nbwl7p0s5eb.gif)

Please take note of this and do not let your animations run infinitely unless it's absolutely necessary.

### Accessibility

In our examples, we set the `animation-iteration-count` to `infinite`, so the animation will run at all times until you close the active browser window.

However, you should provide a mechanism for your users that would allow them to start and stop the animation at will or limit the animation iteration via `animation-iteration-count`.

### Browser support

Not everyone has access to modern browsers. With this in mind, you should use a tool like [Can I use] (https://caniuse.com/) to confirm the browser support of a CSS property before using them in your projects.

---

## Is your frontend hogging your users' CPU?

As web frontends get increasingly complex, resource-greedy features demand more and more from the browser. If you’re interested in monitoring and tracking client-side CPU usage, memory usage, and more for all of your users in production, [try LogRocket] (https://logrocket.com/signup/).

[![LogRocket Dashboard Free Trial Banner] (https://blog.logrocket.com/wp-content/uploads/2019/12/cpu-memory-usage.png)](https://logrocket.com/signup/)

[LogRocket] (https://logrocket.com/signup/) is like a DVR for web apps, recording everything that happens in your web app or site. Instead of guessing why problems happen, you can aggregate and report on key frontend performance metrics, replay user sessions along with application state, log network requests, and automatically surface all errors.

Modernize how you debug web apps — [Start monitoring for free] (https://logrocket.com/signup/).