The task of a page in three columns, one of them is a hundred pixels

This article was intended as a small guide to doing lab work for students starting to learn web technology.

Design a page consisting of three colorful columns. The left column is 100 pixels wide, the center and right columns occupy all the space remaining to the edge of the page evenly. The height of all three is 100% of the page. There should be no scrollbar and white stripes around the page.

After several years of work in front-end development, tasks like this are classified as “5 minutes, did it a hundred times”, because, it would seem, a page in three columns, which could be simpler. But students had problems at all stages of solving the problem: from understanding the essence and developing the structure to protecting the laboratory work.

And if, learning to read the conditions of the task and oratory lies beyond the subject of the Basics of Web Technologies, then to reflect the variety of ideas that struck me that struck me in such a simple layout struck me as interesting.

Students demonstrated a total of about ten different solutions to this problem. From completely useless to completely acceptable. Of course, I will consider only the sane half, that is, there will be five examples reproduced by me + several suggested by the community in the comments.

I option


The first option is quite a student. Usually, everything looked like this. And for obvious reasons: a student, having only an understanding of the general principle of the combination of HTML + CSS technologies and the simplest CSS selectors as a background, probably could not write anything else.


html, body {
  width: 100%;
  height: 100%;
  margin: 0;
  display: flex;
}
.one {
  width: 100px;
  height: 100%;
  background: red;
}
.two {
  width: calc(50% - 50px);
  height: 100%;
  background: green;
}
.three {
  width: calc(50% - 50px);
  height: 100%;
  background: blue;
}

CODEPEN

Moreover, it must be understood that some young programmers have never heard of the rules for designing the code, so its "beauty" and readability required refactoring.

So, here we have several antipatterns: insignificant class names, repeated repetition of the code, as well as the lack of a container and, as a result, stylization body. At this stage, students were immersed in the study of the naming conventions in BEM and the principles of DRY, DIE, KISS, SOLID, YAGNI .

I would like to separately tell you why I forbid to hang styles on body, since there was no single answer on the network the first time. This decision came from personal practice: initially in one of the projects, the following was set:

body {
  max-width: 1024px;
}

As a result, when creating a new page, on which the design was a block stretched to full width, there were problems. Since, according to the rules of CSS, a child element physically cannot be larger than a parent. Quite a lot of time was spent on fixing this problem and, as a result, the rule was formulated that “do not hang any significant styles on the page body”.

Next, for brevity, we make general repeating styles. The colors for filling the columns are defined here. These styles will be used in all subsequent examples.

.red {
  background: red;
}
.green {
  background: green;
}
.blue {
  background: blue;
}

II option


Another most obvious option was the layout in the table. The keyword “column” played a role in the formulation of the problem.


html, body {
  margin: 0;
  width: 100%;
}
.blocks {
  height: 100vh;
  width: 100%;
  border-collapse: collapse;
}
.blocks--block__fixed-width {
  width: 100px;
}
.blocks--block {
  width: calc(50% - 50px);
}

CODEPEN

This option, although it was working, was rejected, since tables should be used to represent tabular data that does not have a place to be. Students were invited to study Flexbox Layout as a simpler and more elegant solution to the task.

III option


A feature of the following option is an additional wrapper for the second and third columns. This wrapper makes it easier to solve the problem of distributing page space between the center and right columns without using the capabilities of Flexbox Layout.


html, body {
  margin: 0;
}
.blocks, .blocks--wrapper {
  display: flex;
  height: 100vh;
}
.blocks--wrapper {
  width: calc(100% - 100px);
}
.blocks--block {
  width: 50%;
}
.blocks--block__fixed-width {
  width: 100px;
}

CODEPEN

IV option


In this example, firstly, uses pseudo:first-child and :not(:first-child)to isolate respectively the first and vseh_krome_pervogo elements having class="block". Secondly, more features of Flexbox Layout are used , in particular, the property of child elements flex, which combines the properties flex-grow, flex-shrink и flex-basisand, thus, determines the relative sizes of the elements.


html, body {
  margin: 0;
}
.blocks {
  display: flex;
  height: 100vh;
}
.block:first-child {
  flex: 0 0 100px;
}
.block:not(:first-child) {
  flex: 1 1 50%;
}

CODEPEN

A big advantage of the previous option is a single occurrence depending on the width of the left column. This greatly facilitates the support and further development of the project.

The next point that I want to emphasize separately: if the number of columns of different types increases and a decision is made to use, for example, a function mapto create them, such a stylization method will make this much easier. Consider this case using the following code as an example:


const colours = ['red','blue','green'];
const blocks = colours.map(colour => 
      
); ReactDOM.render(
{blocks}
, document.getElementById('root') );

#root, html, body {
  margin: 0;
}
.blocks {
  display: flex;
  height: 100vh;
  width: 100%;
}
.block:first-child {
  flex: 0 0 100px;
}
.block:not(:first-child) {
  flex: 1 1 50%;
}

CODEPEN

Without delving into the work of the React library, with the help of which the components are rendered in this case, I will only explain that creating a large number of elements of the same type is a frequently encountered task and the possibility of its automation is a big plus. This should be remembered at all stages of web development: design, layout, programming.

V option


And the last solution to the problem, only with the caveat that it consists precisely in coloring the page.


html, body {
  margin: 0;
}
.container {
  width: 100%;
  height: 100vh;
  background: linear-gradient(
    to right, 
    red 100px, 
    green 100px,
    green calc(50% + 50px),
    blue calc(50% + 50px)
  );
}

CODEPEN

A property is used here backgroundthat sets the gradient color change from left to right. For a clear border, each subsequent color starts at the breakpoint of the previous color.

VI option


In a comment, SmithZx suggested an excellent solution on the Grid Layout - this is a very convenient and modern alternative to existing layouts. Based on it, it turned out, probably, the most concise solution:


html, body {
  margin: 0;
}
.blocks {
  display: grid;
  height: 100vh;
  grid-template-columns: 100px 1fr 1fr;
}

CODEPEN

VII option


The following example suggested Ukrop1975 in a comment . It uses a property value display:tablethat allows you to set table behavior for any elements.


html, body {
  margin: 0;
}
.blocks {
  display: table;
  width: 100%;
  height: 100vh;
  table-layout: fixed;
}
.block {
  display: table-cell;
  width: 50%;
}
.block.fixed-width {
  width: 100px;
}

CODEPEN

This approach allows you to use all the advantages of tables over blocks without violating the rules of semantics. One of these advantages is that, by default, the width of the table columns depends on the content, and the height is the same.

VIII option


Also very interesting was the idea of ​​not using only the display:blockone proposed by nebsehemvi in the commentary . Such a need may arise, for example, to provide backward compatibility, since browsers that do not support Flexbox and Grid are still widely used .


html, body {
  margin: 0;
}
.block {
  display: block;
  float: left;
  height: 100vh;
  width: calc((100% - 100px)/2); 
}
.fixed-width {
  max-width: 100px; 
}

CODEPEN

IX option


And a very extreme version proposed by dimpa91 in the comment . Here the idea is to abandon the function calcso that it flies even on CCS2.


body, html {
  margin: 0;
}
.blocks {
  margin-left: 100px;
}
.block.fixed-width {
  width: 100px;
  margin-left: -100px;
}
.block {
  width: 50%;
  height: 100vh;
  float: left;
}

CODEPEN

Thanks to everyone who expressed their professional opinion and a special thank you to those who illustrated it with a code! All the rays of good.)

Also popular now: