It's feasible using clip-path: path(…)
, but unfortunately it requires to work with fixed sizes (no responsive).
See the Illustrated Guide to the SVG path
Syntax for how to produce the shape you want. In this example we’ll need an Arch and Lines.
Because a clipped element cannot have a border, we use a ::before
pseudo-element to cover up the inside of the button with a slightly smaller shape.
See How to add border in my clip-path: polygon(); CSS style for other possible techniques to outline a shape.
Also provide some extra style for the focus
state, to not exclude users with disabilities or keyboard fans.
fieldset {
background: #212121;
border: 0;
padding: 1rem;
width: fit-content;
display: flex;
gap: 15px;
}
fieldset > * {
box-sizing: border-box;
height: 50px;
padding: 0 1rem;
font: 1rem system-ui;
}
fieldset > *:focus {
outline: none;
}
input {
min-width: 300px;
clip-path: path('M 300 0 A 25 30 0 0 0 300 50 L 0 50 L 0 0')
}
input:focus {
background: cyan;
color: #212121;
}
button {
position: relative;
width: 215px;
margin-left: -25px;
cursor: pointer;
border: 0;
color: #fff;
background: currentColor;
clip-path: path('M 25 0 A 25 30 0 0 0 25 50 L 185 50 L 215 25 L 185 0')
}
button:focus {
color: cyan;
}
button span {
position: absolute;
z-index: 2;
inset: 0;
line-height: 50px;
}
button::before {
content: "";
position: absolute;
z-index: 1;
pointer-events: none;
display: block;
inset: 0;
background: #212121;
clip-path: path('M 25 1 A 24 30 0 0 0 25 49 L 185 49 L 214 25 L 185 1 z')
}
<form>
<fieldset>
<input type="text" aria-label="insert your email" placeholder="Email Address">
<button type="submit"><span>Sign up</span></button>
</fieldset>
</form>