skip to Main Content

So I currently find myself needing to make something like this.

enter image description here

My first thought was to use clip-path, but the rounded corners would be hard to pull off, and it would be hard to maintain the 22.5 degrees when the button changes width because of its contents.

So I ended up making each button 2 divs, with 1 div being skewed by 22.5 degrees and being overlapped by the regular rectangular div. Then I added border radius to both.

body {
  line-height: 0;
  font-size: 16px;
  background-color: black;
}

.cta-button-group {
  display: flex;
  gap: 2rem;
  align-items: center;
}

.button-angular-wrapper-left {
  display: flex;
  isolation: isolate;
  position: relative;
  height: 40px;
  width: fit-content;
}

.button-angular-wrapper-left .button-angular-main {
  border-radius: 7px 0 0 7px;
  height: 100%;
  display: inline-grid;
  place-items: center;
  padding-inline: 8px 16px;
  margin-right: 13px;
  transition: background-color 50ms;
}

.button-angular-wrapper-left .button-angular-slant {
  border-radius: 0 7px 7px 0;
  height: 100%;
  width: 24px;
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  z-index: -1;
  transition: background-color 50ms;
}

.button-angular-wrapper-left .button-angular-slant.back-slash {
  transform: skewX(22.5deg);
}

.button-angular-wrapper-left .button-angular-slant.forward-slash {
  transform: skewX(-22.5deg);
}

.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-main,
.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-slant {
  background: white;
  border: 3px solid white;
  color: blue;
}

.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-main {
  border-right: none;
}

.button-angular-wrapper-left.button-angular-color-solid-white .button-angular-slant {
  border-left: none;
}

.button-angular-wrapper-right {
  display: flex;
  isolation: isolate;
  position: relative;
  height: 40px;
  width: fit-content;
}

.button-angular-wrapper-right .button-angular-main {
  border-radius: 0 7px 7px 0;
  height: 100%;
  display: inline-grid;
  place-items: center;
  padding-inline: 8px 16px;
  margin-left: 13px;
}

.button-angular-wrapper-right .button-angular-slant {
  border-radius: 7px 0 0 7px;
  height: 100%;
  width: 24px;
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  z-index: -1;
}

.button-angular-wrapper-right .button-angular-slant.back-slash {
  transform: skewX(22.5deg);
}

.button-angular-wrapper-right .button-angular-slant.forward-slash {
  transform: skewX(-22.5deg);
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main,
.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-slant {
  border: 3px solid white;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main {
  border-left: none;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main .icon-call {
  color: white;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-main .cta-text {
  color: white;
}

.button-angular-wrapper-right.button-angular-color-outline-white .button-angular-slant {
  border-right: none;
}
<div class="cta-button-group">
  <div class="button-angular-wrapper-left button-angular-color-solid-white" href="">
    <div class="button-angular-main">
      <span class="cta-text">
        Learn More Today
      </span>
    </div>
    <div class="button-angular-slant back-slash">
    </div>
  </div>
  <div class="button-angular-wrapper-right button-angular-color-outline-white" href="">
    <div class="button-angular-main">
      <span class="cta-text tel-link-no">
        1800-1-5555
      </span>
    </div>
    <div class="button-angular-slant back-slash">
    </div>
  </div>
</div>

Codepen: https://codepen.io/katylar/pen/yLRjKaO

It works, but it’s not perfect. I notice significant artifacts and weird corners/edges on some browsers at some resolutions.

Does anyone have a good solution? that doesn’t involved masks (which I always have a hard time with, sizing-wise)?

2

Answers


  1. One suggestion, if you’re totally against masks, is to use perspective and rotate one div in 3D to give an angled element.

    Use a container and make it display: inline-block so the angled div is always at the right hand side. That makes it, when you rotate it on the X axis, lean ‘backwards’ to the right. We create a new stacking context in the container to hide the last div below the parent. Use css custom properties to make sure the final div matches the width of the parent. Personally I’d use a mask but this could be used instead, certainly for elements with a solid background. I don’t know how you’d do it with border as the border width will also change with transform: rotateX() property. It’s also a bit fragile for varying heights but it might be a useful starting point.

    Anyway, see what you think.

    body {
      background: black;
      color: black;
    }
    
    .container {
      --height: 4rem;
      perspective: 100px;
      isolation: isolate;
      display: inline-flex;
    }
    
    .main,
    .angle {
      display: inline-flex;
      align-items: center;
      padding-left: 1rem;
      background-color: white;
      border-radius: 0.5rem;
    }
    
    .main {
      height: var(--height);
      width: 200px;
    }
    
    .angle {
      position: relative;
      right: 30px;
      width: 30px;
      transform-origin: top center;
      transform: rotateX(20deg);
      height: calc(var(--height) * 0.96);
      z-index: -1;
    }
    <div class="container">
      <div class='main'>Learn more today!</div><div class="angle"></div>
    </div>
    Login or Signup to reply.
  2. Using background linear-gradient can also achieve the effect you want, you can try it like this:

    body {
      background-color: black;
    }
    
    .button {
      display: inline-block;
      height: 40px;
      line-height: 40px;
      padding: 0 24px;
      text-align: center;
      color: blue;
      background: linear-gradient(-120deg, transparent 20px, #fff 0);
      background-repeat: no-repeat;
    }
    <div class="button">
      Learn More Today
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search