📜 ⬆️ ⬇️

BEM with a human face

The sonorous abbreviation BEM came to us from Yandex labs . There, as in the case of XSLT, they decided to build BEM into an absolute: the BEM in Yandex means a whole family of utilities and approaches united by a single ideology of the block architecture of web applications. Like any totalitarian system, BEM requires adherence to strict rules in the design, not infrequently in conflict with the common sense of small projects that are not comparable in resources with Yandex. And yes, the same feeling when you read the official BEM docks.


However, as often happens in the process of evolution of large systems, under the pressure of intelligence and unlimited deadlines a technological diamond is born, as small and independent as it is valuable that others will limit. Yes, BEM with its saving severity is a clear revelation. Everyone who took communion before my eyes instantly became happy. However, after the first wave of pleasure comes the realization that the second approach to this projectile can tear mental ligaments throughout the brain volume. And now complaints are heard about the overly complex development, excessive verbosity, (attention!) Increase in the number of megabytes in HTML and CSS, and who knows what else is irrelevant.


I agree, it is difficult to take and start writing BEM without a run-up: the eye notation hurts, and the old tricks do not work, and you have to think systematically. And in general, they wrote once for years without BEM and we will write! But for easy and easy to overcome the threshold of entry, you need to make only two movements. First, lower the threshold itself by softening the BEM. And secondly, a little catch up yourself. Then the transition will be smooth and we will gently roll into the era of readable and supported CSS.


How did we get to life like that?


As always, I remind you that if you have no problems with CSS support, then we, the foolish BEMs, enviously ask you to have mercy and boldly consider the article as nonsense, rubbish, heresy, bulshit, graf-art and technology for the sake of technology. The rest, stuck in the calling flexibilities CSS, please be patient and follow me.


A little context does not hurt us, especially the historical one. To better understand where BEM leads us, it’s worth remembering where we are going from. So, briefly give the stages of formation of the style of writing CSS.


1995: Prehistoric era


<font color="red"> 

Data and presentation are mixed, it is impossible to take and change the color of all headings, the proportion of information is extremely low. And if you still remember the tables and cut pictures, then even the sixth explorer is a cake! But all this is not yet a problem, successful sites give such a return that they can be written even in assembly language.


2000: Primitivism


 h3 { color: red } 

Hooray, you can take and repaint everything with one edit. The layout is still done by tables, but the floats are sneaking up. The dotcom bubble burst, it's time to think about efficiency and support.


2005: We know how to selectors!


 div p.red h3 { color: red } 

Here it is, the glow of the fire, in the chaos of which many of us burn at work to this day. Then the sites were already able to do not only technical university students, but also experienced system programmers. They developed backend frameworks, designed databases correctly, learned how to handle the load, and even created nginx ! But at the same time they didn’t know how and didn’t want to be able to use CSS, or, especially, this nasty JavaScript. This led to Bootstrap and jQuery.


2007: Semantic CSS


 .article.new .title { color: red } 

The pepelsbey bursts into the thread of the avid beckenders and bears a kind, bright, clean. Removes tags from CSS, opens his eyes to the meaning of these in HTML, inspires a healthy way of thinking and code in the front end. More microformats and a good, usable web, as the creator intended.


2010: Back to the Stone Age with Twitter Blueprint


 <p class="text-left clearfix red"> 

Yes, many good deeds were done by our comrades, who seriously took Bootstrap as a framework, not only for admins. At that time, the Internet is growing exponentially, any working solutions are copied without looking, because you have to keep up with riveting rivals the same good. What more support - just to catch your Facebook!


2015: BEM


 .article__header--new { color: red } 

The pendulum was ottyagi-ottyagili in the direction of a quick start and doottyagyvalis: in the forehead flew hard to the cruelty of BEM. Ashamed of our past licentiousness, we are ready to rush headlong into the thorny bush of elaborate syntax, just to hide behind a powerful authority and again not to think about our CSS.


Main exaggerations: do not have global styles, do not pack everything into elements, do not look at other methodologies, don’t touch your own HTML, do not bring someone else’s CSS home. With such a strict abstinence and code, you will not get up.


One step back, two steps forward.


What is the main thing we need from BEM:


  1. No collisions
  2. No collisions
  3. And once again the absence of collisions

BEM ensures that there is no collision through isolation through namespaces. The good old concept of insulated modules. And with SASS, a whole OOP. Of course, you first need to think carefully about splitting into components, but first let's rejoice in the gifts of modularity:


  1. Readable and supported code
  2. Reuse of components
  3. Ease of testing
  4. Harmony with object nature javascript

That's all. If we manage to preserve the main value of BEM - isolation by a component, then it will be possible to create anything inside the components themselves. If you control all root styles, that is, you have all the whole code broken into namespaces, and there are no selectors outside of them, then you have achieved enlightenment and can afford everything.


It is impossible, but if you really want ...


How can humanize BEM? And it's very simple: you need to relax a little, return to common sense and remember the feeling of fan from experiments. From simple to complex, from obvious to intriguing.


See double underscore


CamelCase notation for blocks pleases the eyes of avid C-plus-plus / yavaskriptists / rubists, and also helps never to confuse blocks and elements.


 .Article { … } .Article-title { color: red } 

A little bit more and it will be quite similar to the sexy ruby ​​DSL.


Laconic modifiers


If you follow the rule "never violate the boundaries of the namespaces" and select for each block a separate element, that is, instead of two classes per node:


 <div class="Box Article"> 

make two nodes for two classes:


 <div class="Box"><div class="Article"> 

then you can simplify the naming of modifiers to the usual:


 .Article.new { … } 

And if you add the is- prefix to is- , you can directly read the styles out loud:


 .Article.is-new { … } 

The point, of course, is not behind the modifier prefixes, this is just a nice bonus. The main thing is that the Box and Article blocks will not have conflicts even if they want to, and there is no need to catch bugs from the fact that sometimes the Article module is loaded before the Box module and its styles get a different priority. But it is already so obvious!


Cascade


You can return some CSS to your BEM:


 .Article.is-new .Article-title { color: red } 

The good news is that further single attachment BEM will not let you by definition (do not repeat the structure of the HTML tree), so this is no longer possible:


 .Article .Article-title .Article-name { … } 

And of course, you absolutely cannot interfere in someone else’s namespace:


 .Article .SubmitButton .Icon { … } 

Sometimes, according to the old bad habit, I really, really want to do that. But it is impossible. The balance with the chaos must be kept, otherwise you will violate the basis of the integrity of BEM and all efforts will go down the drain.


The wise remarks of ArmorDodks and the poignant banter of vintage simply force the reader’s attention to the fact that trees are not stylized with such modifiers: all the children of a node with such a modifier will break. It is necessary to stylize trees even more strictly - directly in a place. I am sure that readers using recursive structures on the web enjoy cascading CSS every day.


Do not use BEM


Yes, if you always use BEM on the project, sometimes you can not use BEM. In leaf components, you can use free-form CSS without following any BEM principles. It is enough to pack such a “naughty” code in its own block-isolator and you can write like this:


 .WYSIWYG { h1 { … } p { … } ul li { … } } 

The strict culture of other modules will not allow them to interfere in the internal affairs of the WYSIWYG module and everything will be fine. Of course, to invest some other component in the “naughty” component will not work without the possibility of collisions, so that such “naughty” blocks can only be leaves in the component tree: they can be inserted into any components, but not any components can be inserted into them.


Such a trick can be useful not only in the case of embedding unpredictable user content. Any jQuery plugin easily wraps around in a block isolator and does not smell its entire page CSS. There are also some very large components, for example, tabular tables in a table of tables where strict adherence to BEM will bury the layout designer alive under the weight of prefixes, so it is cheaper to stick in Bootstrap. And there are still complex forms that are also more convenient and faster to make sheet elements in insulator blocks, and then to think.


Basic styles


This refers to the font size, leading, link color, bulits lists and other reset / normilize.css. Most of the inherited styles can only be escaped with a hard override of all these styles for each container. It looks superfluous for anyone who does not plan to conquer the world with its universal library of absolutely portable components. Sometimes, it is more useful to come to terms with the imperfections of the text web, than to waste energy on fighting windmills.


Having accepted this, it becomes obvious that the good old SMACSS approach to the separation of styles is perfectly ported to BEM. Basic styles remain as is. Layout becomes just a special non-leaf component. Modules, they are components, they are also blocks. States are projected onto modifiers one to one. Support for themes in BEM is generally native. And the state in the modern application should be controlled by the domain logic and then render the model through React (hands off jQuery!).


Total


And now everything has become familiar and not at all scary. You could even say that BEM with a human face is good old CSS for semantically correct HTML, only it is easier supported, it is easier to write, it is compressed better and it is executed faster.


Naked BEM is a Procrustean bed, but if you understand, accept and finish it, it becomes the seat of a fighter - cramped, but you can fly on it!


A letter called to the road


@ArmorDarks writes:


Perhaps you will be interested: More Transparent UI Code with Namespaces

Thank you, how interesting!


As far as I understand, the described techniques help to write readable HTML, using and replenishing ready-made CSS. For example, the utilitarian class u-font-size-large is applied to the node to make the font larger, and t-light to apply a theme with a lighter background to the button. In general, if you know the whole set of CSS rules, then HTML code is really easy to read and write. However, when mixing styles with the same priority, it will soon require !important , which is described in the article as a sometimes acceptable approach. To this I can not go , isagalaev raised us differently .


In BEM I was touched by the strict isolation of styles from HTML. Since CSS still needs to be known and understood, why not finally remove all the work with styles in CSS? For example, if you use .u-font-size-large for the title of the article, then:


 %u-font-size-large { font-size: x-large } .Article-title { @include %u-font-size-large } 

The article provides an example that may require additional minor style edits, even thousands of them. And the author immediately rightly objects that such minor edits speak of problems with the design. But it should be so, let's add .u-font-size-large-xx and do not have to produce any .article__title--large-xx , .post__title--large-xx , .user__title--large-xx . Here I am on the side of BEM with its explicit against implicit, and here's why.


First, here you found in someone else’s code <div class="Article-title is-xx"> inspected by the inspector, and the very first styles will be the modifier, as the most specific. In the case of .u-font-size-large-xx will have to look a little and think. Further. If you define .Article-title.is-xx through inheritance @extends .u-font-size-large you see the inspector as well .u-font-size-large , and other blocks that use the same superclass. And if you prefer @include , which is probably more logical in this case, you have already jumped right into the Article.scss file and here it is the logic of your modifier, perhaps even more complicated, but visual and in terms of SCSS.


Secondly, it is not necessary to think about what combinations of different .u-* can be, but they are all for this particular block - they lie in the Article.scss file Article.scss guaranteeing the correct semantics. All possible combinations of modifiers from a library right in front of my eyes, albeit somewhat verbose. I think this is a saving determinism. Such a Go vs C ++.


Thirdly, when the style changes, you do not need to go into .erb , .inc , .php , .js template and replace the .u-font-size-large with a new .u-font-size-large-xx in all places of use component Article , it is enough to recompile SASS. Of course, if you add a semantically new modifier for the new state of the domain entity, templates will have to be corrected. But it will be a legitimate, understandable edit, with an adequate comment in the commit, with a line in the documentation for the new state, with tests without binding to CSS.


Fourth, you can mix several modifiers (inside one component) and change them as you like, delete, refactor, without reading the code of other components and not thinking about broken tests. Difficulty falls exponentially.


And for all that is unpredictable, which changes too often or contains a lot of elements and / or modifiers, there are leafy blocks that violate all the laws of BEM, except for the namespace.


Thanks again, the avalanche is gone.


@ArmorDarks writes :


This approach ( o-btn c-btn c-btn--positive qa-modal-accept note aut. ) Allows you to create most of the unique pages without writing a single new line of CSS.

Here it is the key phrase, thank you for it. This is a watershed, the abyss in the middle, the state border, the horizon of events, finally. It is this phrase that drives a stake between two completely opposite and simultaneously equal and complementary approaches to the layout. Personally, I am on the fanatical side of “maintaining and scaling one complex project over the years, constantly changing CSS,” and your extreme “prepare a solid foundation and build a large array on it without touching CSS”. It's like patterns against frameworks. Abstract against concrete. Using BEM as an approach, people build libraries of components as frameworks. An article about the approach. It is time for the author to take a category theory course.


By the way, as Bootstrap documentation correctly suggests, such a fundamental CSS framework should be read-only, just like before the appearance of CSS and the <font> was a web: you take - and you write, using only the ready and available HTML tags, without thinking about CSS. It worked the same. But if you still allow to change such a CSS framework at the process level, that is, at the request of the business ... GOTO 1 .


')

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


All Articles