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

1

7

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?

Castilian answered 22/6, 2016 at 13:6 Comment(2)
What exactly are you asking? How to best use media queries in your CSS? BEM works fine with "adaptive" (is this the same as responsive?) websites and media queries... Look at the "Naming breakpoints" section here: sitepoint.com/css-sass-styleguideAbukir
Yes, I want to know what is the best approach to use media queries and BEM together.Castilian
H
9

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.

Horbal answered 22/6, 2016 at 15:52 Comment(11)
Thank you very much for feedback. I have some questions:Castilian
) Why you use "margin: -0.5rem;" for t-news. I think that it is a bad pratice to add position for block. Only parent block can set position of it's child. Child block must have exact size.Castilian
2) I talk with some developers and the conclustion of our discussion was that we can just use "b-block__element--modifier" and not "b-block__element b-block__element--modifier" because in less we can specify "b-block__element, b-block__element--modifier {/*commons styles here*/}".Castilian
3) Media queries in every block, in some elements and modifiers isn't looking good because every media query is work for browser. I am not sure, but I think that the huge number of media queries can decrease website perfomance.Castilian
The margin: -0.5rem is not really necessary, I use it is my projects to neutralize the children's margins, like t-news__post { margin: 0.5rem }. I have tried other techniques like using nth-child for removing specific left or right margins, but I find it this way easier to mantain. I have an example: codepen.io/leofavre/pen/rebzqX?editors=1100Horbal
@Castilian b-block__element b-block__element--modifier is a BEM specification, see "Modifiers" in this documentation, but you can choose to follow it or not.Horbal
@Castilian In my experience, I find it easier to mantain the CSS if media querries are closer to the selectors they are modifing, but this is also a personal choice. My point is that i think you should specify media querries related to .t-news and .b-post inside their respective blocks.Horbal
The last answer without any arguments. It's only your opinion. I want to hear real advantages and disadvanges of this approach. I can't use only opinion as argument to develop big projects.Castilian
@Castilian You are right, of course, I'll try to make a better explanation of my choices, but I think I will end up being just my opinion. I can't seem to find and specifications on how to deal with media querries on BEM documentation, I can only tell you what has worked for me and why. I'll work on the "why" part.Horbal
I have updated my answer to better explain why i think media queries should stay with their blocks and not "outside" BEM structure.Horbal
thank you, I mark your answer as solution, because there aren't other opinions.Castilian

© 2022 - 2024 — McMap. All rights reserved.