So I currently find myself needing to make something like this.
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
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 withtransform: rotateX()
property. It’s also a bit fragile for varying heights but it might be a useful starting point.Anyway, see what you think.
Using background linear-gradient can also achieve the effect you want, you can try it like this: