skip navigation

Clip Path

The CSS clip-path property is used to create a shape which removes part of the HTML element it’s applied to.

For example a simple div with the following CSS:

div {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}

This draws a box around the div element. It starts in the top left corner then goes to the top right then bottom right and finally bottom left.

If the order is different we get a different result, even though the coordinates are the same. Here the only difference is that last two coordinates are switched around:

div {
    clip-path: polygon(0 0, 100% 0, 0 100%, 100% 100%);
}

Making a diagonal section

The next paragraph uses the following CSS:

p {
    clip-path: polygon(0 0, 100% 20%, 100% 100%, 0 80%);
    padding: 5em 2.5em;
}

As clip path removes part of your element you generally need to add some padding if the element contains text:

This is a paragraph which is clipped by changing the coordinates and adding some padding.

You can make many kinds of shapes. The clip-path property takes a variety of values.

Picsum image Picsum image Picsum image

Basic shapes include:

Value example What it does
circle circle(50% at 50% 25%) The first figure is the radius and the second pair the coordinates of it’s center. If you don’t specify either, circle(), then it defaults to a 50% radius from the center or 50% at 50% 50%
ellipse ellipse() With nothing defined the shape defaults an ellipse shaped around the container. For more info see MDN
path path("M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80") These are best created using software.
url The path to an SVG

You can create shapes out of any element.

transitions transforms

Creating paths

There are various tools like Clippy where you can use premade shapes or create your own (see sidebar)

You can edit a clip-path in Firefox’s dev tools.

Create a path in image program, export as an SVG. You can then use the SVG directly using the url() value, or use the path defined in it directly using path()

shape-outside

You can also create a shape outside an element around which text flows.

picsum photo cb7 Lorem ipsum dolor sit amet consectetur, adipisicing elit. Consequatur sapiente ullam id obcaecati cupiditate tempore eos ducimus deleniti aspernatur nisi in vel eveniet voluptates necessitatibus doloribus asperiores laboriosam quas, incidunt laudantium? Perferendis iusto ab nam, quisquam quidem sunt, deserunt incidunt iste, numquam porro aut exercitationem molestiae reprehenderit? Dicta, ab minus ipsum velit, rerum perferendis vel, dolor consectetur in fugit voluptas? Iste harum qui error minima!

The above uses the following CSS:

img {
    clip-path: circle();
    shape-outside: circle();
    margin-right: 10px;
    shape-margin: 0.5em;
    float: left;
}
View the CSS for this page
:root {
    --clipbox: #0005;
}


.clip-box {
    width: min(250px, 100%);
    aspect-ratio: 1 / 1;
    background-color: var(--clipbox);
    }
.cb1 {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
}
.cb2 {
    clip-path: polygon(0 0, 100% 0, 0 100%, 100% 100%);
}
.cb3 {
    background-color: var(--clipbox);
    clip-path: polygon(0 0, 100% 20%, 100% 100%, 0 80%);
    padding: 5em 2.5em;
}

.cb4 {
    display: flex;
    flex-wrap: wrap;
    gap: 1em;
}
.cb4 img:first-of-type {
    clip-path: circle();
}
.cb4 img:nth-of-type(2) {
    clip-path: polygon(30% 0%, 70% 0%, 100% 30%, 100% 70%, 70% 100%, 30% 100%, 0% 70%, 0% 30%);
    height: auto;
}
.cb4 img:nth-of-type(3) {
    clip-path: ellipse();
}

.cb4 img:nth-of-type(3)::before {
    content: 'ellipse';
    font-size: 3em;
    color: red;
}

.arrows {
    margin-block: 4em;
    display: flex;
    gap: 4em;
    justify-content: center;
}

.arrows a {
    color: #18181889;
background-color: #FBAB7E;
background-image: linear-gradient(62deg, #FBAB7E 0%, #F7CE68 100%);
text-transform: uppercase;
font-weight: bold;
}
.arrows a:hover {
    color: #181818;
    background-image: linear-gradient(62deg, #f88c4d 0%, #f5b920 100%);
}
.arrows a:first-of-type {
    padding: 2em 1em 2em 5em;
    clip-path: polygon(40% 0%, 40% 20%, 100% 20%, 100% 80%, 40% 80%, 40% 100%, 0% 50%);
}
.arrows a:last-of-type {
    padding: 2em 5em 2em 1em;
    clip-path: polygon(0% 20%, 60% 20%, 60% 0%, 100% 50%, 60% 100%, 60% 80%, 0% 80%);
}

.cb7 img {
    clip-path: circle();
    shape-outside: circle();
    margin-right: 10px;
    shape-margin: 0.5em;
    float: left;
}