5

Is it possible to create concave corners like this in css? If yes, how would you do it?

Image

Mick
  • 30,759
  • 16
  • 111
  • 130

5 Answers5

10

Lea Verou has a description of how to do this:

By using radial gradients, you can simulate rounded corners with a negative radius. You can do this without the support of any extra elements. Its a little tricky.

It also falls back to a solid color background if CSS gradients are not supported. It will work on Firefox 3.6, latest Webkit and —hopefully— Opera 11.10 (they announced that gradients support is coming). You could add a -webkit-gradient() background too, to make it work in practically all versions of Webkit currently in use, but I warn you: It’s not going to be easy and I personally refuse to spend more than 5 minutes of my time messing with that non-standard thing.

Here is a live demo of their implementation.

Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Alfred
  • 21,058
  • 61
  • 167
  • 249
  • Wow! This actually allows us to use only one div and to have a background image. This is perfect. – Mick Sep 16 '12 at 15:11
  • Thanks @Patt :) , I think this is the better way to do this. This creates less headache than others. Consider giving this a +1. – Alfred Sep 16 '12 at 15:15
  • Indeed, it does look aliased in Safari. Could you explain this: `don't put the color stops at the exact same position`. Can this code work well in Safari and IE? – Mick Sep 16 '12 at 15:17
  • This post is originally from Lea Berrou. Here is the [link](http://lea.verou.me/2011/03/beveled-corners-negative-border-radius-with-css3-gradients/). Please, don't forget to give the source. – Mick Sep 16 '12 at 15:49
  • @Patt - Thanks for pointing this out. I've edited the answer to provide proper credit to Lea for this. – Brad Larson Sep 17 '12 at 14:27
7

Here is a good example of how I would tackle this:

http://jsfiddle.net/x4wLf/

HTML:

<div class='concave'>
    <div class='topleftconcave'></div>
    <div class='botleftconcave'></div>
</div>

CSS:

 div.concave {
    background:blue;
    width:150px;
    height:120px;
    position:relative;
}
div.topleftconcave {
    position:absolute;
    background:white;
    width:25px;
    height:35px;
    border-bottom-right-radius:500px;
}
div.botleftconcave {
    position:absolute;
    background:white;
    width:25px;
    height:35px;
    bottom:0;
    left:0;
    border-top-right-radius:500px;
} 
JTG
  • 8,587
  • 6
  • 31
  • 38
Korvin Szanto
  • 4,531
  • 4
  • 19
  • 49
  • That was quick @Korvin. Well done! This is beautiful and this is exactly what I am after! – Mick Sep 16 '12 at 14:57
  • This option creates extra elements. Actually it can be solved without adding any extra elements. – Alfred Sep 16 '12 at 15:10
  • 1
    Technically no it can't. The ::before and ::after method is limited to two concave corners as I mentioned in David Thomas's example, that's why I chose adding elements. – Korvin Szanto Sep 16 '12 at 15:12
  • Maybe there is a little disadvantage with this but I am not sure this is possible to avoid it. If there is an image in the background, we will see the corner in a different color right? – Mick Sep 16 '12 at 15:20
2

If you'd rather not add extra elements to the HTML, need to style only two corners and are able to use generated content instead, I'd suggest:

.concave {
    position: relative;
    width: 10em;
    height: 3em;
    line-height: 3em;
    margin: 1em auto;
    padding: 0.5em;
    background-color: #00f;
    color: #fff;
}

.concave::before {
    content: '';
    position: absolute;
    top: -1em;
    left: -1em;
    border: 1em solid #fff;
    border-radius: 1em;
}

.concave::after {
    content: '';
    position: absolute;
    bottom: -1em;
    left: -1em;
    border: 1em solid #fff;
    border-radius: 1em;
}
​

JS Fiddle demo.

David Thomas
  • 249,100
  • 51
  • 377
  • 410
0

The only way I know is to add four divs at the four corners, each with a positive border radius.

jazmit
  • 5,170
  • 1
  • 29
  • 36
0

What about the CSS3 border-image property? Great article here:

http://css-tricks.com/understanding-border-image/

It will mean no support for older browsers such as IE 7-8, but if you can live with that or find a work around this would work well.

I recently done used border-image myself to do this exact thing.

Glen
  • 31
  • 2