CSS Battle #4 - Ups n Downs
Tags: html, css, webdev, tutorial
Published: 2019-06-19 19:09:40

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.

```css
<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>
```

## 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][2]. In this outer box, we style three divs to be `inline-block` (notice how all of them are _glued_ together to avoid [unwanted spaces][3]). Finally, their positioning is achieved by using margins.

```css
<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>
```

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.

```css
<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>
```

## 3. Pseudo Elements

Here we are using [pseudo elements][4]. 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.

```css
<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>
```

[1]: https://cssbattle.dev/play/4
[2]: https://zellwk.com/blog/css-positions/
[3]: https://css-tricks.com/fighting-the-space-between-inline-block-elements/
[4]: https://developer.mozilla.org/en-US/docs/Web/CSS/::after