3
\$\begingroup\$

a few weeks ago I started learning Flexbox and to practice my skills I did the following exercise:

Piet Mondrian was a 20th century Dutch painter whose paintings emphasized simple geometric elements.

Inside a file called mondrian.html, create this Piet Mondrian painting (https://artmiamimagazine.com/wp-content/uploads/2019/02/Piet-Mondrian-d35kfou.jpg) using HTML and flexbox.

If you're having trouble creating the whole thing, pick a "chunk" of the painting and work on just that. Then pick another "chunk" and do that, etc. How can you combine your chunks into a single image? (think: HTML tree structure). Some students have found printing the image and numbering each rectangle helpful.

I would like to receive a review of the code. Is the use of the semantic tags correct? Is the code style right? What bad practices do I apply in the code? Have I overcomplicated myself? Is there a simpler and better way to solve the problem?

Code:

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.container {
  display: flex;
  border: 16px solid #292827;
  height: 100vh;
}

.box_A,
.box_B {
  flex: 1 0 auto;
}

.box_A {
  border-right: 8px solid #292827;
}

.box_A > div,
.box_B > div {
  height: 10%;
}

.row0,
.row1,
.row2,
.row3,
.row4,
.row5,
.row6,
.row7,
.row8,
.row9 {
  display: flex;
}

.a1 {
  flex: 1 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.a2 {
  flex: 3 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.a3 {
  flex: 2 0 auto;
  background-color: #f9e217;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.b1 {
  flex: 1 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.b1-bottom {
  flex: 1 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.b2 {
  flex: 4 0 auto;
  background-color: red;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.b3 {
  flex: 2.5 0 auto;
  background-color: #f9e217;
}

.b3-bottom {
  flex: 2.5 0 auto;
  background-color: #f9e217;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.c1 {
  flex: 1 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.c2 {
  flex: 4 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
  background-color: red;
}

.c2-bottom {
  flex: 4 0 auto;
  background-color: red;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.c3 {
  flex: 1.25 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.c3-bottom {
  flex: 1.25 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.c4 {
  flex: 1.25 0 auto;
}

.c4-bottom {
  flex: 1.25 0 auto;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.d1 {
  flex: 1 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.d2 {
  flex: 2 0 auto;
  background-color: black;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.d3 {
  flex: 2 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.d4 {
  flex: 2.5 0 auto;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.e1 {
  flex: 1 0 auto;
  background-color: #f9e217;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.e2 {
  flex: 2 0 auto;
  background-color: black;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.e3 {
  flex: 2 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.e4 {
  flex: 2.5 0 auto;
  background-color:  #0c7bbc;
}

.f1 {
  flex: 1 0 auto;
  background-color: #f9e217;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.f2 {
  flex: 2 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.f3 {
  flex: 2 0 auto;
  background-color: black;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.f4 {
  flex: 2.5 0 auto;
  background-color:  #0c7bbc;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.g1 {
  flex: 1 0 auto;
  background-color: #f9e217;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.g2 {
  flex: 2 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.g3 {
  flex: 1 0 auto;
  background-color: #f9e217;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.g4 {
  flex: 1 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.g5 {
  flex: 2.5 0 auto;
  background-color: red;
}

.h1 {
  flex: 3 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.h2 {
  flex: 1 0 auto;
  background-color: #f9e217;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.h3 {
  flex: 1 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.h4 {
  flex: 2.5 0 auto;
  background-color: red;
}

.i1 {
  flex: 2 0 auto;
  background-color:  #0c7bbc;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.i2 {
  flex: 0.5 0 auto;
  background-color: #f9e217;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.i3 {
  flex: 0.5 0 auto;
  background-color: black;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.i4 {
  flex: 3 0 auto;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.j1 {
  flex: 2 0 auto;
  background-color:  #0c7bbc;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.j2 {
  flex: 1 0 auto;
  background-color: #f9e217;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.j3 {
  flex: 2 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.j4 {
  flex: 1 0 auto;
  background-color: #f9e217;
}

.k1 {
  flex: 2 0 auto;
  background-color:  red;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.k2 {
  flex: 1 0 auto;
  background-color: black;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.k3 {
  flex: 2 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.k4 {
  flex: 1 0 auto;
  background-color: #f9e217;
}

.l1 {
  flex: 2 0 auto;
  background-color:  red;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.l2 {
  flex: 1 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.l3 {
  flex: 2 0 auto;
  background-color: black;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.l4 {
  flex: 1 0 auto;
  background-color: #f9e217;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.m1 {
  flex: 2 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.m2 {
  flex: 1 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.m3 {
  flex: 2 0 auto;
  background-color: black;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.m4 {
  flex: 1 0 auto;
}

.n1 {
  flex: 1 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.n2 {
  flex: 1 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.n3 {
  flex: 3 0 auto;
  background-color: #0c7bbc;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.n4 {
  flex: 1 0 auto;
}

.o1 {
  flex: 1 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.o2 {
  flex: 1 0 auto;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.o3 {
  flex: 3 0 auto;
  background-color: #0c7bbc;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.o4 {
  flex: 1 0 auto;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.p1 {
  flex: 2 0 auto;
  background-color: #f9e217;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.p2 {
  flex: 3 0 auto;
  background-color: #0c7bbc;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.p3 {
  flex: 1 0 auto;
}

.q1 {
  flex: 2 0 auto;
  background-color: #f9e217;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.q2 {
  flex: 3 0 auto;
  background-color: #0c7bbc;
  box-shadow: -8px -8px 0 0 #292827 inset;
}

.q3 {
  flex: 1 0 auto;
  box-shadow: 0 -8px 0 0 #292827 inset;
}

.r1 {
  flex: 1 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.r2 {
  flex: 1 0 auto;
  background-color: black;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.r3 {
  flex: 2.5 0 auto;
  box-shadow: -8px 0 0 0 #292827 inset;
}

.r4 {
  flex: 1.5 0 auto;
}


  
<div class="container">
    <div class="box_A">
      <div class="row0">
        <div class="a1"></div>
        <div class="a2"></div>
        <div class="a3"></div>
      </div>
      <div class="row1">
        <div class="b1"></div>
        <div class="b2"></div>
        <div class="b3"></div>
      </div>
      <div class="row2">
        <div class="b1-bottom"></div>
        <div class="b2"></div>
        <div class="b3-bottom"></div>
      </div>
      <div class="row3">
        <div class="c1"></div>
        <div class="c2"></div>
        <div class="c3"></div>
        <div class="c4"></div>
      </div>
      <div class="row4">
        <div class="c1"></div>
        <div class="c2-bottom"></div>
        <div class="c3-bottom"></div>
        <div class="c4-bottom"></div>
      </div>
      <div class="row5">
        <div class="d1"></div>
        <div class="d2"></div>
        <div class="d3"></div>
        <div class="d4"></div>
      </div>
      <div class="row6">
        <div class="e1"></div>
        <div class="e2"></div>
        <div class="e3"></div>
        <div class="e4"></div>
      </div>
      <div class="row7">
        <div class="f1"></div>
        <div class="f2"></div>
        <div class="f3"></div>
        <div class="f4"></div>
      </div>
      <div class="row8">
        <div class="g1"></div>
        <div class="g2"></div>
        <div class="g3"></div>
        <div class="g4"></div>
        <div class="g5"></div>
      </div>
      <div class="row9">
         <div class="h1"></div>
        <div class="h2"></div>
        <div class="h3"></div>
        <div class="h4"></div>
      </div>
    </div>
    <div class="box_B">
      <div class="row0">
        <div class="i1"></div>
        <div class="i2"></div>
        <div class="i3"></div>
        <div class="i4"></div>
      </div>
      <div class="row1">
        <div class="j1"></div>
        <div class="j2"></div>
        <div class="j3"></div>
        <div class="j4"></div>
      </div>
      <div class="row2">
        <div class="k1"></div>
        <div class="k2"></div>
        <div class="k3"></div>
        <div class="k4"></div>
      </div>
      <div class="row3">
        <div class="l1"></div>
        <div class="l2"></div>
        <div class="l3"></div>
        <div class="l4"></div>
      </div>
      <div class="row4">
        <div class="m1"></div>
        <div class="m2"></div>
        <div class="m3"></div>
        <div class="m4"></div>
      </div>
      <div class="row5">
        <div class="n1"></div>
        <div class="n2"></div>
        <div class="n3"></div>
        <div class="n4"></div>
      </div>
      <div class="row6">
        <div class="o1"></div>
        <div class="o2"></div>
        <div class="o3"></div>
        <div class="o4"></div>
      </div>
      <div class="row7">
        <div class="p1"></div>
        <div class="p2"></div>
        <div class="p3"></div>
      </div>
      <div class="row8">
        <div class="q1"></div>
        <div class="q2"></div>
        <div class="q3"></div>
      </div>
      <div class="row9">
        <div class="r1"></div>
        <div class="r2"></div>
        <div class="r3"></div>
        <div class="r4"></div>
      </div>
    </div>
  </div>

Thank you in advance for your comments.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ As an alternative to defining each rectangle in the .css file, you could add style= elements to the <div> tags. If you’re only using a given “style” in one place, and its real purpose is to draw part of a picture, it feels a bit simpler to me to put it where it’s being used. This is not a stylesheet you would ever use with another document, so there’s little reason to make it a separate file, rather than part of the <head>. But you might or might not consider that an improvement. \$\endgroup\$
    – Davislor
    Jan 17 at 13:04
  • 1
    \$\begingroup\$ For the exercise, fine; but in real life HTML isn't really the tool for the job and you'd instead use SVG. \$\endgroup\$
    – Reinderien
    Jan 17 at 13:20

1 Answer 1

3
+200
\$\begingroup\$

CSS knows variables

In CSS it is possible to initialize a variable with the following syntax: --border-color: #292827. After the initialization it can be used with shadow-box: -8 0 0 0 var(--border-color) inset. You can find more about it in the MDN docs.

Don't use classes as ids

Every element (the rows, boxes and cells) has its own class. But the purpose of a class is for it to be reused. The opposite is true for an id. An id gets only used once.

By using reusable classes we can achieve a more readable HTML and CSS. Because <div class="flex-2_5 border-right-and-bottom blue"></div> is better to read and understand than <div class="i5"></div>.

Let's fix the rows

In the given code we can easily replace the "id"s with reusable classes.

.row0,
.row1,
.row2,
.row3,
.row4,
.row5,
.row6,
.row7,
.row8,
.row9 {
 display: flex;
}

All the classes for the rows can be replaced by one row class:

.row {
  display: flex;
}

After that change we simply can mark a div as a row by <div class="row">...</div> instead of <div class=row1>...</div>, <div class=row2>...</div> and so on.

Let's fix the boxes

.box_A,
.box_B {
 flex: 1 0 auto;
}

.box_A > div,
.box_B > div {
 height: 10%;
}

In this case we can create again a single box-class. After that we can reuse it in the CSS and the HTML:

.box {
  flex: 1 0 auto;
}

.box>div {
  height: 10%;
}
<div class="box">
    <!-- all the cells -->
</div>
<div class="box">
    <!-- more cells -->
</div>

Let's fix the cells

This is the fun part. We don't need to create a class for every cell. Instead, we can extract the characteristics, put them into their own classes and reuse the created classes in the HTML.

First, we need to identify the characteristics:

  • cells can have the same width
  • cells can have the same borders (box-shadows)
  • cells can have the same color

Second, we create classes for those properties:

/* here are the sizes */
.flex-0_5 {
  flex: 0.5 0 auto;
}

.flex-1 {
  flex: 1 0 auto;
}

/* ... and more sizes */
/* here are the borders */
.border-right {
  box-shadow: var(--border-width) 0 0 0 var(--border-color) inset;
}

.border-bottom {
  box-shadow: 0 var(--border-width) 0 0 var(--border-color) inset;
}

.border-right-and-bottom {
  box-shadow: var(--border-width) var(--border-width) 0 0 var(--border-color) inset;
}
/* here are the colors */
.red {
  background-color: red;
}

.yellow {
  background-color: #f9e217;
}

.black {
  background-color: black;
}

.blue {
  background-color: #0c7bbc;
}

Final Solution

:root {
  --border-width: -8px;
  --border-color: #292827;
}

*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

.container {
  display: flex;
  border: 16px solid var(--border-color);
  height: 100vh;
}

.box {
  flex: 1 0 auto;
}

.box>div {
  height: 10%;
}

.row {
  display: flex;
}

.red {
  background-color: red;
}

.yellow {
  background-color: #f9e217;
}

.black {
  background-color: black;
}

.blue {
  background-color: #0c7bbc;
}

.flex-0_5 {
  flex: 0.5 0 auto;
}

.flex-1 {
  flex: 1 0 auto;
}

.flex-1_25 {
  flex: 1.25 0 auto;
}

.flex-1_5 {
  flex: 1.5 0 auto;
}

.flex-2 {
  flex: 2 0 auto;
}

.flex-2_5 {
  flex: 2.5 0 auto;
}

.flex-3 {
  flex: 3 0 auto;
}

.flex-4 {
  flex: 4 0 auto;
}

.border-right {
  box-shadow: var(--border-width) 0 0 0 var(--border-color) inset;
}

.border-bottom {
  box-shadow: 0 var(--border-width) 0 0 var(--border-color) inset;
}

.border-right-and-bottom {
  box-shadow: var(--border-width) var(--border-width) 0 0 var(--border-color) inset;
}
<div class="container">
  <div class="box">
    <div class="row">
      <div class="flex-1 border-right-and-bottom"></div>
      <div class="flex-3 border-right-and-bottom"></div>
      <div class="flex-2 border-right-and-bottom"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right"></div>
      <div class="flex-4 border-right red"></div>
      <div class="flex-2_5 border-right yellow"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right-and-bottom"></div>
      <div class="flex-4 border-right red"></div>
      <div class="flex-2_5 border-right-and-bottom yellow"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right"></div>
      <div class="flex-4 border-right red"></div>
      <div class="flex-1_25 border-right"></div>
      <div class="flex-1_25 border-right"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right"></div>
      <div class="flex-4 border-right-and-bottom red"></div>
      <div class="flex-1_25 border-right-and-bottom"></div>
      <div class="flex-1_25 border-right-and-bottom"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right-and-bottom"></div>
      <div class="flex-2 border-right black"></div>
      <div class="flex-2 border-right"></div>
      <div class="flex-2_5 border-right-and-bottom"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right yellow"></div>
      <div class="flex-2 border-right-and-bottom black"></div>
      <div class="flex-2 border-right-and-bottom"></div>
      <div class="flex-2_5 border-right blue"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right yellow"></div>
      <div class="flex-2 border-right"></div>
      <div class="flex-2 border-right-and-bottom black"></div>
      <div class="flex-2_5 border-right-and-bottom blue"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right-and-bottom yellow"></div>
      <div class="flex-2 border-right-and-bottom"></div>
      <div class="flex-1 border-right yellow"></div>
      <div class="flex-1 border-right"></div>
      <div class="flex-2_5 border-right red"></div>
    </div>
    <div class="row">
      <div class="flex-3 border-right yellow"></div>
      <div class="flex-1 border-right yellow"></div>
      <div class="flex-1 border-right"></div>
      <div class="flex-2_5 border-right red"></div>
    </div>
  </div>
  <div class="box">
    <div class="row">
      <div class="flex-2 border-right blue"></div>
      <div class="flex-0_5 border-right-and-bottom yellow"></div>
      <div class="flex-0_5 border-right-and-bottom black"></div>
      <div class="flex-3 border-bottom"></div>
    </div>
    <div class="row">
      <div class="flex-2 border-right-and-bottom blue"></div>
      <div class="flex-1 border-right-and-bottom yellow"></div>
      <div class="flex-2 border-right"></div>
      <div class="flex-1 yellow"></div>
    </div>
    <div class="row">
      <div class="flex-2 border-right red"></div>
      <div class="flex-1 border-right-and-bottom black"></div>
      <div class="flex-2 border-right-and-bottom"></div>
      <div class="flex-1 yellow"></div>
    </div>
    <div class="row">
      <div class="flex-2 border-right-and-bottom red"></div>
      <div class="flex-1 border-right-and-bottom"></div>
      <div class="flex-2 border-right black"></div>
      <div class="flex-1 border-bottom yellow"></div>
    </div>
    <div class="row">
      <div class="flex-2 border-right-and-bottom"></div>
      <div class="flex-1 border-right-and-bottom"></div>
      <div class="flex-2 border-right-and-bottom black"></div>
      <div class="flex-1"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right"></div>
      <div class="flex-1 border-right"></div>
      <div class="flex-3 border-right blue"></div>
      <div class="flex-1"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right-and-bottom"></div>
      <div class="flex-1 border-right-and-bottom"></div>
      <div class="flex-3 border-right blue"></div>
      <div class="flex-1 border-bottom"></div>
    </div>
    <div class="row">
      <div class="flex-2 border-right yellow"></div>
      <div class="flex-3 border-right blue"></div>
      <div class="flex-1"></div>
    </div>
    <div class="row">
      <div class="flex-2 border-right-and-bottom yellow"></div>
      <div class="flex-3 border-right-and-bottom blue"></div>
      <div class="flex-1 border-bottom"></div>
    </div>
    <div class="row">
      <div class="flex-1 border-right"></div>
      <div class="flex-1 border-right black"></div>
      <div class="flex-2_5 border-right"></div>
      <div class="flex-1_5"></div>
    </div>
  </div>
</div>

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.