
Hello to all! The time has come to inform that we expect to release a
new book on CSS before the end of February, which is recommended to everyone who has already
mastered MacFarland (so far we have the closest reprint in January).
Today, you are invited to translate the article by China Grant (published in June), in which the author presents his point of view on CSS and actually explains what he wanted to say in his book. We read and comment!

I spent a lot of time thinking about what “CSS-based thinking” is. It seems that some manage to "learn" him, and others - no. I think that if I could articulate clearly what this worldview is about, maybe the CSS itself would become clearer for those who are torn with them. This is partly why I sat down and wrote the book "CSS for Professionals."
')
Today I want to once again approach this problem. Consider three key characteristics of CSS that distinguish this language from traditional programming languages. CSS is robust, declarative, and context sensitive. I think understanding these aspects of a language is a key prerequisite for becoming a CSS master.
CSS resistantIf you accidentally delete a snippet of code in a JavaScript file, the application or web page where it is used will almost certainly crash or hang, and the script (or even the entire page) will fail. If you do the same in CSS, then maybe you will not notice anything. Practically all the rest of the code except the deleted fragment will continue to work as it should.
This property is called “
resilience ”. HTML and CSS are specially designed for fault tolerance. If a problem occurs, the browser throws an error; otherwise, it simply ignores this part of the code and goes on.
From the point of view of debugging, this may seem absurd: if the program does not throw out errors, how can we know that something went wrong? But this is the most important aspect of the CSS device. It is woven into the fabric of the tongue itself. I admit it takes time to get used to it. However, once you understand this, you can safely move on to using features not supported in all browsers. This is how the progressive development of the site or application is ensured.
Consider this example with a grid layout. It works in both browsers that support the grid, and in browsers that do not support the grid. In those browsers where the grid is not supported, the layout will be slightly uneven (the exact dimensions of the elements may vary), but the page will still be laid out just like it should:
.portfolio { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); } .portfolio__item { display: inline-block; max-width: 600px; }
A browser that does not understand the two grid declarations will ignore them, and it will be possible to complete the work thanks to other rules. In turn, the browser that understands the grid uses a grid layout and will ignore the inline-block declaration (since this is how the grid is designed). Jen Simmons, half in jest, calls this phenomenon “
Quantum CSS ”. You take some CSS capability and “both use and not use at the same time. But it both works and does not work at the same time. ”
Such a phenomenon of "safeguarding" behavior is an integral part of working with CSS, but it is alien to most traditional programming languages.
CSS is declarativeIn JavaScript, we write specific step-by-step instructions that describe how a program should come to some result. In CSS, you tell the browser exactly what you want to see on the screen, and the browser finds a way to do it. To understand this is very important. If you learn it, CSS
will do all the hard work for you , and if you don’t learn it, you will be up to the core of the CSS language, and you will be disappointed time after time.
When writing CSS, you actually set the constraint system. We do not indicate to the browser where each specific element on the page should be, but we inform you what indents between them should be, after which the browser puts everything in its place. You do not indicate to the browser (at a minimum, should not indicate) what height the container should be. You allow the browser to determine this for itself at the time of display, when it knows the contents of the container, what other styles are used in this context, and what is the available width of the viewing area.
You have to take into account too many variables. The essence of CSS is to organize the process so that you can not worry about all these variables. Set a system of restrictions. The language itself will take care of the details.
Simple exampleLet's look at this sample CSS:
font-size: 2em
. What does this code do? “Increases font size,” you say. But this is not all. It also corrects text line breaks inside the container, since now there are fewer words in each line. Accordingly, this often increases the number of text lines, and also increases the height of the container so that these new lines fit in it. When you change the height of the container, all the text located on the page under this container will move accordingly. Finally, the above code also sets the local
em
value. The values ​​of all other properties, which were used in determining the units of
em
, will have to be recalculated.
This announcement alone generates a whole plume of changes on the page. And all of them are designed to achieve exactly what you must strive for: the content always fits on the page, the elements do not overlap each other at random, and all the properties depending on the font size (say, internal indents) are adjusted. You do not have to think about all these details. The browser itself performs all the listed calculations, and does it by default.
If you want none of this to happen - this can also be done. You can severely limit the height of the container to
max-height
and
overflow: auto
properties. You can override the indentation so that they are measured in units of
rem
or
px
, that is, they are not recalculated after the font size. This opens up an interesting aspect of working with CSS: sometimes you don’t tell the browser what it should do, and, in fact, prohibit it from doing something.
Mesh advantagesHowever, in CSS there are new features that are even cooler. The most typical examples are Flexbox and Grid. Just a few ads - and you have an exceptionally flexible mesh layout that just works. Do not have to worry about numerous special cases. In fact, you order the browser: “put these blocks in columns of 400 pixels wide each”, and the browser does it for you. For everything you need about three lines of code.
If you tried to do it imperatively, you would have to deal with a lot of strange scenarios. What if a word gets too long in one of the blocks? What if the viewport is too narrow? And if very wide? What if there is a whole sheet of content in one element, and just a few words in another? True, it is likely that in CSS you will not have to think about any of this. Everything is thought out for you and laid down in the specifications, and the browser follows the rules for you. This is the power of declarative language.
Of course, there is no cost without compromise. If the declarative language does not support any necessary opportunity for you (say, “to tile”), it is necessary to rely on grandfathers tricks or on JavaScript. Moreover, the development of CSS was largely devoted to the fight with such things for many years. Fortunately, with the development of Flexbox and Grid, we can do much more, and without any hacks (yes, loose elements are a hack). If in this situation you are still missing something, I recommend reading about
CSS Houdini , which are just starting to take root in browsers.
CSS is context sensitiveIn the React era, we adopted an exceptionally practical approach: modular, component-based development. It is well in line with recommended CSS practices, along with BEM, SMACSS, and CSS-in-JS. I do not want to downplay the values ​​of all these possibilities, since they play a key role in creating large-scale applications. But I think it’s equally important to recognize that CSS is not 100% modular, and should not be.
There are two reasons for this. The first and most obvious one is that the application should be designed in global styles. Almost always you need to set the headset and font size at the page level, which will be used by default. After that, these values ​​will be inherited by all descendant elements, which will not explicitly override them. You also need some aspects of your design to be systematically applied across the entire page: color theme, rounding radii for blocks, block shading, and overall margins. More local styles, acting in parts of the page, are applied in the context of these global styles.
The second, more subtle reason is that the work of CSS and your design decisions depend on the context of the page. Suppose we apply the following CSS styles to an element on the page:
.the-thing { position: absolute; top: 10px; left: 10px; }
What will this code do? Not knowing exactly where this element is located within the DOM, and what styles are applied on the rest of the page, we cannot answer this question. Absolute placement is done relative to the nearest ancestor element, and such positioning will be different depending on which ancestor we are talking about and which placement was applied to it.
Moreover, your ability (or impossibility) to overlap elements will largely depend on where these two elements are located in the DOM. Mixing elements in a DOM can drastically affect the layout of elements and how they overlap each other. That is why the document flow and overlay contexts are fundamental (although sometimes complex) topics.
The contextual nature of CSS has developed in part because of the design. If an engineer is designing a bridge, then you cannot just look at the drawing and say: “everything is fine, only I do not like this beam; take her away. ” If you remove one beam, it will affect the structural unity of the entire bridge. Similarly, it is enough to change any design element - and all other elements on the screen will be perceived differently. Often it is necessary to arrange several elements at once in close unity with each other.
For example, if you increase the heading on one of the tiles, it will become more visible to the user, and because of this, other elements on the screen will seem less important. Here the restrictions do not lie in the plane of physics, as in the construction of a bridge; it's about more “humanitarian” laws affecting human perception. Elements of the page are reflected on the screen, which has its own physical characteristics, and when working, it is necessary to take into account the realities of the physical world and how we perceive it.
As you know, the software architecture is subject to the
principles of modularity and encapsulation . This approach is also justified at the code level, since the code is complex, and the described method allows to break the problem into digestible fragments. However, it should be noted that this approach is imperfect. In CSS, you can never completely abstract from what happens in a particular module.
ResultsThe three aspects described distinguish CSS from traditional programming languages. These differences may not immediately fit in the head, but they are the most strengths of CSS. I would venture to suggest that developers, who will be able to perceive and how these principles should be learned, have been achieved in CSS real heights.