CSS Art – Using the CSS shape() Function to Make Advanced Shapes: Heart, Crosses, Arcs, and Smooth Curves

Want to take your image creation skills to the next level? This step-by-step article will show you how to use the CSS shape() to create complex shapes.

CSS Art – Using the CSS shape() Function to Make Advanced Shapes: Heart, Crosses, Arcs, and Smooth Curves
Photo by engin akyurt / Unsplash

Introduction

Once you have a solid understanding of the basics, it’s time to learn how to create advanced shapes.

In this article, you will discover how to use the CSS shape() function to create hearts, crosses, as well as quadratic and cubic curves. By combining different shape() commands and parameters, you’ll learn how to create complex and sophisticated images.

CSS properties and functions you’ll be exploring in this article.

  • clip-path
  • shape()

Preview

By combining multiple shape() function commands, you can create complex shapes like hearts and crosses.

Preview - Heart
Preview - Heart
Preview - Cross
Preview - Cross

Prerequisites

Essential CSS and HTML knowledge will help you understand the concepts and techniques introduced in this article. Jump over to this article if you require an HTML and CSS primer.

We assume you have configured tools to modify CSS. If not, this article will guide you through the setup process.

HTML Structure

<div class="container">
  <div class="cross"></div>
</div>
<div class="container">
  <div class="quad-curve"></div>
</div>
<div class="container">
  <div class="cubic-curve"></div>
</div>
<div class="container">
  <div class="smooth-curve"></div>
</div>
<div class="container">
  <div class="heart"></div>
</div>

container is the outermost enclosure. It enables the content to be centered and draws a light gray border. The rest of the <div>s represent each image component.

Keep the HTML structure as is for the image to display correctly.

Body and Container <div> CSS

CSS code for the body and container <div>.

/* Body and Container Settings */
/* Center shapes */
body {
  margin: 0;
  padding: 0;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: wrap;
}

/* Set blue background and light gray border */
.container {
  min-width: 500px;
  height: 500px;
  border: 5px solid lightgray;
  background: white;
  position: relative;
  margin: 5px;
  display: flex;
  justify-content: center;
  align-items: center;
}

Common Properties

Common properties are combined to ensure minimal code size.

/* Common Properties */
.cross,
.quad-curve,
.cubic-curve,
.smooth-curve,
.heart {
  width: 500px;
  height: 500px;
  background: #085bb5;
}

The width and height properties are both set to 500px. The shape’s background color is set to a blue shade, #085bb5.

shape() Function <curve-command> and <smooth-command>

The shape() function <curve-command> and <smooth-command> can both be used to create a Bézier curve.

<curve-command>

Syntax: curve [by | to] <coordinate-pair> with <coordinate-pair> [/ <coordinate-pair>].

  • Using the by or to keyword tells us whether the end point of the curve, set by the first <coordinate-pair>, is relative or absolute, respectively. The with keyword defines the control points for the Bézier curve.
  • When only one <coordinate-pair> is given, the command creates a quadratic Bézier curve, which is defined by three points: the start point, the control point, and the end point.
  • When two <coordinate-pair> values are given, the command creates a cubic Bézier curve, which is determined by four points: the starting point, two control points, and the ending point.

<smooth-command>

Smooth curves allow for a continuous transition from the shape, whereas quadratic curves don’t. Quadratic curves use a single control point to create a seamless transition, while smooth cubic curves use two control points for a more refined transition.

Syntax: smooth [by | to] <coordinate-pair> [with <coordinate-pair>]

  • Using the by or to keyword decides whether the curve's ending point, defined by the first <coordinate-pair>, is relative or absolute.
  • When <coordinate-pair> is left out, the command draws a smooth quadratic Bézier curve that’s defined by the previous control point and the current endpoint.
  • When the optional with keyword is used, it defines the control points of the curve through <coordinate-pair>, creating a smooth cubic Bézier curve based on the previous control point, the current control point, and the current endpoint.

Check this article out to get familiar with other shape() function parameters and commands.

CSS Art – Using the CSS shape() Function to Make Basic Shapes: Squares, Rectangles, Circles, Ellipses, and Triangles
Creating art is all about the basics. Learn how to make triangles, ellipses, and much more using the CSS shape() in this step-by-step article.

Let’s start working on the first advanced shape, a cross, in the next section.

Cross

The cross can be made using the shape() with both the <hv-line-command> and the <line-command>. For this example, we’ll be utilizing the latter command. Interchanging horizontal and vertical will be used to create the cross.

Cross
Cross
.cross {
  clip-path: shape(
    from 170px 30px,
    line to 305px 30px,
    line to 305px 175px,
    line to 450px 175px,
    line to 450px 320px,
    line to 305px 320px,
    line to 305px 465px,
    line to 170px 465px,
    line to 170px 320px,
    line to 35px 320px,
    line to 35px 175px,
    line to 170px 175px,
    close
  );
}

The <line-command> requires two coordinates, an x or horizontal coordinate and a y or vertical coordinate.

  1. from 170px 30px sets the starting coordinates at 170px from the left edge and 30px from the top.
  2. A horizontal line is drawn using line to 305px 30px from the starting point to point 2.
  3. Downward line drawn to point 3 with line to 305px 175px.
  4. A line going to the right drawn by line to 450px 175px. You’re at point 4 now.
  5. line to 450px 320px draws a downward line to point 5.
  6. Use line to 305px 320px to draw a leftward line to point 6.
  7. A horizontal line is drawn using line to 305px 465px to point 7. This completes the right side of the cross.
  8. Draw a horizontal line from point 7 to point 8 using line to 170px 465px.
  9. line to 170px 320px draws a vertical line to point 9.
  10. To get to point 10, draw a horizontal line using line to 35px 320px.
  11. line to 35px 175px draws a vertical line to point 11.
  12. line to 170px 175px draws a horizontal line to point 12.
  13. close draws a line back to the starting point, closing the cross shape.
Cross - Detailed Information
Cross - Detailed Information

Let’s start working on curves in the next section.

Quadratic Curve

The quadratic curve example uses the shape() function <curve-command>.

Quadratic Curve
Quadratic Curve
.quad-curve {
  width: 500px;
  height: 500px;
  clip-path: shape(
    from 40px 350px,
    curve to 460px 350px with 250px 10px,
    close
  );
}

from 40px 350px sets the starting point: 40px from the left edge and 350px from the top. The ending point is specified using curve to 460px 350px. The control point is set to 250px on the horizontal axis, and 10px on the vertical axis using with 250px 10px. You can control the height and angle of the quadratic curve by adjusting the control point coordinates.

Up next is the cubic curve.

Cubic Curve

What sets the cubic curve apart from the quadratic curve in the previous section is the number of control points used. Unlike the quadratic curve, which uses three control points, the cubic curve requires four.

Cubic Curve
Cubic Curve
.cubic-curve {
  clip-path: shape(
    from 40px 350px,
    curve to 460px 350px with 40px 10px / 460px 10px,
    close
  );
}
  • The starting point is set to 40px from the left side and 350px from the top using from 40px 350px.
  • curve to 460px 350px sets the end point at 460px on the horizontal axis and 350px on the vertical axis.
  • The first control point is set to 40px 10px.
  • 460px 10px sets the second control point.

Let’s work on the smooth curve in the next section.

Smooth Curve

With the <smooth-command>, you can make a smooth transition between two shapes.

Smooth Curve
Smooth Curve
.smooth-curve {
  clip-path: shape(
    from 30px 200px,
    smooth to 140px 75px with 85px 10px,
    smooth to 450px 200px with 300px 600px,
    close
  );
}

You first set the starting point with from 30px 200px. The first smooth command ends at 140px 75px with a control point set by with 85px 10px. The second smooth has a control point set using with 300px 600px and an endpoint set to 450px 200px.

Check this article out for a visual representation of the control points.

CSS Art – How to Make Vector Shapes with path()
Make basic and advanced shapes with CSS path() function and Scalable Vector Graphics (SVGs). Find out how in this step-by-step article.

Next up is the heart, which is our final shape for this article. Let’s move on to the final section.

Heart

Both the arc-command and the curve-command are used together to create the heart shape.

Heart
Heart
.heart {
  clip-path: shape(
    from 20px 140px,
    arc to 250px 140px of 40px cw,
    arc to 480px 140px of 40px cw,
    curve to 250px 460px with 480px,
    curve to 20px 140px with 20px,
    close
  );
}
  • from 20px 140px sets the starting point.
  • arc to 250px 140px of 40px cw creates the first arch. The arch end point is set to 250px 140px, with its peak set to 40px and rotates clockwise with cw.
  • The second arch is created using arc to 480px 140px of 40px cw.
  • curve to 250px 460px with 480px make a quadratic curve from the second arch end point to the 250px 460px with a control point set at 480px.
  • To finish the heart shape, another quadratic curve is set to end at 20px 140px with a control point set to 20px.

You can see and play with the complete code on Pyxofy’s CodePen page.

See the Pen CSS Art – Using the CSS shape() Function to Make Advanced Shapes: Heart, Crosses, Arcs, and Smooth Curves by Pyxofy (@pyxofy) on CodePen.

Conclusion

The examples in this article demonstrate the image creation capabilities of the CSS shape() function. By combining multiple shape() parameters and commands, you can create advanced shapes like hearts, crosses, and smooth curves.

shape() curves are versatile, allowing you to create both quadratic and cubic Bézier curves with control points. By combining arc and curve commands, you can produce fluid, organic shapes.

What exciting, complex, or advanced shapes and images will you create with the CSS shape() function? Share your masterpiece with us on LinkedIn, Threads, Bluesky, Mastodon, X (Twitter) @pyxofy, or Facebook.

We hope you liked this article. Kindly share it with your network. We appreciate it.

CSS Art – Koinobori Carp Streamer – Part 1
Koi carp represents courage and determination in the Land of the Rising Sun. Join us in creating the symbolic Koinobori step-by-step using CSS.
CSS Animation – Horizontal and Vertical Movement
How can we move shapes from left to right, top to bottom on the internet? Let’s find out how in this step-by-step CSS animation article.
スクラッチプログラミング - コントローラーでそうさするシューティングゲーム
プロジェクトの中にコントローラーをつくってあそぶシューティングゲームをしょうかいします。スプライトでコントローラーをつくれば、パソコンだけでなくキーボードのないタブレットでもそうさできるようになりますよ。
JavaScript - 背景色を変更する方法 - 配列からランダムに色を選ぶには?
JavaScript で要素のスタイルを変更する方法を学びましょう。ユーザーのクリックで背景色を変えるコードを、基本と応用に分けて解説します。プログラミング初心者の方や、配列や乱数について知りたい方におすすめの内容となっています。