Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to structure css using BEM methodology for adaptive web pages?

It is easy to use BEM for fixed layouts. What is about css styles structure for adaptive web pages with media queries?

html sample:

<div class="t-news">
    <div class="t-news__post b-post">
        <div class="b-post__title"></div>
        <div class="b-post__text--green"></div>
    </div>
    <div class="t-news__post b-post--small">
        <div class="b-post__title"></div>
        <div class="b-post__text--red"></div>
    </div>
</div>

less sample:

.t-news {
     &__post {
         //some styles
     }
}
.b-post {
     &__title {
         //some styles
     }
     &__text {
         //some styles

         &--red {
              //some styles
         }
         &--green {
              //some styles
         }
     }

     &--small {
         //some styles
     }
}
  • .t-news - page template. It is a block that defines position of blocks inside.
  • .b-post - BEM block
  • .b-post__title - BEM element of b-post
  • .b-post__text--red - BEM modifier of b-post__text of b-post

Should I put media queries inside or outside my blocks?

like image 537
pepeevich Avatar asked Jun 22 '16 13:06

pepeevich


People also ask

How do you use BEM methodology?

BEM names intentionally use double underscores and double hyphens instead of single to separate Block-Element-Modifier. The reason is so that single hyphens can be used as word separators. Class names should be very readable, so abbreviation isn't always desirable unless the abbreviations are universally recognizable.

What is BEM methodology in CSS?

What is BEM? BEM is a front-end naming method for organizing and naming CSS classes. The Block, Element, Modifier methodology is a popular naming convention for class names in HTML and CSS. It helps to write clean CSS by following some simple rules.


1 Answers

In my experience, I realized that blocks shouldn't be responsible for their widths or margins for the sake of flexibility and modularity. Having "elastic" blocks in a project allow them to be moved around to occupy different areas (with different sizes) of a page without breaking functionality or layout. As for the margins, it's easier to keep consistent spaces between the blocks if they are defined on a higher level: a template block like, I assume, t-news is (considering the "t" is for template).

BEM is all about modularity, every piece of code that is related to a specific block stays in the block's folder in the file system, so it shouldn't be different with media queries, that are only a part of the CSS. The important thing is to know what the CSS is doing, for example: if a set of rules is defining areas and margins in a template, whether it needs media queries for that or not, these rules should be a part of the block that is responsible for these definitions.

This approach may generate a lot of media queries, and there may be a concern with rendering performance, but, according to this article, multiple media queries may affect performance only if they are different from each other. Repetitions of the same rule, like @media (max-width: 850px), will be serialized and interpreted as one.

This way, media queries related to areas and margins go in the template block, and additional media queries related to the components themselves, go in the components blocks. Since the template is responsible for sizes, I would change the "small" modifier, in your example, to the template block.

Also, I would reconsider using green and red as modifiers, since colors may change during the lifetime of a project. I suggest trying something that doesn't describe the appearance of the elements, like correct and alert.

Finally, remember that modifiers should folow element classes in the HTML, like b-post__text b-post__text--alert.

Here's your updated code:

Html:

<div class="t-news">
    <div class="t-news__post b-post">
        <div class="b-post__title">Title 1</div>
        <div class="b-post__text">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eget ligula eu lectus lobortis condimentum. Aliquam nonummy auctor massa. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla at risus. Quisque purus magna, auctor et, sagittis ac, posuere eu, lectus. Nam mattis, felis ut adipiscing.</div>
    </div>
    <div class="t-news__post b-post">
        <div class="b-post__title">Title 2</div>
        <div class="b-post__text b-post__text--correct">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam eget ligula eu lectus lobortis condimentum. Aliquam nonummy auctor massa. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Nulla at risus. Quisque purus magna, auctor et, sagittis ac, posuere eu, lectus. Nam mattis, felis ut adipiscing.</div>
    </div>
    <div class="t-news__post t-news__post--small b-post">
        <div class="b-post__title">Title 3</div>
        <div class="b-post__text">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
    </div>
    <div class="t-news__post t-news__post--small b-post">
        <div class="b-post__title">Title 4</div>
        <div class="b-post__text b-post__text--alert">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
    </div>
</div>

Scss:

.t-news {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
    margin: -0.5rem;

    &__post {
        margin: 0.5rem;
        width: calc(50% - 1rem);
        @media (max-width: 800px) { width: calc(100% - 1rem); }

        &--small {
            width: calc(25% - 1rem);
            @media (max-width: 800px) { width: calc(50% - 1rem); }
        }
    }
}

.b-post {
    box-sizing: border-box;
    border: 1px solid #eeb;
    background: #ffc;
    padding: 0.5rem;

    &__title {
        font-size: 1.5rem;
        @media (max-width: 800px) { font-size: 1.25rem; }
    }

    &__text {
        font-size: 1rem;

        &--correct {
            color: green;
        }

        &--alert {
            color: red;
        }
    }

    &--small {
        border: none;
        font-style: italic;
    }
}

Hope this helps.

like image 189
Leonardo Favre Avatar answered Nov 15 '22 06:11

Leonardo Favre