DEV Community

Cover image for CSS Battle #8 - Forking Crazy
Olzhas Askar
Olzhas Askar

Posted on

CSS Battle #8 - Forking Crazy

You know what? The title says it all. Forking Crazy!
This was by far the most challenging piece of all. Even though there is another one I couldn't solve yet.
The thing is, it is difficult to match the smallest details if you don't have any clue about the measurements. You'll see below loads of some magic numbers, which came up out of nowhere, after hours (or probably minutes, to be fair) of fine-tuning, and somehow managed to settle.
I will try to explain my only solution to this problem. By the way, this is by far the longest one character-wise, resulting in whopping 1454 characters! If you care about the score, and it only makes sense if you have something below 350 characters (otherwise you'll get a score of 600 for anything else) you should go and use battle tips. To be fair, you should only use them once you are fully aware of what you've done and what you're up to, because those are mainly exploits of the errors, which browser would forgive you, like omitting closing tags.

The solution

Let's start with styling the body tag. We obviously give it a background color first and then a padding, to frame our working space. So, we limit our figure to be 50px away from the top and 130px away from the sides. Keep in mind, that the written numbers include the standard browser margin of 8px. You can, of course, define all elements relative to the whole window using margins, thus reducing the number of characters, but I chose not to do so since there is enough complexity.
The whole figure will consist of five parts:

1. The upper part

This is the part where we define the upward facing tines. It carries the name of bg, short for the background since its background is the same as the one of the body. We limit its size to 140 x 20 and give it a font-size: 0, to make our inline-block divs more readable instead of packing them like sardines in a crushd tin box.
Inside we have four half circles, to be fair, which are looking to the top. Each of them has a size of 20px and darker background color. All apart from the very first one also have margin-left: 20px. Now that look at the solution once again, I think it might have been more elegantly solved by a flexbox. For that, you'd need to give a parent class display: flex and justify-content: space-between, to avoid ugly left margins. Hmm, maybe I'll write more solutions than I planned to.

2. The stripes

At the very beginning, I seriously considered making each one of the stripes an own div. But then a revelation of a repeating-linear-gradient came to and I understood it was nonsense. Instead of styling two repeating divs with respectively a darker and lighter blues, which is the worst, or styling only a darker div and repeating it with margins, which is better than the previous proposal, we take it a level higher. We create striped id of 140 x 70 with a gradient, which goes from the left to the right. Note that the colors are repeating at the beginning and the end of each stop in order to avoid the gradient effect and make it look like an evenly colored line.

3. Tines end

This part is very similar to the upper part. It has half circles, which have a lighter blue as their background and margins between them. The background of the whole line is darker.

4. The bottom

The bottom part is of size 140 x 90 and has rounded corners of 90px. There is nothing spectacular about the bottom part.

5. The stick

Maybe you shouldn't ask me about this last piece.

Magic

We are placing a stick relatively so that we can lift it above the bottom to avoid a weird gap at the conjunction if we were placing our stick statically. It has a size of 20 x 60 and margin-left: 60px. Then we lift it ten pixels by giving it a negative value.

<div class="bg">
    <div class="upward-circle"></div>
    <div class="upward-circle left-margin"></div>
    <div class="upward-circle left-margin"></div>
    <div class="upward-circle left-margin"></div>
</div>
<div id="striped"></div>
<div class="bg darker">
    <div class="downward-circle left-margin"></div>
    <div class="downward-circle left-margin"></div>
    <div class="downward-circle left-margin"></div>
</div>
<div id="bottom"></div>
<div id="stick"></div>

<style>
  body {
    padding: 42px 122px 0;
    background: #6592CF;
  }
  .bg {
    font-size: 0;
    width: 140px;
    height: 20px;
  }
  .darker {
    background: #060F55;
  }
  .left-margin {
    margin-left: 20px;
  }
  #striped {
    width: 140px;
    height: 70px;
    background: repeating-linear-gradient(
      to right,
      #060F55 0px,
      #060F55 20px,
      #6592CF 20px,
      #6592CF 40px);
  }
  #bottom {
    width: 140px;
    height: 90px;
    background: #060F55;
    border-radius: 0 0 100px 100px;
  }
  .upward-circle {
    width: 20px;
    height: 20px;
    background: #060F55;
    border-radius: 20px 20px 0 0;
    display: inline-block;
  }
  .downward-circle {
    width: 20px;
    height: 20px;
    background: #6592CF;
    border-radius: 0 0 20px 20px;
    display: inline-block;
  }
  #stick {
    width: 20px;
    height: 60px;
    z-index: 1;
    position: relative;
    top: -10px;
    background: #060F55;
    margin-left: 60px;
  }
</style>
Enter fullscreen mode Exit fullscreen mode

Finally

And let's try to optimize it! We start it by using a shiny flexbox. By the way, make sure you know how flexbox and grid work if you are applying for a frontend position.

Our bg class now is a flexbox which would evenly distribute its content, creating an appropriate space in between.

.bg {
  width: 140px;
  height: 20px;
  display: flex;
  justify-content: space-between;
}
Enter fullscreen mode Exit fullscreen mode

You can safely remove left-margin classes next to the upward-circle and see exactly the same outcome on that part of our figure. Suddenly, the tine-body conjunction now looks broken. Let's fix that. We reduce our width to 100px and 20px padding from both sides to recreate our figure from before.

.darker {
  width: 100px;
  padding: 0 20px;
  background: #060f55;
}
Enter fullscreen mode Exit fullscreen mode

Now we can remove left-margin class completely from both HTML and CSS. And font-size: 0 as well. 1409 characters and counting. Do you feel the unbearable lightness of being yet? This is not exactly how you reduce your bundle size (you do it by removing left-pad), but that is something to keep in mind.

We can still lose some weight, though. Or, speaking more accurately, width. Since we enclosed our figure with padding from all around, let's just go and delete all that width: 140px everywhere. The elements will just take all the available space. 1355 characters.

There are two colors used throughout the task - light and dark blue. We have to have declared at least once each, but there is definitely room for improvement when you look at the current state. Light blue has to be used for body in order to give us the wanted background. What if we every other element to have a dark blue as a default background?

* * {
  background: #060f55;
}
Enter fullscreen mode Exit fullscreen mode

* * means everything which is inside of the body element would have our dark blue. bg gets broken, but let's remove background: #060F55 from the other elements. That would be .darker, #bottom, .upward-circle and #stick. Now we can fix bg by specifying the lighter blue background: #6592CF. This will break the downward facing half circles and so we set background: #6592CF for darker class. 1343 characters.

upward-circle and downward-circle read like a lot of characters, especially if you reuse them lots of times. Let's extract the common logic and rename the classes. We know, that this is the main shape:

.circle {
  width: 20px;
  height: 20px;
  display: inline-block;
}
Enter fullscreen mode Exit fullscreen mode

and these are the things that give the direction and color:

.up {
  border-radius: 20px 20px 0 0;
}
.down {
  background: #6592cf;
  border-radius: 0 0 20px 20px;
}
Enter fullscreen mode Exit fullscreen mode

In order to shovel away just a little more, we can define border-radius of the up class to be in circle instead, thus eliminating the need of up as a separate class. down will still remain the same. If you remove 4 usages of up class in the markup, you will have only 1223 characters remaining.

Since we know exactly how much space we have in our disposal, having a fixed width and height of 400 x 300 pixels, we can rephrase our stick. We fix the position and set top and left values instead. 1200 characters.

#stick {
  width: 20px;
  height: 60px;
  position: fixed;
  top: 240px;
  left: 190px;
}
Enter fullscreen mode Exit fullscreen mode

I hope you enjoyed the journey just as much as I did. Even though this challenge is basically solved using one solution, I believe this time it was deeper thought sharing. We reduced our solution by 254 characters, in which some crazy CSS hackers can fit 4 solutions of the first challenge, and it is still semantically correct, readable and maintainable. Unless you've told me there is another more elegant solution, we can be proud of ourselves.

Oldest comments (13)

Collapse
 
chinchang profile image
Kushagra Gour

A great read, yet again!

Collapse
 
beloron247 profile image
Beloron247

I have used box-shadow.

p {
    margin:50px auto;
    width:20px;
    height:110px;
    border-radius:100px;
    background:#6592CF;
    box-shadow:20px 0 #060F55,
                -20px 0 #060F55,
                40px 0 #6592CF,
                -40px 0 #6592CF,
                60px 0 #060F55,
                -60px 0 #060F55,
                0 -190px 0 100px #6592CF,
                0 30px 0 60px #060F55,
                0 150px 0 #060F55,
                0 0 0 400px #6592CF;
  }
Enter fullscreen mode Exit fullscreen mode
Collapse
 
zizifn profile image
zizifn

Nice!! I only use box-shadow for fork pointed, other part are too abstract when use box-shadow.

Collapse
 
wavesforthemasses profile image
wavesforthemasses

My solution, based on your:

<p><style>*{background:#6592CF}p{zoom:10;margin:5 auto;width:2;height:11;border-radius:1in;box-shadow:2px 0#060F55,-2px 0#060F55,4px 0#6592CF,-4px 0#6592CF,6px 0#060F55,-6px 0#060F55,0-19px 0 10px#6592CF,0 3px 0 6px#060F55,0 15px 0#060F55
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ali_shahzil99 profile image
Syed Ali Shahzil • Edited

By using flexbox make it easy and simple


div id="a"
    div id= "a1" div
    div id="a2"  div
    div id= "a1" div
    div id="a2"  div
    div id= "a1" div
    div id="a2"  div
    div id= "a1" div
 div
 div id="b" div
 div id="c" div



  body {
    margin: 0;
    background: #6592CF;
    display:flex;
    align-items:center;
    padding-top:50px;
    flex-direction:column;
    position:relative;
   
    
  }
  #a {
    display:flex;
    align-items:center;
    flex-direction:row;
  }
  #a1{
   width:20px;
   height:100px;
   background:#060F55;
   border-radius:10px 10px 0px 0px;
  }
  #a2{
   width:20px;
   border-radius:0px 0px 10px 10px;
   height:110px;
   margin-bottom:-10px;
   background:#6592CF;
   z-index:2;
  }
  #b{
    width:140px;
    height:100px;
    background:#060F55;
    border-radius:0px 0px 75px 75px;
  }
  #c{
    margin-top:-2px;
    width:20px;
    height:150px;
    background:#060F55;
    position:absoulte;
    z-index:3;
  }


Collapse
 
universalxeno profile image
UniversalXeno

Hey, can you tell me about your div placement corresponding to the solution you have provided?

Thanks in advance!

Collapse
 
ali_shahzil99 profile image
Syed Ali Shahzil

HTML code is not showing in the comment. How can I show the HTML code?

Collapse
 
gowravkumar profile image
Gowrav-Kumar

body{
background: #6592CF;
}
.botrec{
background: #060F55;
height: 60px;
width:20px;
margin-top: 245px;
margin-left: 182px;
}
.circle{
background: #060F55;
height: 140px;
width: 140px;
border-radius: 100px;
margin-top: -195px;
margin-left: 122px;
}
.dbra{
background: #060F55;
height: 140px;
width: 20px;
border-radius: 100px / 100px;
margin-top: -200px;
margin-left: 122px
}
.bra{
background: #6592CF;
height: 110px;
width: 20px;
border-radius: 100px / 100px;
margin-top: -140px;
margin-left: 142px;
}
.dbrb{
background: #060F55;
height: 110px;
width: 20px;
border-radius: 100px / 100px;
margin-top: -110px;
margin-left: 162px;
}
.brb{
background: #6592CF;
height: 110px;
width: 20px;
border-radius: 100px / 100px;
margin-top: -110px;
margin-left: 182px;
}
.dbrc{
background: #060F55;
height: 110px;
width: 20px;
border-radius: 100px / 100px;
margin-top: -110px;
margin-left: 202px;
}
.brc{
background: #6592CF;
height: 110px;
width: 20px;
border-radius: 100px / 100px;
margin-top: -110px;
margin-left: 222px;
}
.dbrd{
background: #060F55;
height: 140px;
width: 20px;
border-radius: 100px / 100px;
margin-top: -110px;
margin-left: 242
}

Collapse
 
aaryansinha16 profile image
aaryansinha16

body{
margin:0;
background:#6592CF;
}
#rect {
width: 140px;
height: 150px;
background: #060F55;
position:absolute;
top:100px;
right:130px;
border-radius:10px 10px 70px 70px;
}
#srect{
width:20px;
height:50px;
background:#060F55;
position:absolute;
top:250px;
right:190px; //Note
}
#db1,#db2,#db3,#db4,#lb1,#lb2,#lb3{
width:20px;
height:120px;
border-radius:10px 10px 10px 10px;
position:absolute;
}
#db1,#db2,#db3,#db4{
top:50px;
background:#060F55;
}
#lb1,#lb2,#lb3{
background:#6592CF;
top:40px;
}
#db1{
right:250px
}
#db2{
right:210px;
}
#db3{
right:170px;
}
#db4{
right:130px;
}
#lb1{
right:230px;
}
#lb2{
right:190px;
}
#lb3{
right:150px;
}

Collapse
 
nando123 profile image
Nancy Do

1 div solution:

<div></div>

<style>
  body {
    background: #6592CF;
  }

  *::after, *::before {
    position: fixed;
    content: "";
    background: #060F55;
  }

   div {
    margin: 110px 122px;
    width: 140px;
    height: 140px;
    background: #060F55;
    border-radius: 0 0 50% 50%;
  }

    div::after {
    color: #060F55;
    margin: -60px 0;
    width: 20px; 
    height: 110px; 
    border-radius: 30px 30px 30px 30px;
    box-shadow: 
      20px 0 #6592CF,
      40px 0,
      60px 0 #6592CF,
      80px 0,
      100px 0 #6592CF,
      120px 0;
  }

  div::before {
    margin: 130px 60px;
    width: 20px; 
    height: 70px;
  }

</style>
Enter fullscreen mode Exit fullscreen mode
Collapse
 
philgood7 profile image
Philgood7

I used a grid:

"div class="cont"
  (div id="A" class="clair")(/div)
  (div id="B" class="clair")(div class="bu")(/div)(/div) 
  (div id="C" class="foncé") (div class="bd")(/div)(/div) 
  (div id="D" class="clair")(div class="bu")(/div)(/div)
  (div id="E" class="foncé")(div class="bd")(/div)(/div)
  (div id="F" class="clair")(div class="bu")(/div)(/div)
  (div id="G" class="foncé")(div class="bd")(/div)(/div)
  (div id="H" class="clair")(div class="bu")(/div)(/div)
  (div id="I")(div class="Q")(/div)(/div)
  (div id="J" class="foncé")(/div)
(/div)

(style)

*{margin:0;
padding:0;}
body{background:#6592CF;}

.clair{background:#6592CF;}
.foncé{background:#060F55;}

.cont{
display:grid;
grid-template-columns: repeat(7,20px);
grid-template-rows: 50px 110px 90px 50px;
grid-template-areas:
"a a a a a a a"
"b c d e f g h"
"i i i i i i i"
"k k k J l l l";
justify-content: center;
align-content: end;

}

'#A{grid-area:a;}
'#B{grid-area:b;}
'#C{grid-area:c;}
'#D{grid-area:d;}
'#E{grid-area:e;}
'#F{grid-area:f;}
'#G{grid-area:g;}
'#H{grid-area:h;}
'#I{grid-area:i;}
'#J{grid-area:3/4/5/5;}

/bd pour bâton down (bâton vers le bas)/
.bd{
position: absolute;
width: 20px;
height: 110px;
background: #6592CF;
border-bottom-left-radius:10px;
border-bottom-right-radius:10px;
z-index:7;
}

/bd pour bâton up (bâton vers le haut)/
.bu{
position: absolute;
width: 20px;
height: 110px;
background: #060F55;
border-top-left-radius:10px;
border-top-right-radius:10px;
z-index:7;
}

/* Q pour le cul de la fourchette, la partie basse*/
.Q{
position: absolute;
width: 140px;
height: 90px;
background: #060F55;
border-bottom-left-radius:70px;
border-bottom-right-radius:70px;
z-index:7;
}

Collapse
 
cpcjain profile image
cpcjain • Edited
`<div class="fork">
  <div class="dblue"></div>
   <div class="lblue"></div>
   <div class="dblue"></div>
   <div class="lblue"></div>
   <div class="dblue"></div>
   <div class="lblue"></div>
   <div class="dblue"></div> 
</div>
 <div class="semi-circle"></div>
<div class="handle"></div>
<style>

  .fork{
    position: absolute;
    top: 50px;
    left: 131px;
    height: 150px;
    width: 140px;
    background-color:#6592CF;
    display: flex;
    flex-direction: row;
  }
  body{
    background-color:#6592CF;
    margin:0;
    padding: 0;
    box-sizing: border-box;
  }
  .dblue{
    height:112px;
    width: 20px;
    background-color:#060F55;
    border-radius: 25px 25px 0 0;

  }
  .lblue{
    height:110px;
    width: 20px;
    background-color:#6592CF;
    border-radius: 0 0 25px 25px;
    z-index: 1;
  }
  .semi-circle{
   height: 150px;
    width: 140px;
    position: absolute;
    left: 131px;
    top: 100px;
    border-radius: 0 0 50% 50%;
     background-color:#060F55;
    }
  .handle{
    width: 5vw;
    height: 75px;
    position: absolute;
    bottom:0;
    left: 190px;
    background-color:#060F55
  }
</style>`
Enter fullscreen mode Exit fullscreen mode
Collapse
 
subashkarki68 profile image
Subash Karki

body{
background:#6592CF;
display:flex;
align-items:center;
justify-content:center;
}
.fork-top >*{
display:flex;
gap:20px;
position:relative;
top:-45
}
div {
width: 20px;
height: 110px;
background: #060F55;
border-radius: 100vh 100vh 0 0;
}
.out-pronge{
position:absolute;
top:50;
left:150;

}
.out-pronge *{
background:#6592CF;
border-radius: 100vh;
}
.base i{
position:absolute;
width:140px;
height:100px;
bottom:50;
z-index:-1;
left:50%;
transform: translate(-50%);
background: #060F55;
border-radius: 0 0 100vh 100vh;
}
.base .b{
bottom:-10;
width:20px

}