Reputation:
Here is a simple convex example.
#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:
Upvotes: 24
Views: 32741
Reputation: 5997
Welcome to 2024. Simply achievable using two radial gradients in a single element. No pseudo elements, nor additional, nor shenanigans.
div {
--size: 50px;
--concave-size: calc(var(--size) / 2);
height: var(--size);
width: var(--size); /* can be whatever */
background-color: red;
background-image:
radial-gradient(circle at left, yellow, yellow var(--concave-size), transparent var(--concave-size)),
radial-gradient(circle at right, blue, blue var(--concave-size), transparent var(--concave-size));
}
<div></div>
Upvotes: 0
Reputation: 13574
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.
Upvotes: 16
Reputation: 71
There are several ways to make the concave border. And I prefer to use the radial gradients on the background. https://jsfiddle.net/black_horse/qygmb8z9/
.single-border{
height: 50px;
padding: 20px;
background:-moz-radial-gradient(0 100%, circle, rgba(204,0,0,0) 20px, #c00 21px), -moz-radial-gradient(100% 100%, circle, rgba(204,0,0,0) 20px, #c00 21px), -moz-radial-gradient(100% 0, circle, rgba(204,0,0,0) 20px, #c00 21px), -moz-radial-gradient(0 0, circle, rgba(204,0,0,0) 20px, #c00 21px);
background:-o-radial-gradient(0 100%, circle, rgba(204,0,0,0) 20px, #c00 21px), -o-radial-gradient(100% 100%, circle, rgba(204,0,0,0) 20px, #c00 21px), -o-radial-gradient(100% 0, circle, rgba(204,0,0,0) 14px, #c00 21px), -o-radial-gradient(0 0, circle, rgba(204,0,0,0) 20px, #c00 21px);
background:-webkit-radial-gradient(0 100%, circle, rgba(204,0,0,0) 20px, #c00 21px), -webkit-radial-gradient(100% 100%, circle, rgba(204,0,0,0) 20px, #c00 21px), -webkit-radial-gradient(100% 0, circle, rgba(204,0,0,0) 20px, #c00 21px), -webkit-radial-gradient(0 0, circle, rgba(204,0,0,0) 20px, #c00 21px);
background-position:left bottom, right bottom, right top, left top;
-moz-background-size:51% 51%;
-webkit-background-size:51% 51%;
background-size:51% 51%;
background-repeat:no-repeat;
}
<div class="single-border">
Single border
</div>
Upvotes: 2
Reputation: 39322
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:
Upvotes: 7
Reputation: 24559
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>
Upvotes: 3
Reputation: 168685
I suggest using border-image
, with a scalable SVG image in the border.
That way you can have any shape you want in the border; no need to be restricted to the shapes offered by border-radius
, and no need to do any clever hacks or extra markup either.
The down-side is that neither border-image
nor SVG is supported in older browsers (ie old IE versions). But of course, border-radius
isn't either, so you don't lose much with this technique, compared with the flexibility you gain.
Upvotes: 2
Reputation: 23001
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.
Upvotes: 20