Search code examples
htmlcsstransformshapesclip-path

custom shape with a border and transparent background / clip path


I have been trying to make a custom shape with a border and transparent background.

The initial approach, i tried was with transfrom skew but that couldn't give me the shape i was after.

I have also been experimenting with clip paths, my first attempt i managed to control the angle based off the height and also the right padding, which is a benefit. I would prefer to use this for that reason but unfortunately putting border on it doesn't work.

I found a bit online about having a shape inside a shape but then i cant have a clear background but its the shape i'm after.

If any one knows how i can create this shape either amending the code i tried using or a different approach i haven't thought about that would be great.

For visual reference this is what i'm trying to achieve. enter image description here

<!DOCTYPE html>
<html lang="en" dir="ltr">

<head>
  <meta charset="utf-8">
  <title></title>

  <style>
     :root {
      --cta-height: 60px;
      --cta-angle: calc(var(--cta-height) - 20px);
      --cta-side-padding: 40px;
      --cta-height-inner: calc(var(--cta-height) - 4px);
      --cta-angle-inner: calc(var(--cta-height-inner) - 20px);
    }
    
    .img1 {
      background: url("https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg");
    }
    
    .bk-image {
      background-repeat: no-repeat;
      background-size: cover;
      background-position: center;
      padding: 50px;
    }
    /* attemp one with angle and right padding based off of the height */
    
    .cta {
      clip-path: polygon(0% 0%, 100% 0%, calc(100% - var(--cta-angle)) 100%, 0% 100%);
      -webkit-clip-path: polygon(0% 0%, 100% 0%, calc(100% - var(--cta-angle)) 100%, 0% 100%);
      display: flex;
      align-items: center;
      height: var(--cta-height);
      padding-right: calc(var(--cta-angle) + var(--cta-side-padding));
      padding-left: var(--cta-side-padding);
      margin-bottom: 50px;
    }
    
    .cta__ora {
      border: 2px solid orange;
      color: #ffffff;
    }
    
    .flex-p {
      display: flex;
      align-content: center;
    }
    /* attemp two */
    
    .outside {
      position: relative;
      background: tomato;
      clip-path: polygon(0% 0%, 100% 0%, calc(100% - var(--cta-angle)) 100%, 0% 100%);
      -webkit-clip-path: polygon(0% 0%, 100% 0%, calc(100% - var(--cta-angle)) 100%, 0% 100%);
      height: var(--cta-height);
      padding-right: calc(var(--cta-angle) + var(--cta-side-padding));
      padding-left: var(--cta-side-padding)
    }
    
    .inside {
      position: absolute;
      top: 4px;
      left: 4px;
      right: 4px;
      bottom: 4px;
      background: white;
      clip-path: polygon(0% 0%, calc(100% - 4px) 0%, calc(100% - var(--cta-angle)) 100%, 0% 100%);
      -webkit-clip-path: polygon(0% 0%, calc(100% - 4px) 0%, calc(100% - var(--cta-angle)) 100%, 0% 100%);
    }
  </style>

</head>

<body>


  <div class="bk-image img1 ">

    <div class="flex-p">
      <a class="cta cta__ora">clip path angle adjust from the height</a>
    </div>

    <div class="outside">
      <div class="inside">
        hello
      </div>
    </div>

  </div>

</body>

</html>


Solution

  • You can work a little bit with ::after and position like a slash

    body {
      background: url("https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg") no-repeat;
    }
    
    .inside {
      height: 50px;
      width: 300px;
      border: 2px solid black;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      clip-path: polygon(0 0, 100% 0%, 89% 100%, 0% 100%);
    }
    
    .inside::after {
      content: "";
      position: absolute;
      height: 65px;
      width: 300px;
      top: -2px;
      right: -1.5px;
      border-right: 2px solid black;
      transform: rotate(31.8deg);
      transform-origin: right top;
    }
    <div class="inside">
      Find out more
    </div>