3

How can we make this shape using CSS?

enter image description here

I'm able to write the below code using CSS but the shape generated output is a bit off. Can we do that using CSS?

.btn-arrow {
  width: 15px;
  height: 24px;
  border: 2px solid red;
  border-top-right-radius: 40px;
  border-bottom-right-radius: 40px;
  border-left: 0;
  display: inline-block;
  position: relative;
}

.btn-arrow:after,
.btn-arrow:before {
  right: 100%;
  top: 50%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
}

.btn-arrow:after {
  border-right-color: white;
  border-width: 12px;
  margin-top: -12px;
}

.btn-arrow:before {
  border-right-color: red;
  border-width: 14px;
  margin-top: -14px;
}

body {
  padding: 20px;
}
<div class="btn-arrow"></div>
Shashank Agrawal
  • 25,161
  • 11
  • 89
  • 121
  • 5
    This would be much easier with SVG rather than HTML and CSS – Turnip Apr 11 '18 at 10:34
  • 1
    The rounding in your shape goes on for more than 180 degrees, so you can’t expect to achieve that with two border-radius that cover/span an exact 90 degree section each. You would have to start with a fully rounded element, and then overlap parts of it with the actual “right angle/straight edge” shape ... which means, if you need it to be transparent/work on multi-color backgrounds, this is pretty much out right away. – CBroe Apr 11 '18 at 10:40
  • Thanks guys for the direction. I'll go with SVG – Shashank Agrawal Apr 11 '18 at 10:48
  • 1
    I have a solution with CSS, if you give me some time to construct it. – Marcos Pérez Gude Apr 11 '18 at 11:02
  • 1
    related: https://stackoverflow.com/questions/30711203/how-do-i-create-a-teardrop-in-html – Danield Apr 11 '18 at 11:48

3 Answers3

3

With CSS you can achieve that.

Just create ::after and ::before pseudoelements and the main box rotate 45 degrees. You can adjust the degrees on the linear-gradient part instead of "to right" sentence.

This trick is necessary because border-image and border-radius can't live both on the same element.

You can see more about this:

.shape {
  position:relative;
  width: 100px;
  border-radius: 100% 100% 100% 0;
  height: 100px;
  transform: rotate(45deg);
  margin: 0 auto;
  background: white;
  background-clip: padding-box;
}
.shape::after {
    position: absolute;
    top: -8px; 
    bottom: -8px;
    left: -8px; 
    right: -8px;
    background: linear-gradient(to right, #fe3870, #fc5d3e);
    content: '';
    z-index: -1;
    border-radius: 100% 100% 100% 0;
}
.shape::before {
    position: absolute;
    top: 8px; 
    bottom: 8px;
    left: 8px; 
    right: 8px;
    background: white;
    content: '';
    z-index: 1;
    border-radius: 100% 100% 100% 0;
}
<div class="shape">
</div>
Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
3

One of many possible solutions in just CSS:

This solution only requires one pseudo element.

.btn-arrow {
  width: 44px;
  height: 44px;
  border-top-right-radius: 40px;
  border-top-left-radius: 40px;
  border-bottom-right-radius: 40px;
  background: -webkit-linear-gradient(left, rgba(232,51,105,1) 0%,rgba(235,94,67,1) 100%); /* Chrome10-25,Safari5.1-6 */
  transform:rotate(45deg);
  position: relative;
}

.btn-arrow::after {
  display: block;
  width: 30px;
  height: 30px;
  border-top-right-radius: 40px;
  border-top-left-radius: 40px;
  border-bottom-right-radius: 40px;
  background: white;
  position: absolute;
  content: '';
  top: 7px;
  left: 7px;
}

body {
  padding: 20px;
}
<div class="btn-arrow"></div>
-2

Adjust the CSS to look like this

.btn-arrow {
      width: 30px;
    height: 30px;
    border: 2px solid red;
    border-radius: 100%;
    border-left: 0;
    display: inline-block;
    position: relative;
}

.btn-arrow:after,
.btn-arrow:before {
  right: calc(100% - 6px);
  top: 50%;
  border: solid transparent;
  content: " ";
  height: 0;
  width: 0;
  position: absolute;
}

.btn-arrow:after {
  border-right-color: white;
  border-width: 12px;
  margin-top: -12px;
}

.btn-arrow:before {
  border-right-color: red;
  border-width: 14px;
  margin-top: -14px;
}

body {
  padding: 20px;
}
Diyen Momjang
  • 1,811
  • 1
  • 11
  • 10