CSS Shapes: The Ribbon

Written by Web Developer

September 16, 2023
CSS Shapes: The Ribbon

After the Heart Shape, let’s tackle another famous CSS shape; The Ribbon. I can hear you saying: “Why another article about CSS ribbon!?”. In this one, I will consider modern CSS tricks to create not one but a lot of ribbon shapes with the smallest code possible. In fact, the HTML code will be as simple as:

<div class="ribbon">I am a ribbon</div>

A single element is all that is needed to create different ribbon shapes. You can find all of them in one place and easily copy/paste the code: css-generators.com/ribbon-shapes

In this article, we will explore some of them to understand the CSS tricks used to create such shapes.

Overview of the CSS Ribbon shapes

I will consider three categories for the ribbon: The full ribbon (the top one on the figure above), the ribbons on the corners, and the ones on the sides. The goal is to provide a CSS code that we can easily adjust to control the ribbon shape and also make sure the shape fits its content. We are not going to use any magic number of fixed dimensions. The size will be based on the text inside the ribbon.

50%

💰 50% OFF YOUR FIRST MONTH ON MANAGED CLOUD SERVERS

with the discount code

SERVERS-SALE

Use Code Now

The Full Ribbon

Let’s start with our first ribbon. Below is a figure to illustrate the different variables that will control the shape:

Overview of the CSS variables

We define them using CSS variables

.ribbon {
  --s: 50px; /* the ribbon size */
  --d: 20px; /* the depth */
  --c: 25px; /* the cutout part */
}

Now the trick is to rely on clip-path and CSS gradients to build the shape. You are probably thinking we are going to use pseudo-elements and a lot of CSS code but no. Two properties will do the job.

We first apply the gradients:

background:
  conic-gradient(at left  var(--s) bottom var(--d),
   #0000 25%,#0008 0 37.5%,#0004 0) 0   /50% no-repeat,
  conic-gradient(at right var(--s) bottom var(--d),
   #0004 62.5%,#0008 0 75%,#0000 0) 100%/50% no-repeat;
background-color: #CC333F
Overview of the gradients configuration

Each gradient covers half the area and is made with three different colors. A transparent one (#0000) and two semi-transparent ones. By defining a background-color behind the gradients we create the different shades of colors for our ribbon. Updating the color is as simple as changing the background-color.

The last step is to apply the clip-path. This will probably look a bit complex at first glance because the value is a bit verbose but if you follow the polygon point by point, it becomes easy.

.ribbon {
  clip-path: polygon(0 var(--d), var(--s) var(--d),var(--s) 0,calc(100% - var(--s)) 0,calc(100% - var(--s)) var(--d),100% var(--d),calc(100% - var(--c)) calc(50% + var(--d)/2),100% 100%,calc(100% - var(--s) - var(--d)) 100%,calc(100% - var(--s) - var(--d)) calc(100% - var(--d)),calc(var(--s) + var(--d)) calc(100% - var(--d)),calc(var(--s) + var(--d)) 100%,0 100%,var(--c) calc(50% + var(--d)/2))
}

Here is a figure to illustrate some of the points.

The clip-path polygon

You can refer to my article "CSS Tricks To Master The clip-path Property" to better understand the coordinates and how the shape's symmetry can help you easily find most of the values.

It’s done! We have a nice ribbon and all you have to do is update a few variables to easily control the shape:

.ribbon {
  --s: 50px; /* the ribbon size */
  --d: 20px; /* the depth */
  --c: 20px; /* the cutout part */
  
  padding: 0 calc(var(--s) + var(--d)) var(--d); /* we need some padding so the text doesn't overlap the ribbon part */
  background:
    conic-gradient(at left  var(--s) bottom var(--d),
     #0000 25%,#0008 0 37.5%,#0004 0) 0   /50% no-repeat,
    conic-gradient(at right var(--s) bottom var(--d),
     #0004 62.5%,#0008 0 75%,#0000 0) 100%/50% no-repeat;
  clip-path: polygon(0 var(--d), var(--s) var(--d),var(--s) 0,calc(100% - var(--s)) 0,calc(100% - var(--s)) var(--d),100% var(--d),calc(100% - var(--c)) calc(50% + var(--d)/2),100% 100%,calc(100% - var(--s) - var(--d)) 100%,calc(100% - var(--s) - var(--d)) calc(100% - var(--d)),calc(var(--s) + var(--d)) calc(100% - var(--d)),calc(var(--s) + var(--d)) 100%,0 100%,var(--c) calc(50% + var(--d)/2));
  background-color: #CC333F; /* the main color */
  width: fit-content; 
}

90%

💸 90% OFF YOUR FIRST MONTH WITH ALL VERPEX SHARED WEB HOSTING PLANS

with the discount code

MOVEME

Save Now

The Corner Ribbon

This ribbon shape is easier than the previous one because we have only one variable to control the shape and no complex gradient configuration.

Corner Ribbon Shape

We first define the background color and we apply a border at the bottom with a semi-transparent color to get a different shade from the main color and simulate the folded part.

.ribbon {
  --f: 15px; /* control the folded part */
  
  background: var(--c,#45ADA8);
  border-bottom: var(--f) solid #0007;
}

Then we apply the clip-path

.ribbon {
  clip-path: polygon(100% calc(100% - var(--f)),100% 100%,calc(100% - var(--f)) calc(100% - var(--f)),var(--f) calc(100% - var(--f)), 0 100%,0 calc(100% - var(--f)),999px calc(100% - var(--f) - 999px),calc(100% - 999px) calc(100% - var(--f) - 999px))
}

Most of the points should be easy to understand but two of them are a bit trick. the 999px calc(100% - var(--f) - 999px) and calc(100% - 999px) calc(100% - var(--f) - 999px). I have to cut the shape of an isosceles triangle on each side but to do this I need to know the height of the element. I don't have this information since the height depends on the content and we don't want to set a fixed dimension.

The trick is to rely on a big value that should be bigger than any height we may encounter. I am using 999px but it can be smaller since a ribbon won’t be that tall.

Cutting the corner of the ribbon shape

Finally, we rotate the ribbon either by 45deg or -45deg depending on the position we want. Such ribbon is generally placed on the corner of a container so in addition to the rotation we need to also consider some positioning to correctly place the ribbon:

.ribbon {
  position: absolute;
  top: 0;
}
.right {
  right: 0;
  transform: translate(calc((1 - cos(45deg))*100%), -100%) rotate(45deg);
  transform-origin: 0% 100%; /* bottom left */
}
.left {
  left: 0;
  transform: translate(calc((cos(45deg) - 1)*100%), -100%) rotate(-45deg);
  transform-origin: 100% 100%; /* bottom right */
}

Two more ribbon shapes straight into the collection!

The Side Ribbon

I suppose you get the main concept by now. All the ribbons use the same code structure and this one is not an exception.

The side ribbon shapes

We first apply a bottom border for the folded part and a left border to have enough space for the cutout. Then we use clip-path to create the final shape.

.ribbon {
  --f: 15px; /* control the folded part*/
  --r: 20px; /* control the ribbon shape */
  
  position: absolute;
  background: #FA6900;
  border-bottom: var(--f) solid #0005;
  border-left: var(--r) solid #0000;
  clip-path: 
    polygon(0 0,100% 0,100% calc(100% - var(--f)),calc(100% - var(--f)) 100%,
      calc(100% - var(--f)) calc(100% - var(--f)),0 calc(100% - var(--f)),
      var(--r) calc(50% - var(--f)/2));
  right: calc(-1*var(--f));
}

What about the other sides?

They follow the same idea with small updates to the code. In the above demo, I am showing the left side and the right side version but I let you try to figure out how to create the top side version. You can still find all of them here: css-generators.com/ribbon-shapes

90%

💸 90% OFF YOUR FIRST MONTH WITH ALL VERPEX HOSTING PLANS FOR WORDPRESS

with the discount code

MOVEME

Grab the Discount

Conclusion

Using clip-path and a few CSS properties, we were able to create different kinds of ribbon shapes. We can easily control them by adjusting CSS variables not to mention that their size is defined by their content. You can even have multi-line of text and the ribbon will adjust accordingly.

Defining the clip-path polygon is probably the trickiest part and it can be difficult to understand at first glance. Take the time to study each polygon of each example point by point and check my other article to learn more tricks around clip-path. It also helps to use a pen and paper and draw them by hand.

Don’t forget that I made a collection of different ribbon shapes from where you can easily copy the code. This gives you more examples to study and get familiar with clip-path and other properties.

Frequently Asked Questions

Are website builders easy to use?

One of the easiest ways to build a website is with a website builder. Using a website builder doesn't require any programming and coding skills.

Why should I create a website?

There are many reasons why you should create a website if you’re an artist. You can use it to create a place where people can learn about you, talk about your art, or show off your work.

Should I build my website with PHP?

PHP's flexibility and ease of integration with various databases like MySQL and PostgreSQL make it ideal for creating dynamic, data-driven websites.

How do I make my website HTTPS?

To enable HTTPS for your domain, you must install an SSL or TLS certificate on your website. You can get this certificate through your web host, or you can obtain it from a Certificate Authority and install it yourself.

Discount

Enter Discount Code MOVEME During The SIGN UP Process To Get 90% Off Your First Month

with the discount code

MOVEME

Use Code Now
Jivo Live Chat