How to Create CSS Ribbon Shapes with a Single Element — SitePoint

Key Takeaways

  • CSS ribbon shapes could possibly be created using trendy CSS suggestions, with minimal code, relying solely on a single side and CSS variables for easy administration, with out the need for mounted dimensions or magic numbers.
  • The creation of CSS ribbon shapes consists of defining variables to handle the shape and shade, using clip-path to cut the required type, and using box-shadow to create a folded part of the ribbon.
  • The CSS lh unit, which corresponds to the line-height value, is used to handle the height of the ribbon, and it might be utilized in combination with clip-path and a CSS variable to create a pleasing hover animation.
  • The creation of a rotated CSS ribbon type consists of utilizing new trigonometric capabilities along with CSS variables and calc(), using a gradient coloration to cut parts of the precept side, and using pseudo-elements to create parts behind the precept side.

On this text, I’ll current you straightforward strategies to make use of trendy CSS tricks to create fancy CSS ribbon shapes with minimal code. As a further bonus, our ribbons may have hover animations!

CSS ribbons are in all places, and you’ll uncover a ton of articles about them, nonetheless those we’ll create listed below are a bit explicit. We’re going to depend upon a single side to create each of the shapes, and CSS variables to easily administration them. We aren’t going to depend upon mounted dimensions or magic numbers. The shapes will match their content material materials so that you simply don’t have to stress regarding the textual content material inside.

I’ve made a gaggle of CSS ribbon shapes with plenty of cool examples, and on this text, we’re going to evaluate two sorts of them, pictured beneath.

How to Create CSS Ribbon Shapes with a Single Element — SitePoint

I’ll be calling the left one the “folded ribbon” and the most effective one the “rotated ribbon”.

Making a CSS Folded Ribbon Kind

The 1st step in creating our folded CSS ribbon is to stipulate the variables of our type.

Naming parts of our ribbon shape: r for the depth of the front arrow and end cutout, and s for the height of the fold

.ribbon {
  --r: 20px; 
  --s: 20px; 
  --c: #d81a14;
}

Two variables will administration the shape, and one variable will administration the color.

Now let’s switch to the code. We’re primarily going to depend upon clip-path. The image beneath illustrates the polygon type we’re going to utilize.

The rectangle ribbon clipped at both ends

We add some padding to steer clear of chopping the textual content material, then we apply the clip-path:

.ribbon {
  --r: 20px; 
  --s: 20px; 
  --c: #d81a14;

  line-height: 1.6; 
  padding-inline: 1.2lh calc(var(--r) + .2lh);
  background: var(--c);
  clip-path: polygon(1lh 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,100% 100%, 0 100%,0 100%); 
}

Using the CSS lh unit

You may be questioning what’s occurring with the lh unit. It’s a model new unit that corresponds to the line-height value. Since we’re using one line of textual content material, the line-height setting is what controls the height, so 1lh is the same as the height of the side, which is great useful. (You could be taught additional regarding the lh unit in An Overview of CSS Sizing Objects.)

In clip-pathI need to chop the type of an isosceles triangle, and to do this I need to know the height of the side. 1lh is similar as that high.

A corner triangle with sides measuring 1lh

Now, to create the folded half, we’re nonetheless going to utilize clip-path and substitute the sooner polygon. The cool issue about clip-path is that it may decrease “outside” the boundaries of the side. It would sound beautiful or presumably ineffective, supplied that now we now have nothing outside, nevertheless it certainly means we’re capable of embrace points like box-shadow, outline, pseudo-elements, and so forth.

In our case, we’ll depend upon box-shadow. The image beneath illustrates the trick.

A half-circle shadow underneath the pointy end of the ribbon

Bear in mind how I’m updating the clip-path to include 4 new components, three of which can be outside the side. Given that half we’re chopping is outside, it’s not seen, however after we add an unlimited box-shadow we make if seen. I’ve used a blue shade for instance the idea above, nonetheless inside the code we’ll use the similar shade as a result of the background:

.ribbon {
  --r: 20px; 
  --s: 20px; 
  --c: #d81a14;

  line-height: 1.6; 
  padding-inline: 1.2lh calc(var(--r) + .2lh);
  background: var(--c);
  clip-path: polygon(1lh 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,1lh 100%,1lh calc(100% + var(--s)),.5lh calc(100% + var(--s) + var(--r)),0 calc(100% + var(--s)),0 100%);
  box-shadow: 0 0 0 999px var(--c); 
}

Lastly, we add a contact of shadow affect by introducing a gradient and one different box-shadow and we’re completed. Our CSS ribbon type is right!

You’re most likely questioning straightforward strategies to create the second ribbon (the inexperienced one). We do the similar issue nonetheless with a definite polygon. We take the first polygon and we invert it.

A polygon could possibly be written like so:

clip-path: polygon(X1 Y1, X2 Y2, ..., Xn Yn)

To get the choice type, you modify all Xi by 100% - Xi. As simple as that! Sooner than checking my code, try to do it alone using the polygon of the first ribbon.

Inside the demo above, hover the shapes to notice a pleasing animation. To realize it, we now have to interchange the polygon on hover by offsetting some components. I gained’t re-write your complete polygon on hover, nonetheless I am going to define a CSS variable that may administration the offset.

In the event you occur to provide consideration to the animation, you’ll uncover that now we now have three components transferring to the left and three components transferring down and to the left as correctly.

Arrows showing the points of the polygon and the direction in which they move

We substitute the Xi of the components transferring to left with Xi + d and we substitute the Yi of the components transferring doing with Yi + d. Then we merely substitute the variable d to handle the movement:

.ribbon {
  --d: 0px; 
  clip-path: polygon(calc(1lh + var(--d)) 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,calc(1lh + var(--d)) 100%,calc(1lh + var(--d)) calc(100% + var(--s) + var(--d)),calc(.5lh + var(--d)) calc(100% + var(--s) + var(--r) + var(--d)),var(--d) calc(100% + var(--s) + var(--d)),var(--d) 100%);
}
.ribbon:hover {
  --d: .2lh;
}

In the event you occur to see such a polygon for the first time, likelihood is you may get confused, as a result of it appears a bit scary. Nevertheless actually, it’s not that superior. We started with a straightforward polygon and we slowly added additional components and further calculations until we reached this superior one.

Making a Rotated CSS Ribbon Kind

Let’s cope with the second type. For this one, we’ll use the model new trigonometric capabilities along with CSS variables and calc() identical to the sooner one. To understand the logic behind this manner, let’s rotate it and protect the textual content material in a straight line.

A Z-like ribbon shape

I’m together with slightly little bit of transparency to see the parts behind the precept side. I’ll be using pseudo-elements to create them. I’ve moreover added the blue outline for instance the world of the side. This manner will in all probability be managed with two variables:

.ribbon {
  --r: 30px;  
  --a: 15deg; 
}

The r is doing the similar job as with the sooner type. The a will administration the rotation of the precept side and many totally different points.

Let’s start with the precept side. We’re capable of see from the decide that we now have to reduce it from either side, so likelihood is you may logically think about using clip-pathnonetheless not this time. We’ll depend upon a gradient coloration, the place the half we now have to reduce may have a transparent shade:

.ribbon {
  --r: 30px;  
  --a: 15deg; 

  background:
    linear-gradient(calc(90deg + var(--a)),
      #0000 calc(1lh*sin(var(--a))),
      var(--c) 0 calc(100% - 1lh*sin(var(--a))),
      #0000 0
    );
}

Proper right here comes the geometry.

A geometric shape used to cut the corner triangle

The a is the angle variable we outlined. Considering this, the gradient should have an angle equal to 90deg + aand the clear shade ought to start at 0 and stop at d. Performing some math, d is similar as 1lh*sin(a). If we apply the similar logic on the alternative side, we get the following code:

background:
  linear-gradient(calc(90deg + var(--a)),
    #0000 0% calc(1lh*sin(var(--a))),
    var(--c) calc(1lh*sin(var(--a))) calc(100% - 1lh*sin(var(--a))),
    #0000 calc(100% - 1lh*sin(var(--a))) 100%
  );

We do some optimization by eradicating the 0% and 100% (they’re implicit), and when now we now have two consecutive shade stops that are equal, we’re capable of alternate the second with 0:

background:
  linear-gradient(calc(90deg + var(--a)),
    #0000 calc(1lh*sin(var(--a))),
    var(--c) 0 calc(100% - 1lh*sin(var(--a))),
    #0000 0
  );

We’re completed with the precept side, so let’s switch to the pseudo-elements. Proper right here as correctly, we wish some geometry tricks to set up the scale.

Widths and heights marked on the Z ribbon shape

We’re capable of merely uncover the height H from the sooner decide we used to ascertain the gradient configuration. It’s equal to 1lh/cos(a). For the width W, it’s equal to (100% - x)*cos(a)the place 100% is the width of the precept side and x is that small half the place now we now have the transparency. It’s equal to 1lh*tan(a).

Every pseudo-elements have the similar measurement, so our code is as follows:

.ribbon:sooner than,
.ribbon:after {
  content material materials: "";
  place: absolute;
  high: calc(1lh/cos(var(--a)));
  width: calc(100%*cos(var(--a)) - 1lh*sin(var(--a)));
}

In the event you occur to’re not cozy with the arithmetic and likewise you’re a bit misplaced with the formulation, it’s constructive. You don’t should exactly understand them. The target is to have the power to change the shape using CSS variables. The formulation are proper right here to make points easier and steer clear of us dealing with hard-coded values and magic numbers.

After the dimension, we must always all the time appropriately place each pseudo-element, rotate it, and use clip-path for the cutout half:

.ribbon:sooner than,
.ribbon:after {
  content material materials: "";
  place: absolute;
  rework: translate3d(0,0,-1px);
  rotate: var(--a);
  high: calc(1lh/cos(var(--a)));
  width: calc(100%*cos(var(--a)) - 1lh*sin(var(--a)));
  background: color-mix(in srgb,var(--c),#000 40%);
}
h1:sooner than {
  correct: 0;
  excessive: 0;
  transform-origin: excessive correct;
  clip-path: polygon(0 0,100% 0,100% 100%,0 100%,var(--r) 50%);
}
h1:after {
  left: 0;
  bottom: 0;
  transform-origin: bottom left;
  clip-path: polygon(0 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,0 100%);
}

The code must be self-explanatory and the clip-path value must be easy to know. We used additional superior polygons with the first type.

Bear in mind utilizing color-mix()which allows me to create a darkish mannequin of the precept shade. I’m moreover using a 3D translate with a detrimental value on the z-axis to convey the pseudo-elements behind the precept side. You could assume that that’s the job of z-indexnevertheless it certainly gained’t work on account of some stacking context factors that I’ve detailed in this Stack Overflow thread.

Now, if we rotate the side within the different manner, we get our CSS ribbon type.

As with the sooner occasion, I’ll mean you can dissect the code of the inexperienced ribbon and see what changes I made to get the choice type.

Conclusion

It was a gratifying practice, don’t you assume? We explored some trendy CSS choices like CSS variables, calc()and trigonometric capabilities, and we combined them to create fancy ribbon shapes.

If you want additional, go check out my full assortment of ribbon shapes. Try to assemble a number of of them alone sooner than checking the code. It is going to seemingly be an outstanding practice to use what you’ve realized proper right here.

By admin

Leave a Reply

Your email address will not be published. Required fields are marked *