What is CSS OK?

Asked

Viewed 576 times

11

I saw that some people are adopting the pattern of putting some classes in CSS separated by a double underline.

Example:

.form__field{
   /** Css aqui **/
}

I never had anything about it, and I came across the term CSS WELL or WELL.

I’d like to know what this is about.

  • It’s a new pattern?

  • What is the purpose of it?

  • What problems he solves?

  • 10

    CSS is evil, always :D

  • 3

    Possible duplicate of Good practices using CSS. One of the answers is about GOOD

  • 4

    It’s another one of those things they created to solve the problem of anyone who mixes a lot of junk, which could be done in a simple way, but that people with little knowledge think they already have enough understanding about CSS (but they don’t even know what Rules are) and they don’t even know how much things could be simplified and get the same result, so they have to invent things to solve difficulties created by their own people because they want to use a series of cacarecos and try to (just really try) avoid getting bogged down.

  • 2

    I voted +1 (and maybe vote to keep it open, I’ll wait for the community) because the question 'seems to me' that could have a focus just on the subject... and I can’t see far the BEM as something useful, actually personally I think that the need to BEM and simplify would be a real "good practice", a question focused on the use of BEM, but not to mention that he’s wonderful, just talk when it’s useful, like these fucked-up projects (don’t get me wrong). So I think this place/question is the place to talk about it, maybe I even dare to answer.

  • 2

    An addendum to my other comment, I’ve come across work from others of a page (a promotional "landingpage") very simple, with BEM, with FLEX, with GRID, which in the end was a little bigger than expected. Yeah, the so-called "good practice" generated by people who forgot to learn the basics, but manage to use a new thing to do about 10 different things, which usually would not even be necessary or appropriate, should follow the philosophy: "do good without looking at whom" :p

3 answers

14


Well it’s not a new standard, it’s a convention that’s a few years old. The goal is that the names of the CSS classes are somewhat relationable with HTML and increase the readability of the CSS produced. BEM stands for Block Element Modifier - block, element, modifier.

The block is the main "container", the element uses two underscores and the modifier uses two hyphens. For example:

<a class="btn btn--red" href="#">
  <span class="btn__icon"></span>
  <span class="btn__text">Subscribe</span>
</a>

in this example we can see the "block" btn and its "modifier" btn--red. Inside the "block" we can also see its child elements: btn__icon and btn__text.

In the CSS file it would be clear that the classes belong to a certain element:

.btn {
   color:blue;
}
.btn--red {
   color: red;
}
.btn__icon {
 }
.btn__text {
 }
  • 1

    Just commenting that you can also have the modifier directly in the "element", for example: btn__text--red { }, this tb would be in accordance with the convention WELL.

4

It’s a CSS architecture developed by a Russian who works or worked on the Yandex search engine. The official website is this https://en.bem.info/

According to this architect, you can organize your css into blocks, block elements and block modifiers or block elements. If you’ve ever played lego, it’s like riding a dummy. The doll is a block, its legs, arms and head are its elements; you can have one of the wooden leg, one hand with a curl, a pirate hat and your doll can be blue. (I’ve never played with lego, so... re-read my analogy. kkk).

For example:

<ul class="list list--row">
    <li class="list__item">
        <a href="#"
           class="list__link list__link--current">...</a>

    </li>
    <li class="list__item">
        <a href="#"
           class="list__link">...</a>

    </li>
    <li class="list__item">
        <a href="#"
           class="list__link list__link--disabled">...</a>

    </li>
</ul>
<style>

.list,
.list__item,
.list__link {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

.list,
.list__item {
    list-style: none;
}

.list--row {
    display: flex;
}

.list__item,
.list__link {
    display: inline-block;
}

.list__item {
    margin: 0 5px;
}


.list__link {
    text-decoration: none;
    text-transform: capitalize;
    color: #1e90ff;
    padding: 10px 5px;
}

.list__link--current {
    border-bottom: 1px solid #1e90ff;
}

.list__link--disabled {
    color: #ccc;
    cursor: text;
}

</style>

1

Well is the acronym for Block Element Modifier (Element Modifier Block), is a methodology based on these three entities that deifne nomenclature rules, file structure and code writing

Block: A functionally independent page component that can be reused

Element: A part composed of a block that cannot be used separately from it

Modifier: Defines the parency, state or behavior of a block or element

Nomenclature:

  • The names are written in lowercase Latin letters.

  • Words are separated by a hyphen (-).

  • The block name defines the namespace for its elements and modifiers.

  • The element name is separated from the block name by a double underscore (__).

  • The modifier name is separated from the block name or element by a single underline (_).

  • The modifier value is separated from the modifier name by a single underscore (_).

  • For boolean modifiers, the value is not included in the name.

There is also alternative nomenclature schemes:

  • Two stroke style: block-name__elem-name--mod-name--mod-val

  • Camelcase style: blockName-elemName_modName_modVal

  • React style: BlockName-ElemName_modName_modVal

  • Style without namespace: _available

In addition to these, it is permitted to create an own nomenclature according to needs

It defines a file structure based on class nomenclature, separating the different technologies into different files

May have a nested structure:

project
    common.blocks                            # Nível de redefinição com blocos
        input                                # Diretório pro bloco input
            _type                            # Diretório pro modificador input_type
                input_type_search.css        # Implementação CSS do modificador input_type
            __clear                          # Diretório pro elemento input__clear
                _visible                     # Diretório pro modificador input__clear_visible
                    input__clear_visible.css # Implementação CSS do modificador input__clear_visible
                input__clear.css             # Implementação CSS do elemento input__clear
                input__clear.js              # Implementação JavaScript do elemento input__clear 
        input.css                            # Implementação CSS do bloco input
        input.js                             # Implementação JavaScript do bloco input

Flat structure:

project
    common.blocks
        input_type_search.css     # Implementação CSS do modificador input_type_search
        input_type_search.js      # Implementação JavaScript do modificador input_type_search
        input__clear.js           # Elemento opcional do bloco input
        input.css
        input.js
        popup.css
        popup.js
        popup.png

Or flex, which is a mixture of both

project
    common.blocks                            # Nível de redefinição com blocos
        input                                # Diretório pro bloco input
            _type                            # Diretório pro modificador input_type
                input_type_search.css        # Implementação CSS do modificador input_type
            __clear                          # Diretório pro elemento input__clear
                _visible                     # Diretório pro modificador input__clear_visible
                    input__clear_visible.css # Implementação CSS do modificador input__clear_visible
                input__clear.css             # Implementação CSS do elemento input__clear
                input__clear.js              # Implementação JavaScript do elemento input__clear 
        input.css                            # Implementação CSS do bloco input
        input.js                             # Implementação JavaScript do bloco input
        popup                                # Diretório pro bloco popup
            popup.css
            popup.js
            popup.png

As you can see, below the project root directory (project), there’s another (common.blocks), this is part of the redefinition levels, the idea is to be able to divide the code into "subprojects", for example, common.blocks with the core and mobile.blocks and desktop.blocks with the specifics of the desktop and mobile interfaces, respectively. Specific files can totally or partially overwrite the classes of core, or until there are no specificities of certain entities

Certain Patterns design acquaintances ...

  • Principle of single responsibility: A class must have one and only one responsibility, that is, a modifier class .button_red should only change the style of the button to red, should not change its position, state or other feature that is not closely related to its main purpose (red style)

  • Open-closed principle: Changes to the CSS must be made by "extension", creating a new modifier and not changing current styles directly or by changing them under a certain context (being a child of another element)

  • DRY ("don’t repeat yourself"): It is directly related to the above principles, the CSS classes must be generic so that they can have specific characteristics through the modifiers, ie there should be no two classes that do almost the same thing, instead, creates a class with the general and two modifiers with the specifics

  • Composition instead of inheritance: New CSS implementations are formed by combining existing ones, this keeps code uncoupled and flexible, for example, if you already have the blocks .button, .menu and .popup, for the creation of a drop-down list, a new block is not necessary, just use existing ones and correctly define their behaviors

It is not recommended to use Wrappers for block positioning, instead mixes should be used:

  • To position two brother blocks (header and content), relative to each other, one can create a parent block (.card) and use two child blocks (.card__header and .card__content) that will have the positioning styles, in addition to the original blocks that will be mixed with the children blocks (.card__header.header and .card__content.content)
<section class="card">
    <!-- Header and navigation -->
    <header class="header card__header">...</header>
    <!-- Content -->
    <div class="content card__content">...</div>
</section>
  • If the elements to be positioned are already parents and children, one can use an element entity to handle the positioning, replacing an abstract wrapper
<button class="button">
    <span class="button__start">
        <span class="icon"></span>
    </span>

    ...
</button>

Creation of HTML can be done manually, that is, write all the code in hand, which, in the long run, is bad from the maintenance point of view, since a change in the structure of entities requires changing the HTML at multiple points

But it’s possible to do that automatically, through templates, by changing it, the existing HTML elements will be updated as well, and can be exchanged for another or extended by new ones. The models are written in a declarative form, allowing the main principles of the methodology to be applied:

  • Use of the same terms: The models are defined in the terms block, element and modifier, for this there is an abstraction above the DOM tree, the tree well, which is a "simplified DOM", only with entities, for example, the following HTML code:
<header class="header">
    <img class="logo">
    <form class="search-form">
        <input class="input">
        <button class="button"></button>
    </form>
    <ul class="lang-switcher">
        <li class="lang-switcher__item">
            <a class="lang-switcher__link" href="url">en</a>
        </li>
        <li class="lang-switcher__item">
            <a class="lang-switcher__link" href="url">ru</a>
        </li>
    </ul>
</header>

Would have the corresponding tree WELL:

header
    logo
    search-form
        input
        button
    lang-switcher
        lang-switcher__item
            lang-switcher__link
        lang-switcher__item
            lang-switcher__link
  • Code division: The template code is stored in separate block files according to the organization rules of the file structure. You can create templates for an entire block or separately for elements or modifiers

  • Use of reset levels: It’s the same idea already described before, applied also to templates, can add and remove entities to the structure or render the same entities differently (for example, changing the HTML tag used)

The methodology also applies to Javascript, keeping the focus on entities and organizing the code according to the structure of files already explained, including the levels of redefinition, where it is possible to add, overwrite or inherit the entities. For everything to work properly and the changes in the DOM do not affect the functioning of the blocks, it is important to implement through the library i-bem.js (there is also the BEM React, a set of tools to implement the methodology in React)

There are some code writing rules as well...

  • Declarative style:

    • The behaviour of each block is described separately

    • The block states are defined declaratively and, when changing, is automatically called the code that defined for this state

    • The block logic is described as a set of actions and conditions for the execution of these actions, this makes it possible to separate the functionality of the block into individual parts and use the levels of reset

  • Encapsulation: The implementation of a block is separate from other blocks and each block provides an API to interact with other blocks. The block statement allows you to hide your internal implementation, and since the elements are always an internal implementation of a block, they can be accessed only through the block API

  • Inheritance: The declarative description of the block’s behavior makes it possible to use the methods of a base block within a derived block and inherit them, so the new block can obtain all the properties and methods of the base block. You can also create inheritance chains, which means that one block inherits from another that in turn inherits from a third block and so on

  • Interaction between blocks: The methodology BEM values to work with independent blocks, but in practice this is unattainable. Communication between blocks can be through:

    • Registration for events from other instances of blocks

    • Signatures for modifier changes

    • Direct calls to methods from other instances or to static methods from other blocks

    • Any interaction patterns. For example, Event Channel: all communication takes place through messages that the components publish and listen to using an intermediary

  • Interaction of a block with its elements: A block usually has additional helpers to work with its elements, which are the internal implementation of a block. Cannot access an element from another block directly, can only be accessed through the API of the block to which this element belongs

I tried to simplify and summarize the parts, there’s more to delve into and also some things I didn’t put here like build and common problems, as well as the various tools (technologies, Toolbox and libraries)

Now answering the questions on the body...

  • It’s a new pattern?

No, according to your story, exists since 2005, but from its beginnings until today changed everything

  • What is the purpose of it?

At first, probably, just standardize how the CSS code is written, today, is a methodology that has several standards and rules to create an organized code, reusable and easy to maintain

  • What problems he solves?

It solves certain problems when working as a team, such as one component overwriting another and disorganization of both code and structure. Also, as I said, the methodology focuses on the development of reusable and maintenance-friendly components.

On the other hand, it brings a lot of complexity and some limitations, such as using classes (.checked) modifiers instead of pseudo-classes (:checked), what would be more practical, and not reuse of modifiers (for example, .bolder for bold) between elements and blocks, but there are alternatives

The methodology NAY standardizes class nomenclature, as described above, it has 5 standards of its own and still allows developers to create their own standards. So anyway, developers will have to organize to decide how classes should be named

All links in the reply were removed from documentation

  • To keep the answer objective, I will leave in the comments my opinion... The methodology brings some interesting patterns/rules, but the total adoption will hardly be beneficial, it is very complex, there is a separation in many files unnecessarily, the code gets very polluted with many classes and big names. CSS preprocessors (SASS, Stylus, etc) offer useful tools that can be used in place of some standards to keep code simpler and cleaner

Browser other questions tagged

You are not signed in. Login or sign up in order to post.