Is a concave border radius possible?
Here is a simple convex example.
http://jsfiddle.net/swY5k/
#test{
width: 200px;
height: 200px;
background: #888888;
border-radius: 50px;
}
However, I want a concave border radius.
I tried making the border-radius negative but this did not work.
Example of concave/convex:
Solution 1:
You can give the impression of a concave border using radial gradients on the background. For example, something like this:
#test {
width: 200px;
height: 200px;
background: #888888;
background:
radial-gradient(circle 20px at -20% 50%,transparent,transparent 100px,#888888 100px),
radial-gradient(circle 20px at 120% 50%,transparent,transparent 100px,#888888 100px);
background-size:100px 200px, 100px 200px;
background-position:0 0,100% 0;
background-repeat:no-repeat;
}
Note that most webkit browsers still require prefixes for radial-gradients, and if you want to fully support older browsers you may need to implement the older gradient syntax too.
Solution 2:
With clever use of the :before
and :after
pseudo classes, we can simulate a concave form:
#test{
width: 100px;
height: 300px;
background: green;
position: relative;
display: inline-block;
}
#test:before{
background: white;
height: 300px;
width: 30px;
border-radius: 0 60px 60px 0 / 0 300px 300px 0;
display: inline-block;
content: '';
}
#test:after{
background: white;
height: 300px;
width: 30px;
border-radius: 60px 0 0 60px / 300px 0 0 300px;
display: inline-block;
content: '';
position: relative;
left: 40px;
}
<div id="test"></div>
The #test
div is a plain rectangle. But its :before
and :after
elements are half-side concave filled with the background color (white in this case).
See this jsfiddle.
Solution 3:
SVG
is the recommended way to create such shapes. It offers simplicity and scale-ability.
We can use SVG
's path element to create a shape like above and fill it with some solid color, gradient or a pattern.
Only one attribute d
is used to define shapes in path
element. This attribute itself contains a number of short commands and few parameters that are necessary for those commands to work.
Following code will create a convex shape:
<path d="M 150,25
Q 115,100 150,175
Q 185,100 150,25" />
And following one will create a concave shape:
<path d="M 30,25
L 80,25
Q 50,100 80,175
L 30,175
Q 60,100 30,25" />
Below is a brief description of path
commands used in above code:
-
M
command is used to define the starting point. It appears at the beginning and specify the point from where drawing should start. -
L
command is used to draw straight lines. -
Q
command is used to draw curves.
Output Image:
Working Demo:
<svg width="300" height="200" viewBox="0 0 300 200">
<defs>
<linearGradient id="grad">
<stop offset="0" stop-color="#ddd" />
<stop offset=".5" stop-color="#fff" />
<stop offset="1" stop-color="#ddd" />
</linearGradient>
</defs>
<g stroke-width="1" stroke="#000" fill="url(#grad)">
<path d="M30,25 L80,25 Q50,100 80,175 L30,175 Q60,100 30,25" />
<path d="M150,25 Q115,100 150,175 Q185,100 150,25" />
</g>
</svg>
Useful Resources:
Below are some useful links for SVG:
- Specification
- MDN
Solution 4:
To generate the shape, you can use pseudo elements
div {
height: 250px;
width: 100px;
background: tomato;
position: relative;
margin:0 auto;
}
div:before {
content: "";
height: 100%;
width: 50%;
position: absolute;
background: white;
border-radius: 50%;
left: -25%;
transition: all 0.8s;
}
div:after {
content: "";
height: 100%;
width: 50%;
position: absolute;
background: white;
border-radius: 50%;
right: -25%;
transition: all 0.8s;
}
div:hover:before,
div:hover:after {
background: blue;
}
hover the shape to see how it works:
<div></div>