The Story Behind TryShape, a Showcase for the CSS clip-path property

I love shapes, especially colorful ones! Shapes on websites are in the same category of helpfulness as background colors, images, banners, section separators, artwork, and many more: they can help us understand context and inform our actions through affordances.
A few months back, I built an application to engage my 7-year old daughter with mathematics. Apart from basic addition and subtraction, my aim was to present questions using shapes. That’s when I got familiar with the CSS clip-path property, a reliable way to make shapes on the web. Then, I ended up building another app called, TryShape using the power of clip-path.

I’ll walk you through the story behind TryShape and how it helps create, manage, share, and export shapes. We’ll cover a lot about CSS clip-path along the way and how it helped me quickly build the app.
Here are a few important links:
First, the CSS clip-path property and shapes
Imagine you have a plain piece of paper and a pencil to draw a shape (say, a square) on it. How will you proceed? Most likely, you will start from a point, then draw a line to reach another point, then repeat it exact three more times to come back to the initial point. You also have to make sure you have opposite lines parallel and of the same length.
So, the essential ingredients for a shape are points, lines, directions, curves, angles, and lengths, among many others. The CSS clip-path helps specify many of these properties to clip a region of an HTML element to show a specific region. The part that is inside the clipped region is shown, and the rest is hidden. It gives an ocean of opportunities to developers to create various shapes using clip-path property.
Learn more about clipping and how it is different from masking.
The clip-path values for shape creation
The clip-path property accepts the following values for creating shapes:
circle()ellipse()inset()polygon()A clip source using url() functionpath()We need to understand the basic coordinate system a bit to use these values. When applying the clip-path property on an element to create shapes, we must consider the x-axis, y-axis, and the initial coordinates (0,0) at the element’s top-left corner.
Here is a div element with its x-axis, y-axis, and initial coordinates (0,0).
Initial coordinates(0,0) with x-axis and y-axisNow let’s use the circle() value to create a circular shape. We can specify the position and radius of the circle using this value. For example, to clip a circular shape at the coordinate position (70, 70) with a radius of 70px, we can specify the clip-path property value as:
clip-path: circle(70px at 70px 70px)
So, the center of the circle is placed at the coordinate (70, 70) with a 70px radius. Now, only this circular region is clipped and shown on the element. The rest of the portion of the element is hidden to create the impression of a circle shape.
The center of the circle is placed at (70, 70) coordinates with a 70px x 70px area clipped. Hence the full circle is shown.Next, what if we want to specify the position at (0,0)? In this case, the circle’s center is placed at the (0,0) position with a radius of 70px. That makes only a portion of the circle visible inside the element.
The center of the circle is placed at (0, 0) coordinates with a 70px x 70px area clipping the bottom-left region of the circle. Let’s move on to use the other two essential values, inset() and polygon(). We use an inset to define a rectangular shape. We can specify the gap that each of the four edges may have to clip a region from an element. For example:
clip-path: inset(30px)
The above clip-path value clips a region by leaving out the 30px values from element’s edges. We can see that in the image below. We can also specify a different inset value for each of the edges.
The inset() function allows us to clip and area from the outside edge of a shape.Next is the polygon() value. We can create a polygonal shape using a set of vertices. Take this example:
clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 80%)
Here we are specifying a set of vertices to create a region for clipping. The image below shows the position of each vertex to create a polygonal shape. We can specify as many vertices as we want.
The polygon() function allows us to create polygonal shapes using the set of vertices passed to it.Next, let’s take a look at the ellipse() and the url() values. The ellipse() value helps create shapes by specifying two radii values and a position. In the image below, we see an ellipse at the position where the radii is at (50%,50%) and the shape is 70px wide and 100px tall.
We need to specify two radii values and a position to create an ellipse.url() is a CSS function to specify the clip-path element’s ID value to render an SVG shape. Please take a look at the image below. We have defined a SVG shape using clipPath and path elements. You can use the ID value of the clipPath element as an argument to the url() function to render this shape.
Here, we are creating a heart shape using the url() functionAdditionally, we can use the path values directly in the path() function to draw the shape.
Here we are creating a curvy shape using the path() function.Alright. I hope you have got an understanding of different clip-path property values. With this understanding, let’s take a loot at some implementations and play around with them. Here is a Pen for you. Please use it to try adding, modifying values to create a new shape.
CodePen Embed Fallback
Let’s talk about TryShape
It’s time to talk about TryShape and its background story. TryShape is an open-source application that helps create, export, share, and use any shapes of your choice. You can create banners, circles, arts, polygons and export them as SVG, PNG, and JPEG files. You can also create a CSS code snippet to copy and use in your application.
TryShape is built using the following framework and libraries (and clip-path, of course):
CSS clip-path: We’ve already discussed the power of this awesome CSS property.Next.js: The coolest React-based framework around. It helped me create pages, components, interactions, and APIs to connect to the back-end database.HarperDB: A flexible database to store data and query them using both SQL and No-SQL interactions. TryShape has its schema and tables created in the HarperDB cloud. The Next.js APIs interact with the schema and tables to perform required CRUD operations from the user interface.Firebase: Authentication services from Google. TryShape uses it to get the social login working using Google, GitHub, Twitter, and other accounts.react-icons: One shop for all the icons for a React-based applicationdate-fns: The modern, lightweight library for date formattingaxios: Making the API calls easy from the React componentsstyled-components: A structured way to create CSS rules from react componentsreact-clip-path: A homegrown module to handle clip-path property in a React appreact-draggable: Make an HTML element draggable in a React app. TryShape uses it to adjust the position of shape vertices.downloadjs: Trigger a download from JavaScripthtml-to-image: Converts an HTML element to image (including SVG, JPEG, and PNG)Vercel: Best for hosting a Next.js appCreating shapes in TryShape using CSS clip-path
Let me highlight the source code that helps create a shape using the CSS clip-path property. The code snippet below defines the user interface structure for a container element (Box) that’s 300px square. The Box element has two child elements, Shadow and Component.
props.shapeInformation.showShadow &&


The Shadow component defines the area that is hidden by the clip-path clipping. We create it to show a light color background to make this area partially visible to the end user. The Component is to assign the clip-path value to show the clipped area.
See the styled-component definitions of Box, Shadow, and Component below:
// The styled-components code to create the UI components using CSS properties

// The container div
const Box = styled.div`
width: ${props => props.width || ‘100px’};
height: ${props => props.height || ‘100px’};
margin: 0 auto;
position: relative;

// Shadow defines the area that is hidden by the `clip-path` clipping
// We show a light color background to make this area partially visible.
const Shadow = styled.div`
background-color: ${props => props.backgroundColor || ‘#00c4ff’};
opacity: 0.25;
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;

// The actual component that takes the `clip-path` value (formula) and set
// to the `clip-path` property.
const Component = styled.div`
clip-path: ${props => props.formula}; // the formula is the clip-path value
background-color: ${props => props.backgroundColor || ‘#00c4ff’};
position: absolute;
top: 10px;
left: 10px;
right: 10px;
bottom: 10px;
The components to show a shape(both visible and hidden areas) after the clipping.Please feel free to look into the entire codebase in the GitHub repo.
The future scope of TryShape
TryShape works well with the creation and management of basic shapes using CSS clip-path in the background. It is helpful to export the shapes and the CSS code snippets to use in your web applications. It has the potential to grow with many more valuable features. The primary one will be the ability to create shapes with curvy edges.
To support the curvy shapes, we need the support of the following values in TryShape:
a clip source using url() andpath().With the help of these values, we can create shapes using SVG and then use one of the above values. Here is an example of the url() CSS function to create a shape using the SVG support.


Then, the CSS::
.heart {
clip-path: url(#heart-path);
Now, let’s create a shape using the path() value. The HTML should have an element like a div:


.curve {
clip-path: path(“M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80”);
Before we end…
I hope you enjoyed meeting my TryShape app and learning about the idea that leads to it, the strategies I considered, the technology under the hood, and its future potential. Please consider trying it and looking through the source code. And, of course, feel free to contribute to it with issues, feature requests, and code.
Before we end, I want to leave you with this short video prepared for the Hashnode hackathon where TryShape was an entry and finally in the list of winners. I hope you enjoy it.

Let’s connect. You can @ me on Twitter (@tapasadhikary) with comments, or feel free to follow.

Typed at

Share your love

Leave a Reply