Reputation: 591
I'm trying to make unique shape with CSS3.
I'm using Bootstrap 3 grid system to make the layout of the elements.
I have already built the most of this shape, but I just can't make the border-radius
property go round inside the element .
what I've already done :
CSS:
.test-midbox{
height: 170px;
background-color: white ;
padding-left: 0px;
padding-right: 0px;
margin-right: 0;
margin-left: 0;
border: solid black 1px;
top: 20px;
}
.test-inbox{
margin-right: 0;
margin-left: 0;
background-image: url("../images/linux.jpg") !important;
background-repeat: no-repeat;
background-position: center;
background-size: auto 80%;
height: 170px;
padding-top:10px;
padding-left:10px;
padding-right:10px;
padding-bottom:40px;
}
.monitor-name:before{
content: "";
position: absolute;
left: 0;
right: 0;
z-index: -2;
display: block;
height: 100%;
background: black;
opacity: 0.7;
border-bottom-right-radius: 20px;
border-top-right-radius: 20px;
}
.monitor-name{
z-index: 100;
position: absolute;
height: 40px;
bottom: 20px;
text-align: center;
color: white;
border:black 1px solid;
border-left: none;
border-bottom-right-radius: 20px;
border-top-right-radius: 20px;
}
.monitor-name-text{
top:1px;
text-align: center;
}
.test-puls{
position: absolute;
height: 20px;
padding-left: 0px;
padding-right: 0px;
margin-right: 0;
margin-left: 0;
border-top: 1px black solid;
bottom: 15px;
}
.btn-plus{
border-radius: 0;
}
.btn-cir{
border: 1px solid black;
position: absolute;
height: 40px;
bottom: 20px;
padding-left: 0px;
padding-right: 0px;
}
HTML :
<div class="col-lg-3 test-outerbox">
<div class="test-midbox col-lg-12">
<div class="col-lg-12 col-lg-offset-1 test-inbox">
</div>
<div class="col-lg-12 col-lg-offset-1 test-puls">
</div>
<div class="monitor-name col-lg-10 col-lg-push-2">
<h4 class="monitor-name-text">tsdsds</h4>
</div>
<div class="col-lg-2 btn-cir">k</div>
</div>
</div>
Upvotes: 2
Views: 255
Reputation: 89780
The border-radius
will always only produce an outward curve and it will never curve inwards. So, it alone cannot be used to produce the effect that you need. Below are a few approaches to produce the required effect. You can choose the one that applies to your case the most.
I have not used Twitter Bootstrap based mark-up but it should be straight-forward for you to convert.
With z-index:
If all the items have a opaque background (that is, no alpha value) and no. of elements is a finite fixed number then use z-index
to position the elements on top of one another such that the first one is on top of the second which in-turn is on top of third and so on. A negative margin-right
is also set to all elements to produce the overlapping effect. Since the backgrounds are opaque they border on the 1st element will look as though the second has an inward curving border and so on.
Note: This doesn't seem to suit your case based on the image provided but have added for completeness.
.items {
position: relative;
float: left;
height: 50px;
width: 200px;
margin-right: -60px;
line-height: 50px;
text-align: center;
border: 1px solid brown;
}
.elongated-border-curve .items {
border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:nth-of-type(n+2) {
border-left: 0;
background: wheat;
}
.items:first-of-type {
background: sandybrown;
color: white;
z-index: 3;
}
.items:nth-of-type(2) {
z-index: 2; /* lower z-index than first */
}
.items:nth-of-type(3) {
z-index: 1; /* lower z-index than second */
}
.items:last-of-type { /* default z-index 0 */
border-radius: 0%;
}
/* just for demo */
h3 {
clear: both;
}
.elongated-border-curve, .shorter-border-curve {
padding-bottom: 50px;
}
body {
background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
min-height: 500px;
}
<h3>With Elongated Border Curves</h3>
<div class='elongated-border-curve'>
<div class='items'>Item 1</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 2</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 3</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 4</div> <!-- give each item a z-index lower than the previous one -->
</div>
<h3>With Shorter Border Curves</h3>
<div class='shorter-border-curve'>
<div class='items'>Item 1</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 2</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 3</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 4</div> <!-- give each item a z-index lower than the previous one -->
</div>
Sample with dynamic width:
.items {
position: relative;
float: left;
height: 50px;
width: 32%;
margin-right: -10%;
line-height: 50px;
text-align: center;
border: 1px solid brown;
}
.elongated-border-curve .items {
border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:nth-of-type(n+2) {
border-left: 0;
background: wheat;
}
.items:first-of-type {
background: sandybrown;
color: white;
z-index: 3;
}
.items:nth-of-type(2) {
z-index: 2; /* lower z-index than first */
}
.items:nth-of-type(3) {
z-index: 1; /* lower z-index than second */
}
.items:last-of-type { /* default z-index 0 */
border-radius: 0%;
}
/* just for demo */
h3 {
clear: both;
}
.elongated-border-curve, .shorter-border-curve {
padding-bottom: 50px;
}
body {
background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
min-height: 500px;
}
<h3>With Elongated Border Curves</h3>
<div class='elongated-border-curve'>
<div class='items'>Item 1</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 2</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 3</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 4</div> <!-- give each item a z-index lower than the previous one -->
</div>
<h3>With Shorter Border Curves</h3>
<div class='shorter-border-curve'>
<div class='items'>Item 1</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 2</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 3</div> <!-- give each item a z-index lower than the previous one -->
<div class='items'>Item 4</div> <!-- give each item a z-index lower than the previous one -->
</div>
With Box Shadow:
If all items have solid background (opaque or transparent) but the no. of elements is either not finite or is large (and thus making the previous approach tough to adopt), use box-shadow
with a large spread radius on a pseudo-element like in the below snippet.
This approach will not work when the elements have a gradient or an image as their background.
.items {
float: left;
height: 50px;
width: 200px;
margin-right: -60px;
line-height: 50px;
text-align: center;
border: 1px solid brown;
}
.elongated-border-curve .items {
border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:first-of-type {
z-index: 3;
}
.items:nth-of-type(n+2) {
position: relative;
border-left: 0;
overflow: hidden;
}
.items:nth-of-type(n+2):after {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0px;
left: -140px; /* -(parent's margin-right) - width of element */
z-index: -1;
}
.elongated-border-curve .items:nth-of-type(n+2):after {
border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items:nth-of-type(n+2):after {
border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:last-of-type {
border-radius: 0%;
}
.opaque-bg .items:first-of-type {
background: sandybrown;
color: white;
}
.semi-transparent-bg .items:first-of-type {
background: rgba(0, 0, 0, 0.5);
color: white;
}
.opaque-bg .items:nth-of-type(n+2):after {
box-shadow: 0px 0px 0px 200px wheat;
}
.semi-transparent-bg .items:nth-of-type(n+2):after {
box-shadow: 0px 0px 0px 200px rgba(127, 127, 127, 0.5);
}
/* just for demo */
h3 {
clear: both;
}
.opaque-bg, .semi-transparent-bg {
padding-bottom: 50px;
}
body {
background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
min-height: 500px;
}
<h3>Items have a solid opaque background + Elongated Border Curves</h3>
<div class='opaque-bg elongated-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
<h3>Items have a solid semi-transparent background + Elongated Border Curves</h3>
<div class='semi-transparent-bg elongated-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
<h3>Items have a solid opaque background + Shorter Border Curves</h3>
<div class='opaque-bg shorter-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
<h3>Items have a solid semi-transparent background + Shorter Border Curves</h3>
<div class='semi-transparent-bg shorter-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
Sample with dynamic width:
.items {
float: left;
height: 50px;
width: 32%;
margin-right: -10%;
line-height: 50px;
text-align: center;
border: 1px solid brown;
}
.elongated-border-curve .items {
border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items {
border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:first-of-type {
z-index: 3;
}
.items:nth-of-type(n+2) {
position: relative;
border-left: 0;
overflow: hidden;
}
.items:nth-of-type(n+2):after {
position: absolute;
content: '';
height: 100%;
width: 100%;
top: 0px;
left: -69%; /* -(parent's margin-right) - width of element */
z-index: -1;
}
.elongated-border-curve .items:nth-of-type(n+2):after {
border-radius: 0% 35% 35% 0% / 0% 50% 50% 0%;
}
.shorter-border-curve .items:nth-of-type(n+2):after {
border-radius: 0% 20% 20% 0% / 0% 50% 50% 0%;
}
.items:last-of-type {
border-radius: 0%;
}
.opaque-bg .items:first-of-type {
background: sandybrown;
color: white;
}
.semi-transparent-bg .items:first-of-type {
background: rgba(0, 0, 0, 0.5);
color: white;
}
.opaque-bg .items:nth-of-type(n+2):after {
box-shadow: 0px 0px 0px 999px wheat;
}
.semi-transparent-bg .items:nth-of-type(n+2):after {
box-shadow: 0px 0px 0px 999px rgba(127, 127, 127, 0.5);
}
/* just for demo */
h3 {
clear: both;
}
.opaque-bg, .semi-transparent-bg {
padding-bottom: 50px;
}
body {
background: radial-gradient(circle at 50% 50%, aliceblue, mediumslateblue);
min-height: 500px;
}
<h3>Items have a solid opaque background + Elongated Border Curves</h3>
<div class='opaque-bg elongated-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
<h3>Items have a solid semi-transparent background + Elongated Border Curves</h3>
<div class='semi-transparent-bg elongated-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
<h3>Items have a solid opaque background + Shorter Border Curves</h3>
<div class='opaque-bg shorter-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
<h3>Items have a solid semi-transparent background + Shorter Border Curves</h3>
<div class='semi-transparent-bg shorter-border-curve'>
<div class='items'>Item 1</div>
<div class='items'>Item 2</div>
<div class='items'>Item 3</div>
<div class='items'>Item 4</div>
</div>
I think the box-shadow
approach should work for your case. If it doesn't then the only other option would be to use SVG. clip-path
can help in achieving this without using SVG but it has very poor browser support at present.
Upvotes: 5