📜 ⬆️ ⬇️

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

This article was conceived as a small guide to the implementation of laboratory work for students starting to learn web technology.

Design a page consisting of three multi-colored columns. The left column is 100 pixels wide, the center and right columns occupy the remaining space to the edge of the page evenly. The height of all three 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, I did it a hundred times,” because it would seem that the page has three columns, which could be simpler. But students' problems arose at all stages of problem solving: from understanding the essence and development of the structure to the protection of laboratory work.

And if learning to read the conditions of the task and oratorical skills is beyond the scope of "The Basics of Web Technologies", then reflecting the diversity of ideas that struck me that structured such a simple layout seems interesting.
')
Students demonstrated a total of about ten different solutions to this problem. From completely useless to quite acceptable. I will, of course, 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 student. Usually, it looked like this. And for obvious reasons: a student, having as his background only an understanding of the general principle of how HTML + CSS technologies work together and the simplest CSS selectors, probably could not write anything else.

<body> <div class="one"></div> <div class="two"></div> <div class="three"></div> </body> 

 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, we must understand that some young programmers have never heard of the code design rules, so its “beauty” and readability required refactoring.

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

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

 body { max-width: 1024px; } 

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

Further, for the sake of brevity, we will render common repeating styles. The colors for the columns are defined here. These styles will be used in all subsequent examples.

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

Option II


Another most obvious option was the layout in the table. The key word “column” in the problem statement played its role.

 <table class="blocks"> <td class="blocks--block__fixed-width red"></td> <td class="blocks--block green"></td> <td class="blocks--block blue"></td> </table> 

 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 is working, was rejected, since the tables should be used to present tabular data that is not the case. Students were asked to study the Flexbox Layout , as a simpler and more elegant solution to the problem.

III option


The peculiarity of the next option is an additional wrapper for the second and third columns. This wrapper makes it easier to solve the problem of allocating page space between the center and right columns without using the features of the Flexbox Layout.

 <div class="blocks"> <div class="blocks--block__fixed-width red"></div> <div class="blocks--wrapper"> <div class="blocks--block green"></div> <div class="blocks--block blue"></div> </div> </div> 

 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 the following example, first, pseudo-classes are used :first-child and :not(:first-child) to select the first and all_crome_first elements, respectively, having class="block" . Secondly, more features of the Flexbox Layout are used , in particular the flex child properties, which combine the flex-grow, flex-shrink flex-basis properties and thus determine the relative sizes of the elements.

 <div class="blocks"> <div class="block red"></div> <div class="block green"></div> <div class="block blue"></div> </div> 

 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 version is the one-time entry 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 single-type columns increases and a decision is made to use, for example, the map function to create them, then this method of styling will make it much easier. Consider this case using the following code:

 <div id="root"></div> 

 const colours = ['red','blue','green']; const blocks = colours.map(colour => <div className={"block " + colour}></div> ); ReactDOM.render( <div className="blocks">{blocks}</div>, 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 going into the work of the React library, with which components are rendered in this case, I’ll only explain that creating a large number of elements of the same type is a frequent task and the possibility of its automation is a big plus. This must be remembered at all stages of web development: design, layout, programming.

V option


And the last solution to the task, with the proviso that it consists precisely in coloring the page.

 <div class="container"></div> 

 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

Here, the background property is used, which sets the gradient color change from left to right. For a clear border, each subsequent color begins with the stop point of the previous color.

VI option


In a comment, SmithZx offered a great solution on the Grid Layout - this is a very convenient and modern alternative to existing layouts. On its basis, the most concise solution was obtained:

 <div class="blocks"> <div class="red"></div> <div class="green"></div> <div class="blue"></div> </div> 

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

CODEPEN

VII option


The following example suggested Ukrop1975 in the comments . It uses the value of the display:table property, which allows you to set table behavior for any element.

 <div class="blocks"> <div class="block fixed-width red"></div> <div class="block green"></div> <div class="block blue"></div> </div> 

 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 above blocks, without violating the rules of semantics. One of these advantages is that by default the width of the columns of the table depends on the content, and the height is the same.

VIII option


Also very interesting was the idea not to use only the display:block proposed by nebsehemvi in the comment . Such a need may arise, for example, to ensure backward compatibility, since there are still widely used browsers that do not support Flexbox and Grid .

 <div> <div class="block fixed-width red"></div> <div class="block green"></div> <div class="block blue"></div> </div> 

 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 quite an extreme option proposed dimpa91 in the comments . Here, the idea is to drop the calc function so that it can fly even on CCS2.

 <div class="blocks"> <div class="block fixed-width red"></div> <div class="block green"></div> <div class="block blue"></div> </div> 

 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 his professional opinion and special thanks to those who illustrated it with code! All the rays of good.)

Source: https://habr.com/ru/post/341262/


All Articles