11

I am trying to make an arrow that looks like this:

Arrow example

However, this is the closest I can get to it:

.button {
  margin: 4em 0;
  padding: 2em;
  width: 15%;
  margin: 0 auto;
  text-align: center;
  background-color: #000000;
  color: #ffffff;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -moz-flex-flow: row wrap;
  -webkit-flex-flow: row wrap;
  -ms-flex-flow: row wrap;
  flex-flow: row wrap;
  webkit-justify-content: center;
  justify-content: center;
}
.curved-arrow {
  display: inline-block;
  border-top: 10px solid #fff;
  border-bottom: 10px solid #fff;
  border-left: 30px solid #fff;
  border-top-right-radius: 100%;
  border-bottom-right-radius: 100%;
}
<div class="button">
  <div class="curved-arrow"></div>
</div>

Is this even possible? I know I can use images, but my designer made several of these in multiple colors to use throughout the site that I'd rather just use CSS for the shape.

If it's hard to see it's a flat straight line from top to bottom on the left, and curves in to the middle on the right.

5
  • I don't know how to do it but judging by this page pattle.github.io/simpsons-in-css I would say that yes, it's possible. Commented Nov 19, 2015 at 15:55
  • I've been digging around, and haven't been able to find anything as of yet, but thanks for giving me hope with these complicated yet very impressive styles! Commented Nov 19, 2015 at 15:57
  • 2
    You might consider a webfont or SVG. Commented Nov 19, 2015 at 15:57
  • @RobertMcKee Thank you, I didn't consider that, I will look into that! Commented Nov 19, 2015 at 15:59
  • 1
    codepen.io/anon/pen/GpezyR Commented Nov 19, 2015 at 16:23

5 Answers 5

10

SVG

CSS border radius won't let you get the exact output you are looking for easily. I would suggest an inline SVG with the path element with one quadratic bezier command :

svg{width:100px;}
<svg viewbox="0 0 20 8">
  <path d="M0 0 Q 30 4 0 8" />
</svg>

Then you can color the arrow with the CSS fill property, see this fiddle (credits to @Nick R for the example posted in the comments)


CSS

You can also use the 2 values for the border-radius property (see MDN for an explanation of how it works) it is simple but it won't let you make the arrow 'point' as sharp as it is in your image :

.curved-arrow { 
  width:40px; height:25px;
  background:#000;
  border-top-right-radius:100% 50%;
  border-bottom-right-radius:100% 50%;
  
}
<div class="curved-arrow"></div>

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

5 Comments

This works great as well. I'm glad to see there are multiple answers to this. I do like the SVG method that I can apply here. Thank you!
Just to add to this, with SVGs you can set the colour using fill property - jsfiddle.net/kcnv7fm0
With this, since it'll be used in multiple places, can I set this svg to a class in CSS, or would your CSS version be the best practice for this solution?
@Ishio it depends on your aim. If you want it to look like the image you posted then CSS isn't the right tool. If the output from the CSS version is good enough, it might be easier for you especialy if you're not used to svg. To color the svg versions, have a look at the fiddle posted by Nick in the comments.
Yeah, I'm not used to SVG, and I'm working with my team to try and tweak this, but I keep getting the use a high version of the image, span in a span to control the height and set a class to it. Was trying to cut down on calls to images. However, this will work great!
8

CSS

This requires just a bit of fancy border-radius styling to achieve the shape you want.

.container {
  width: 100px;
  height: 100px;
  background: red;
  position: relative;
}
.arrow {
  width: 50px;
  height: 30px;
  position: absolute;
  top: 32px;
  left: 25%;
  border-radius: 0px 100% 100% 0px / 0 50% 50% 0;
  background: white;
}
<div class="container">
  <div class="arrow"></div>
</div>


If you want it in a single element, you can just use a psuedo element like so.

.arrow {
  width: 100px;
  height: 100px;
  background: red;
  position: relative;
}
.arrow:before {
  content: '';
  width: 50px;
  height: 30px;
  position: absolute;
  top: 32px;
  left: 25%;
  border-radius: 0px 100% 100% 0px / 0 50% 50% 0;
  background: white;
}
<div class="arrow"></div>


SVG

A good alternative would also be SVG to create this shape which also makes it fully responsive.

<svg width="100px" height="100px" viewbox="0 0 20 20" style="background: red;">
  <path d="M5,7
           Q15,7 15,10
           Q15,13 5,13z" fill="white"></path>
</svg>

1 Comment

This is perfect, thank you so much much for your help on this! This will work exactly as I need it to!
2

I think I've made something quite similar, maybe you could change some margins/widths or heights:

#arrow{
    display: block;
    box-sizing: content-box;
    float: none;
    width: 130px;
    height: 50px;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    margin: 0;
    padding: 0;
    overflow: visible;
    outline: none;
    border: 0 solid rgba(0,0,0,1);
    -webkit-border-radius: 50%;
    border-radius: 50%;
    background: #1abc9c;
    box-shadow: none;
    text-shadow: none;
    margin-left:-65px;
}
#arrow:after {
 position:absolute;
    left:-65px;
    width:65px;
    background:transparent;
    content:'';

}

It should be an oval, which i hide by an half by using :after ( quite dirty trick )

js fiddle

However, I would recomend you to use CSS sprites, I guess they should fit best your situation, because CSS shapes are not that easy to read for browsers.

Hope it helps! :)

1 Comment

something like width:80px and height:20px
2

Here's my take on it. Not quite as sharp a point as I'd like, but it's a little bit closer. Edit: second take uses two pseudo-elements to help sharpen the angle.

.button { margin: 4em 0; padding: 2em; width: 15%; margin: 0 auto; text-align: center; background-color: #000000; color: #ffffff; isplay: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -moz-flex-flow:row wrap; -webkit-flex-flow:row wrap; -ms-flex-flow:row wrap; flex-flow:row wrap; webkit-justify-content: center; justify-content: center; }

.curved-arrow { 
    position: relative;
    display: inline-block;
    height: 36px;
    width: 56px;
    overflow: hidden;
}
.curved-arrow:after {
    content: '';
    position: absolute;
    right: 0;
    top: 0;
    border-radius: 0 100% 0 0;
    height: 50%;
    width: 200%;
    background: #FFF;
}
.curved-arrow:before {
    content: '';
    position: absolute;
    right: 0;
    bottom: 0;
    border-radius: 0 0 100% 0;
    height: 50%;
    width: 200%;
    background: #FFF;
}
<div class="button">
  <div class="curved-arrow"></div>
</div>

Comments

1

Something like this?

#arrow-base {
  width: 120px;
  height: 80px;
  background: red;
}
#arrow {
  width: 0;
  height: 0;
  border-top: 16px solid transparent;
  border-bottom: 16px solid transparent;
  border-left: 32px solid white;
  display: inline-block;
  margin: 24px 44px;
  border-radius: 2px;
}
<div id="arrow-base">
  <div id="arrow">
    <!-- should be empty -->
  </div>
</div>

1 Comment

Negative. I need that left tip to be rounded out.Let me know if that image doesn't show up on the top of the page.

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.