Search code examples
htmlcsstailwind-css

How to create an one side only slanting ribbon ? using CSS


I need your help to create something like this that is also reponsive in mobile. the text inside can vary in length.
enter image description here
So far,
able to create the following code below,
enter image description here

Whats a good approach for such thing?

CSS below

<style>
  .box {
    height: auto;
    border: 2px solid green; 
    border-radius: 0 5px 5px 0;
    margin: 5px;
    background:
      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15" preserveAspectRatio="none"><polygon points="16,17 16,-2 0,-1" fill="yellow" stroke="green" /></svg>') bottom right/30px 100%,  /* Adjusted background position here */
      url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 15 15" preserveAspectRatio="none"><polygon points="16,16 16,-2 0,16" fill="white" stroke="white" /></svg>') bottom right/0px 0%,
      yellow content-box;
    background-repeat: no-repeat;
    font-size: 3em;
  }
</style>

HTML Below

<div class="box">Reinventing Growth Opportunities</div>

Although i am able to create something like this enter image description here

using psuedo class but the border is not applying

enter image description here

<h4 class="ribbon">Reinventing Growth Opportunities</h4>
.ribbon {
    position: relative;
    background-color: #4c6fff;
    color: white;
    padding: 0.5em 2em;
    display: inline-block;
    margin-bottom: 1em;
    /* border: 3px solid black; */
}

.ribbon::before {
    content: "";
    position: absolute;
    top: 0px;
    right: -1em;
    border-top: 2.5em solid #4c6fff;
    border-right: 1em solid transparent;
    bottom: 0em;
    overflow: hidden; 
}

Solution

  • skew transformation on pseudo element can do this:

    .ribbon {
      --b: 2px; /* border width */
      --c: red; /* border color */
      
      padding: 1em 2em 1em 1em;
      font-size: 20px;
      display: inline-block;
      border-left: var(--b) solid var(--c);
      overflow: hidden;
      position: relative;
      z-index: 0;
    }
    
    .ribbon:before {
      content: "";
      position: absolute;
      z-index: -1;
      inset: 0 0 0 calc(-1*var(--b));
      background: lightblue; /* background color */
      border: var(--b) solid var(--c);
      transform-origin: top;
      transform: skewX(-20deg); /* control the slant */
    }
    <div class="ribbon">Some text here</div>