Im looking for a way to recreate this button with CSS only.
I know about the triangle technique and I also know how to add a border to it, but unfortunately I don't know any way to recreate this button (without adding additional wrappers or using images).
The buttons I need this style on are <input["submit"]>
and ordinary <a>
's.
The shape is created with two conic-gradient()
mask layers plus clip-path
. Neither of these features was a thing back in 2013.
.click-me {
--ang: 120deg;
--tri: .5*(.5turn - var(--ang));
--ini: calc(-1*(var(--ang) + var(--tri)));
--set: from var(--ini) at calc(100% - .5em);
--x: calc(100% - .5lh*tan(var(--tri)));
display: inline-block;
margin: .5em;
padding: 0 2em 0 1.5em;
background: lightseagreen;
mask:
conic-gradient(var(--set),
red var(--ang), #0000 0%) -.1875em,
conic-gradient(var(--set),
#0000 var(--ang), red 0%);
color: #fff;
font: clamp(.75em, 8vw, 2em)/ 2.25 verdana, sans-serif;
text-transform: uppercase;
white-space: nowrap;
clip-path:
polygon(0 0, var(--x) 0,
100% 50%, var(--x) 100%, 0 100%);
&:is(button, [type='submit']) { border: none }
&[href] { text-decoration: none }
&:is(:hover, :focus) { background: deepskyblue }
&:focus { outline: none }
}
<button class='click-me'>click me</button>
<input type='submit' value='click me' class='click-me'/>
<a class='click-me' href='#'>click me</a>
With one element, you could do it using gradients and skewed pseudo-elements for a link:
(you could actually do it using just gradients, but then a hover action won't be triggered on hover on the arrow shape itself, but on hover on the rectangular element containing it)
HTML:
<a class='boo' href='#'>click me</a>
Relevant CSS:
.boo {
display: inline-block;
position: relative;
padding: .5em 2em;
background:
linear-gradient(60deg, dodgerblue 50%, transparent 50%) 100% 0,
linear-gradient(-60deg, transparent 50%, dodgerblue 50%) 100% 100%,
linear-gradient(-90deg, transparent 1em, dodgerblue 1em);
background-repeat: no-repeat;
background-size: 1em 50%, 1em 50%, 100% 100%;
}
.boo:before, .boo:after {
position: absolute;
right: -.2em;
width: .5em; height: 50%;
background: dodgerblue;
content: '';
}
.boo:before {
top: 0;
transform: skewX(30deg);
}
.boo:after {
bottom: 0;
transform: skewX(-30deg);
}
If your background is a solid color, not an image or a gradient, you could do it in a much simpler way, without using gradients (which means that this second method also has the advantage of working in IE9).
.boo {
display: inline-block;
position: relative;
padding: .5em 2em;
background: lightblue;
}
.boo:before, .boo:after {
position: absolute;
right: -.3em;
width: .5em; height: 50%;
box-shadow: -.2em 0 0 white;
background: inherit;
content: '';
}
.boo:before {
top: 0;
transform: skewX(30deg);
}
.boo:after {
bottom: 0;
transform: skewX(-30deg);
}