DEV Community

Cover image for CSS Battle #4 - Ups n Downs
Olzhas Askar
Olzhas Askar

Posted on

CSS Battle #4 - Ups n Downs

This one is pretty neat. The shape is the same three times, only the directions and positions differ. Let's use that for our first solution.

1. Absolute Positions

We create three divisions and give them arbitrary ids of a, b and c. If you don't want to do that, you can :nth-of-type() selector. Then we style our figure, however it is called. We give it a width and height, a background color, position it absolutely and round the lower side of the rectangle. Afterward, for each of the given divs we give a proper top and left positions and in case of the first shape, we also rotate it 180 degrees to point upwards.

<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<style>
  * {
    background: #62306D;
  }
  div {
    width: 100px;
    height: 100px;
    background: #F7EC7D;
    position: absolute;
    border-radius: 0 0 50px 50px;
  }
  #a {
    top: 50px;
    left: 150px;
    transform: rotate(180deg);
  }
  #b {
    top: 150px;
    left: 50px;
  }
  #c {
    top: 150px;
    left: 250px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

2. Using Margin/Padding

Div o, which stands for outer, serves as a wrapper here to cut off all of the space. This way we may avoid absolute positioning, thus remaining within a normal document flow. In this outer box, we style three divs to be inline-block (notice how all of them are glued together to avoid unwanted spaces). Finally, their positioning is achieved by using margins.

<div id="o">
  <div id="a"></div><div id="b"></div><div id="c"></div>
</div>
<style>
  body {
    margin: 0;
    background: #62306D;
  }
  #o {
    width: 300px;
    height: 200px;
    margin: 50px;
  }
  #o > div {
    width: 100px;
    height: 100px;
    background: #F7EC7D;
    display: inline-block;
  }
  #a {
    margin: 0 100px;
    border-radius: 50px 50px 0 0;
  }
  #b, #c {
    border-radius: 0 0 50px 50px;
  }
  #c {
    margin-left: 100px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

There is another variation of the same solution where we do not have to create an outer box. Instead, we use the padding of the body element to restrict the content area. This way we achieve the same effect as in the above code without needing to create an extra div.

<div id="a"></div><div id="b"></div><div id="c"></div>
<style>
  body {
    margin: 0;
    padding: 50px;
    background: #62306D;
  }
  div {
    width: 100px;
    height: 100px;
    background: #F7EC7D;
    display: inline-block;
  }
  #a {
    margin: 0 100px;
    border-radius: 50px 50px 0 0;
  }
  #b, #c {
    border-radius: 0 0 50px 50px;
  }
  #c {
    margin-left: 100px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

3. Pseudo Elements

Here we are using pseudo elements. You know, we have three figures and each element can have ::before and ::after, which makes exactly three. So, we only need one division, which we place with the help of margins. We give it its border-radius pointing upwards and the background color. It should also be inline-block and this style should be applicable for its pseudo elements as well.
Then we are using the cascading ability of CSS to overwrite the border-radius for the pseudo elements. It is worth noting, that content property needs to be set, even if only as an empty string.

<div></div>
<style>
  body {
    background: #62306D;
  }
  div, div::before, div::after {
    margin: 42px 142px;
    width: 100px;
    height: 100px;
    background: #F7EC7D;
    display: inline-block;
    border-radius: 50px 50px 0 0;
  }
  div::before, div::after {
    content: "";
    border-radius: 0 0 50px 50px;
    margin: 100px -100px;
  }
  div::after {
    margin: -200px 100px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
florianschommertz profile image
Florian Schommertz • Edited

I like to use the body as the wrapper - I set the stage while using it's margin.
Setting flex to 1 made me happy.
Also fun: usage of rotate origin, instead of marging-top: auto

<div></div>
<div></div>
<div></div>
Enter fullscreen mode Exit fullscreen mode
body{
    background:#62306D;
    margin:50px;
    display:flex;
}
div{
    background:#F7EC7D;
    height:50%;
    border-radius:50%50%0 0;
    flex:1;
}
div:nth-child(odd){
    transform:rotate(180deg);
    margin-top:auto;
/* as an alternative to »margin-top: auto«, transform-origin 50% 100%) */
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
thincats profile image
ThinCats
<div class="wrapper">
  <div></div>
  <div></div>
  <div></div>
</div>

<style>
  body {
    margin: 50px;
    background: #62306D;
  }

  .wrapper {
    display: flex;
  }

  .wrapper > div {
    width: 100px;
    height: 100px;
    border-radius: 50% 50% 0 0;
    background: #F7EC7D;
  }

  .wrapper > div:nth-child(2n+1) {
    transform: rotate(180deg) translate(0, -100px);
  }
</style>
Enter fullscreen mode Exit fullscreen mode