DEV Community

Cover image for CSS Battle #11 - Eye of Sauron
Olzhas Askar
Olzhas Askar

Posted on • Updated on

CSS Battle #11 - Eye of Sauron

I must admit, it is difficult to finish things. You start enthusiastically a lot of things in parallel and then realize you can finish none of them. This time I want to endure. Only two left, if you only consider the first battle. By the way, many thanks to Kushagra Gour & Kushagra Agarwal for adding new battles regularly!

1. Initial solution

This time let's try to gradually change the design of the solution, just like you would do in the real development.
Here is how solved it the first time. Three divs, each with different styles, absolutely positioned relative to body.

<div id="l"></div>
<div id="c"></div>
<div id="r"></div>
<style>
  body {
    background: #191210;
    margin: 0;
    position: relative;
  }
  #l {
    width: 60px;
    height: 30px;
    border-bottom-left-radius: 50px;
    border-bottom-right-radius: 50px;
    border: 20px solid #ECA03D;
    border-top: 0;
    z-index: 1;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: 0 0 0 -150px;
  }
  #c {
    width: 100px;
    height: 100px;
    background: repeating-radial-gradient(circle at 50%, #84271C, #84271C 35%, #191210 35%, #191210 100%);
    border: 20px solid #ECA03D;
    border-radius: 100px;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -70px 0 0 -70px;
  }
  #r {
    width: 60px;
    height: 30px;
    border-top-left-radius: 50px;
    border-top-right-radius: 50px;
    border: 20px solid #ECA03D;
    border-bottom: 0;
    z-index: 1;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -50px 0 0 50px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

2. Fixed position

Because we positioned all divs absolutely is our zero margin redundant. Furthermore, when we don't have a margin anymore, instead of using body, we could use a wildcard. This can also benefit us in reducing all positioning to position: fixed for all elements.

<style>
  * {   // body -> *
    // position: relative;
    position: fixed;
  }
  #l {
    // position: absolute;
  }
  #c {
    // position: absolute;
  }
  #r {
    // position: absolute;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

3. Share position

top and left can also be moved to the wildcard, since we are using them for every element.

<style>
  * {
    top: 50%;
    left: 50%;
  }
  #l {
    // top: 50%;
    // left: 50%;
  }
  #c {
    // top: 50%;
    // left: 50%;
  }
  #r {
    // top: 50%;
    // left: 50%;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

4. No z-index

We actually don't need z-index. Sometimes I add things, which seem to be correct, even though they are not necessary. Let's remove it as it only leads to confusion whomever looks at it.

<style>
  #l {
    // z-index: 1;
  }
  #c {
    // z-index: 1;
  }
  #r {
    // z-index: 1;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

5. Unify border radii

Instead of writing out each of the four possible border radiuses (may I please supporters of both plural types?), we can you use a shorthand with four values.

<style>
  #l {
    // border-bottom-left-radius: 50px;
    // border-bottom-right-radius: 50px;
    border-radius: 0 0 50px 50px;
  }
  #r {
    // border-top-left-radius: 50px;
    // border-top-right-radius: 50px;
    border-radius: 50px 50px 0 0;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

6. Share borders

Since the borders for all elements are also the same, we can move them to the wildcard as well.

<style>
  * {
    border: 20px solid #ECA03D;
  }
  #l {
    // border: 20px solid #ECA03D;
  }
  #c {
    // border: 20px solid #ECA03D;
  }
  #r {
    // border: 20px solid #ECA03D;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

7. Simplify background

For the central circle background, we don't really need to repeat it. One time is enough.

<style>
  #c {
    // background: repeating-radial-gradient(circle at 50%, #84271C, #84271C 35%, #191210 35%, #191210 100%);
    background: radial-gradient(#84271C 35%, #191210 35%);
  }
</style>
Enter fullscreen mode Exit fullscreen mode

8. Rotate

The left and the right side of the circle are same. We only need to rotate one and place it differently to obtain the second. So we can create a common class named half and convert l and r to classes as well. Now the whole appearance will be held by half and the other two will only place and rotate. Let's look at the whole code again.

<div class="half l"></div>
<div id="c"></div>
<div class="half r"></div>
<style>
  * {
    background: #191210;
    position: fixed;
    top: 50%;
    left: 50%;
    border: 20px solid #ECA03D;
  }
  .half {
    width: 60px;
    height: 30px;
    border-radius: 0 0 50px 50px;
    border-top: 0;
  }
  .l {
    margin: 0 0 0 -150px;
  }
  #c {
    width: 100px;
    height: 100px;
    background: radial-gradient(#84271C 35%, #191210 35%);
    border-radius: 50%;
    margin: -70px 0 0 -70px;
  }
  .r {
    transform: rotate(180deg);
    margin: -50px 0 0 50px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

9. Remove margins

We are using fixed position anyways, so margins will only mess up our layout. They collapse, they affect each other.
We better set top and left more precisely.

<div class="half l"></div>
<div id="c"></div>
<div class="half r"></div>
<style>
  * {
    background: #191210;
    position: fixed;
  }
  .half {
    width: 60px;
    height: 30px;
    border-radius: 0 0 50px 50px;
    border: 20px solid #ECA03D;
    border-top: 0;
  }
  .l {
    top: 50%;
    left: 50px;
  }
  #c {
    width: 100px;
    height: 100px;
    background: radial-gradient(#84271C 35%, #191210 35%);
    border: 20px solid #ECA03D;
    border-radius: 50%;
    top: 80px;
    left: 130px;
  }
  .r {
    transform: rotate(180deg);
    top: 100px;
    left: 250px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

10. Some relativity

After reading a couple of chapters of [Lea Verou's book][2], I was fascinated with relative units. Sure, you know relative is better than absolute. But when writing JSS modules, it is easy to neglect their power, favoring simplicity instead. So here we can set a font size to be ten pixels, which will equal to one em. All of the other measurements are bound to it as a reference. So, whenever we change the font size in one place, the whole design will scale gracefully.

<div class="half l"></div>
<div id="c"></div>
<div class="half r"></div>
<style>
  * {
    background: #191210;
    position: fixed;
    font-size: 10px;
  }
  .half {
    width: 6em;
    height: 3em;
    border-radius: 0 0 5em 5em;
    border: 2em solid #ECA03D;
    border-top: 0;
  }
  .l {
    top: 15em;
    left: 5em;
  }
  #c {
    width: 10em;
    height: 10em;
    background: radial-gradient(#84271C 35%, #191210 35%);
    border: 2em solid #ECA03D;
    border-radius: 50%;
    top: 8em;
    left: 13em;
  }
  .r {
    transform: rotate(180deg);
    top: 10em;
    left: 25em;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

And I think this is it. Any suggestions?

Oldest comments (3)

Collapse
 
stiv_ml profile image
Stiv Marcano

I managed to do 493 characters using just pseudo-elements and borders! thanks for sharing

Collapse
 
pheeria profile image
Olzhas Askar

I've managed to make with 355. But my code is ugly and minified.

Collapse
 
nando123 profile image
Nancy Do

1 div solution

<div></div>
<style>
  body {
    background: #191210;
  }

  div {
    margin: 125px auto;
    width: 50px;
    height: 50px;
    border-radius: 50%; 
    background: #84271C;
    box-shadow: 0 0 0 25px #191210, 0 0 0 45px #ECA03D;
  }

  div::before, div::after {
    margin: 25px -125px;
    content: ""; 
    position: fixed; 
    width: 60px; 
    height: 30px; 
    border-radius: 50% / 0 0  100% 100%;
    background: #191210;
    border: 20px solid #ECA03D;
    border-top: 0;
  }

  div::after {
    margin: -25px 75px;
    transform: rotate(180deg)
  }
</style>
Enter fullscreen mode Exit fullscreen mode