2

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 .

The shape : special

what I've already done :

codepen

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>
Harry
  • 87,580
  • 25
  • 202
  • 214
Ariel Livshits
  • 591
  • 1
  • 7
  • 23
  • Are you trying to build something like http://stackoverflow.com/questions/27636373/how-to-make-this-arrow-in-css-only/28196665?s=19|0.0000#28196665 – Harry Dec 19 '15 at 12:51
  • Or even this - http://stackoverflow.com/questions/33808342/create-a-rouded-arrow I am not quite sure which one you are looking for. – Harry Dec 19 '15 at 13:13
  • 1
    some thing like the first one , but rounded and not like arrows – Ariel Livshits Dec 19 '15 at 13:21
  • I am away from my PC right now and so can't help you with a demo but have a look at this answer - http://stackoverflow.com/questions/28248723/rounded-arrow-shape-with-gradient-fill/28248994#28248994 and try combining it with the previous sample. That should help you :) – Harry Dec 19 '15 at 13:29
  • 1
    i will check it tomorrow , sorry for the delay – Ariel Livshits Dec 25 '15 at 01:19

1 Answers1

5

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.

Harry
  • 87,580
  • 25
  • 202
  • 214