BEM with a human face and backend integration

    Layout of modern web-projects is complicated, long and expensive. It would seem that with the transition of IE to automatic updates, HTML5, the end of support for Win XP, we all need to live in a fabulous country with a pony and a rainbow. Why didn’t it become easier?

    • HTML5 and CSS3 gave the web the ability to create a UI that is almost as good as the complexity and responsiveness of desktop applications. Nothing comes easy, HTML, CSS and JS are many times more. Previously, three files were enough for us: styles.css , stupid-ie-must-die.css , scripts.js . Now the number of scripts, styles, downloadable fonts, pictures is measured in tens and hundreds. There was a need for minification, acceleration of rendering and organization of all this junk in the file system.
    • Sites gradually ceased to be a collection of related hypertext pages and became web applications. If earlier for many sites it was enough to make up the “main” and “internal” pages, now everything is not so simple. The number of design layouts easily reaches tens and hundreds.
    • We all heard about landing page, a / b testing and a multiple increase in the conversion for "just like that". We will leave behind the question of the effectiveness of these techniques. Design began to be redone often - this is a fact. Changes and support are known to be much more expensive and more complicated than development.
    • Mobile devices and the need for responsive design have appeared. Testing has become harder and longer. The cycle of fixing bugs found during testing has become longer. UI testing is almost impossible to automate, with the growth of functionality, the time for regression testing is steadily growing.
    • Integration with the backend code has become more complicated, there is a need to do this much more often.


    All this makes us think about optimizing the work with the front-end.


    I want to:
    • Reduce the time and amount of integration work ("pulling" the layout into server technology)
    • Increase reuse of html, css and js, reduce the amount of relevant code
    • Reduce time to modify existing code
    • Reduce errors during modification, especially regression
    • Learn how to create and impose responsive design effectively



    The simplest solution is to abandon server-side templating altogether, switch to REST-API and SPA


    pros


    • Integration phase disappears altogether
    • The back and front are separated, each team is more mobile and they don’t have to use a common set of tools at all
    • Front-end worker does not need to deploy server stack

    Minuses


    • SEO
    • The need for a "fat client"
    • Implicit code duplication: ViewModel on the client and DTO on the server


    Cons are pretty serious. What are the options if the templates are on the server?


    Front-loader edits server templates


    pros


    • Do not "pull" the backend

    Minuses


    • The front-end worker needs to hold two sets of tools and switch between them
    • It’s difficult for the front-runner to use unfamiliar technology, all kinds of @using (Hml.BeginForm (// ... and <? Php $ form-> textbox ('name')
    • Front-end worker can break server code and not understand this
    • Front-end worker does not know coding standards of backend command
    • The front-end worker needs to deploy and configure the entire application, including DB and other dependencies


    The front-end editor edits his templates in pure html without server inserts (possibly with preprocessors) and passes it to the back-end


    pros


    • No need to duplicate a set of tools, everyone is doing his own thing, in which he is a specialist
    • Easy environment configuration
    • The ability to simultaneously layout many completely different layouts by different contractors

    Minuses


    • Duplication of work
    • Need to edit a template in two places
    • We have not reduced integration costs


    Front-end worker uses the server engine for layout and independently allocates layouts, blocks and templates


    pros


    • Integration costs virtually disappear
    • The same set of tools and programming language are used on the server and client (this approach is especially attractive for node.js)
    • Closer interaction between the front and back commands is required to coordinate the “cutting” of patterns and blocks

    Minuses


    • Tools are required, maybe they already exist, you may have to write (for php and asp.net this is done in a day or two)
    • Tools may not be compatible with sass / less / stylus / other favorite preprocessors
    • A steeper learning curve for new employees
    • The need for a clear prescribed regulation and style guide for creating templates, view models and the location of files in the file system
    • Closer interaction between the front and back commands is required to coordinate the “cutting” of patterns and blocks (yes, this is both a plus and a minus)


    I tried all the approaches described. My experience is that, depending on the type of project, ceteris paribus, the first and last options work best.

    And where is BEM?


    Perhaps BEM is one of the most holistic topics of our time, so I can not insert the picture below.

    .

    I tried to work with BEM and the semantic layout and came to the conclusion that constant changes in requirements and modifications lead to the frequent need to change the markup and be tied to tag names and cascades in CSS - the idea is so-so.

    Why are cascades bad?

    The idea of ​​“throwing” a cascade out of the “cascading” style pages seems seditious at first glance, but:
    • Most browsers handle styles from right to left and the difference in rendering speed .some-block .some-element li> p a and .some-block__link can reach several times and this must be taken into account.
    • Cascades are very difficult to maintain and modify, it is difficult to create reusable components.
    • The rejection of IDs in styles eliminates view constructs
      #some-elementp,
      #some-other-elementp,
      #one-more-fucking-idp,
      .what-the-hell-class-namep.is-doing-here{
      /*…*/
      }
      

    • “Classic” CSS recommends, but does not dictate, clear rules and regulations, so Vasya may not like how Fedya types up and vice versa. BEM involves a unified methodology, so Vasya and Fedya do everything the same way - according to the methodology. This is a good way to increase the bus factor on the project and reduce the search time for the desired style.
    • The concept of blocks, elements, and especially modifiers is very suitable for responsive design, when you want to display different blocks / or display blocks / elements in different elements depending on the size of the screen.
    • Block, element and modifier are good terms for communication between different specialists. They are intuitive enough so that not “non-techies” are not afraid of these words and are at the same time associated with certain techniques.

      These facts make me reckon with BEM and endure ugly class names. However, even the authors of BEM themselves insist that BEM is a methodology, can and should be “drafted” for the needs of the project and the team. For this, the team needs checklists.


    My checklist


    General requirements

    1. Make-up must be cross-browser and on the grid, it is allowed to correct errors in indentation in the design
    2. Layout should be implemented according to the BEM methodology
    3. Layout must pass w3c validation
    4. Layout to meet the requirements of this checklist
    5. Tables should only be used to represent tabular data; nested tables are not allowed

    Forms

    1. Forms should always be formatted using the form tag , the tag must contain the action attribute
    2. Buttons should be decorated with input or button tags
    3. For phones, you must use an input mask
    4. Validation must be implemented.

    BEM

    1. It is forbidden to use element id and tag names, with the exception of the exceptions below, to set styles
    2. Classes should be named according to the following principle: some-block__ some-element_ some-modificator
    3. Inline styles are forbidden
    4. The names of blocks and elements should correspond to their purpose and function, and not how they are displayed.
      If the blocks perform different functions, but look the same, they need to be designed as one block with a neutral name that reflects their similarity. No excessive code duplication
    5. It is necessary to use normalization for all tags that cannot have a class name (the cases are described below), using reset.css is not allowed. Using normalize.css is acceptable, just like the normalization option is only for tags for which it is impossible to specify a class
    6. It is forbidden to use cascading styles with a depth of more than one element (for example table td ), with the exception of the following situation: depending on the block modifier used, child elements / blocks must be displayed differently. The cascade will be short, when dynamically switching the java-script modifier, the implementation is much simpler and more effective in terms of interacting with the DOM than in the case of modifying the styles of all child elements.
    7. Prefixes b- for blocks are not used
    8. Global modifiers must be declared as a separate class, for example _uppercase . Underscore at the beginning indicates that it is a modifier, not a block. For adaptive layout it is necessary to use the global modifiers _desktop , _tablet and _phone for blocks that need to be displayed only on a specific device. It is preferable to use the mobile-first approach: from simple to complex
    9. Styles should be applied to tags through the parent cascade in cases where it is impossible to control element classes, for example:
      • The user enters the content through a form on the site, is created dynamically or gets from other sources that are not under our control
      • Form Controls: The parent cascade is preferred because form elements can be created using server-side code. Additional reformatting is required to preserve the styles of the elements. This is undesirable.

    Formatting and file system

    1. The use of one large CSS file or JS file is unacceptable, it is necessary to use a branched file structure, namely:
    2. Each block is located in its own folder, reusable blocks and main layouts are located in the shared folder.
    3. The description of the block and all elements is located in a single file called <BLOCK_NAME> .css . If the description of blocks and elements exceeds 600 lines, you must decompose it
    4. Class names and CSS rules are sorted alphabetically
    5. The modifier should redefine no more than 40% of styles, otherwise it is better to create a new block
    6. The block HTML template is in the same folder (server or client template technology is used)
    7. Layouts are separated from pages, all necessary pages are "cut" into separate files

    Bundling, minification and assembly

    1. All resources must be prepared for production and divided into bundles. Bundles should be grouped in such a way that their number is minimal, and the weight of the bundle does not exceed 250KB.
    2. The use of server technology for splitting html layouts into layouts, pages and blocks is allowed and encouraged.
    3. Acceptance is made after the "assembly". The result is n html pages and an index.html file with links to all the pages that have been laid out. It is permissible to transfer the layout in the "source", with the attached bat / make-file and the "collector", if the size of the "collector" does not exceed 10 MB and can be guaranteed to run on the host OS.
    4. Links in css and js files must be absolute, otherwise there is a risk that they will not work correctly after minification



    A selection of good BEM materials:



    Just awesome getting started guide for new employees

    It is difficult to use as a checklist because of the scale of this document: habrahabr.ru/post/114256 . Here's an abridged version that works as a checklist: github.com/delka/html5checklist .

    BEM check

    s=document.createElement('script');s.src ="//2gis.github.io/makeup/autoload/script.js";document.body.appendChild(s)
    

    Also popular now: