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>

5
  • 5
    This would be much easier with SVG rather than HTML and CSS Commented Apr 11, 2018 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. Commented Apr 11, 2018 at 10:40
  • Thanks guys for the direction. I'll go with SVG Commented Apr 11, 2018 at 10:48
  • 1
    I have a solution with CSS, if you give me some time to construct it. Commented Apr 11, 2018 at 11:02
  • 1
    related: stackoverflow.com/questions/30711203/… Commented Apr 11, 2018 at 11:48

3 Answers 3

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>

Sign up to request clarification or add additional context in comments.

5 Comments

i think the difficult part is not only the shape but the gradient of the shape
I am using the border-image property but seems to be incompatible with border radius, so I achieved without background. I will following try.
@TemaniAfif I achieved the white background. Just with ::after and ::before. I will explain on post.
i understand what you ahve done ;) but now you are missing the transparent part ... not sure if the OP need it or not
Amazing! Worked like a charm. Thanks for the solution but more importantly for pointing in the right direction
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>

1 Comment

This is awesome. This is exactly I wanted but I learned this new thing. Thanks for the answer & the time
-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;
}

1 Comment

Not the exact design/shape I want. Other answer helped but thanks for the time

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.