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.

Ishio
  • 755
  • 2
  • 9
  • 29

5 Answers5

9

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>
Community
  • 1
  • 1
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • 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! – Ishio Nov 19 '15 at 16:22
  • 1
    Just to add to this, with SVGs you can set the colour using `fill` property - http://jsfiddle.net/kcnv7fm0/ – Nick R Nov 19 '15 at 16:22
  • 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 Nov 19 '15 at 16:28
  • 1
    @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. – web-tiki Nov 19 '15 at 16:34
  • 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! – Ishio Nov 19 '15 at 16:36
7

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>
Stewartside
  • 20,378
  • 12
  • 60
  • 81
  • This is perfect, thank you so much much for your help on this! This will work exactly as I need it to! – Ishio Nov 19 '15 at 16:19
1

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! :)

CapitanFindus
  • 1,498
  • 15
  • 26
1

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>
Joseph Marikle
  • 76,418
  • 17
  • 112
  • 129
0

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>
Berendschot
  • 3,026
  • 1
  • 21
  • 43
  • 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. – Ishio Nov 19 '15 at 16:16