Search code examples
htmlcsscss-shapescss-transforms

How to make slanted ribbon


How to create a ribbon like the below image using CSS. I know how to make the slanted filled box with text in it, but I struggle with the flaps.

enter image description here

Here's codepen link


Solution

  • Below is a sample of how you can do this. It is basically made with one parent div which has the ribbon text and two other div to produce the folded portions of the ribbon at the top and bottom. The folded portions are positioned according to the needs.

    enter image description here

    body {
      font-size: 18px;
      color: #FFF;
    }
    .container {
      margin: 50px 100px;
    }
    .ribbon {
      position: absolute;
      width: 400px;
      text-align: center;
      background: #000;
      padding: 20px 5px 20px 5px;
      -webkit-transform: skew(1deg, -15deg);
      -moz-transform: skew(1deg, -15deg);
      -o-transform: skew(1deg, -15deg);
      -ms-transform: skew(1deg, -15deg);
      transform: skew(1deg, -15deg);
      /* Note: The best practice is to always add the un-prefixed standards version as last */
    }
    .ribbon_before {
      height: 25px;
      width: 50px;
      position: relative;
      border: 2px solid black;
      top: 116px;
      left: 2px;
    }
    .ribbon_after {
      height: 25px;
      width: 50px;
      position: relative;
      border: 2px solid black;
      top: -56px;
      left: 355px;
    }
    <div class="container">
      <div class='ribbon_before'>&nbsp;</div>
      <div class="ribbon">LOREM IPSUM DOLOR SIT AMET</div>
      <div class='ribbon_after'>&nbsp;</div>
    </div>

    Demo on CodePen


    Note: The same effect can be achieved by using just a single div and a couple of pseudo-elements also like shown in the below snippet.

    body {
      font-size: 18px;
      color: #FFF;
    }
    .ribbon {
      margin: 100px 100px;
      position: relative;
      width: 400px;
      text-align: center;
      background: #000;
      padding: 20px 5px 20px 5px;
      -webkit-transform: skew(1deg, -15deg);
      -moz-transform: skew(1deg, -15deg);
      -o-transform: skew(1deg, -15deg);
      -ms-transform: skew(1deg, -15deg);
      transform: skew(1deg, -15deg);
    }
    .ribbon:before {
      height: 25px;
      width: 50px;
      position: absolute;
      content: '';
      border: 2px solid black;
      bottom: -8px;
      left: 0px;
      -webkit-transform: skew(-1deg, 15deg);
      -moz-transform: skew(-1deg, 15deg);
      -o-transform: skew(-1deg, 15deg);
      -ms-transform: skew(-1deg, 15deg);
      transform: skew(-1deg, 15deg);
    }
    .ribbon:after {
      height: 25px;
      width: 50px;
      position: absolute;
      content: '';
      border: 2px solid black;
      top: -8px;
      right: 0px;
      -webkit-transform: skew(-1deg, 15deg);
      -moz-transform: skew(-1deg, 15deg);
      -o-transform: skew(-1deg, 15deg);
      -ms-transform: skew(-1deg, 15deg);
      transform: skew(-1deg, 15deg);
    }
    <div class="ribbon">LOREM IPSUM DOLOR SIT AMET</div>


    Solution Tweaked by OP to meet their needs:

    I've tweaked the code a little to elevate it to condition close to 'pixel perfect' and here's the final link http://cdpn.io/zwDir