<h1 class="ribbon" contenteditable="true">Click to edit</h1>
.ribbon {
--r: .5em; /* control the cutout of the ribbon */
--a: 20deg; /* control the angle of the folded part */
--w: 5em; /* control the width of the folded part */
--c: #d81a14;
padding-inline: calc(1lh*tan(var(--a)/2) + .3em);
margin-block: calc(var(--w)*sin(var(--a)));
text-align: center;
color: #fff;
line-height: 2;
background-image:
linear-gradient(var(--c) 70%,#0000 0),
linear-gradient(to bottom left,#0000 50%, color-mix(in srgb,var(--c),#000 40%) 51% 84%,#0000 85%);
background-position: 0 .15lh;
background-size: 100% 1lh;
position: relative;
clip-path: polygon(
0 .15lh,
calc(100% - .7lh/sin(var(--a))) .15lh,
calc(100% - .7lh/sin(var(--a)) - 999px) calc(.15lh - 999px*tan(var(--a))),
100% -999px,
100% .15lh,
calc(100% - .7lh*tan(var(--a)/2)) .85lh,
100% 1lh,
100% calc(100% - .15lh),
calc(.7lh/sin(var(--a))) calc(100% - .15lh),
calc(.7lh/sin(var(--a)) + 999px) calc(100% - .15lh + 999px*tan(var(--a))),
0 999px,
0 calc(100% - .15lh),
calc(.7lh*tan(var(--a)/2)) calc(100% - .85lh),
0 calc(100% - 1lh)
);
/*width: fit-content; you may need this in your real use case */
outline: none;
}
.ribbon:before,
.ribbon:after {
content:"";
position: absolute;
height: .7lh;
width: var(--w);
background: color-mix(in srgb,var(--c),#000 40%);
rotate: var(--a);
}
.ribbon:before {
top: .15lh;
right: 0;
transform-origin: top right;
clip-path: polygon(0 0,100% 0,calc(100% - .7lh/tan(var(--a))) 100%,0 100%, var(--r) 50%);
}
.ribbon:after {
bottom: .15lh;
left: 0;
transform-origin: bottom left;
clip-path: polygon(calc(.7lh/tan(var(--a))) 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,0 100%);
}
/* if you update the line-height, you need to also update the below */
@supports not (height:1lh) {
.ribbon {
padding-inline: calc(2em*tan(var(--a)/2) + .3em);
background-position: 0 .3em;
background-size: 100% 2em;
clip-path: polygon(
0 .3em,
calc(100% - 1.4em/sin(var(--a))) .3em,
calc(100% - 1.4em/sin(var(--a)) - 999px) calc(.3em - 999px*tan(var(--a))),
100% -999px,
100% .3em,
calc(100% - 1.4em*tan(var(--a)/2)) 1.7em,
100% 2em,
100% calc(100% - .3em),
calc(1.4em/sin(var(--a))) calc(100% - .3em),
calc(1.4em/sin(var(--a)) + 999px) calc(100% - .3em + 999px*tan(var(--a))),
0 999px,
0 calc(100% - .3em),
calc(1.4em*tan(var(--a)/2)) calc(100% - 1.7em),
0 calc(100% - 2em)
);
}
.ribbon:before,
.ribbon:after {
height: 1.4em;
}
.ribbon:before {
top: .3em;
clip-path: polygon(0 0,100% 0,calc(100% - 1.4em/tan(var(--a))) 100%,0 100%, var(--r) 50%);
}
.ribbon:after {
bottom: .3em;
clip-path: polygon(calc(1.4em/tan(var(--a))) 0,100% 0,calc(100% - var(--r)) 50%,100% 100%,0 100%);
}
}
body {
margin: 0;
min-height: 100vh;
display: grid;
place-content: center;
place-items: center;
background: #f2f2f2;
line-height: 2;
}
/* due to precise values you have to choose good font-size values to avoid rounding issues and visual glitches */
h1 {
font-family: sans-serif;
text-transform: uppercase;
font-size: 3.5rem;
margin: 0;
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.