如何使用 BEM 方法为自适应网页构造 css?

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

对于固定布局,使用 BEM 很容易。具有媒体查询的自适应网页的 css 样式结构是什么?

html样本:

<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>

样本较少:

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

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

     &--small {
         //some styles
     }
}

我应该将媒体查询放在块内还是块外?

根据我的经验,我意识到为了灵活性和模块化,块不应该对其宽度或边距负责。在一个项目中有 "elastic" 个块允许它们 moved around 占据页面的不同区域(具有不同大小)而不会破坏功能或布局。至于边距,如果在更高级别上定义它们,则更容易在块之间保持一致的空间:模板块,我假设,t-news 是(考虑到 "t" 用于模板)。

BEM 完全是关于模块化的,与特定块相关的每一段代码都保留在 file system 中块的文件夹中,因此它与媒体查询应该没有什么不同,它只是一个CSS 的一部分。重要的是要知道 CSS 在做什么,例如:如果一组规则在模板中定义区域和边距,无论是否需要媒体查询,这些规则都应该是的一部分负责这些定义的块。

这种方法可能会生成大量媒体查询,并且可能会影响渲染性能,但是,根据 this article,多个媒体查询只有在 时才会影响性能彼此不同。相同规则的重复,如 @media (max-width: 850px),将被序列化并解释为一个。

这样,与区域和边距相关的媒体查询进入模板块,与组件本身相关的其他媒体查询进入组件块。由于模板负责大小,因此在您的示例中,我会将 "small" 修饰符更改为模板块。

此外,我会重新考虑使用 greenred 作为修饰符,因为颜色可能会在项目的生命周期内发生变化。我建议尝试一些不描述元素外观的东西,比如 correctalert.

最后,请记住修饰符应该跟在 HTML 中的元素 类 之后,例如 b-post__text b-post__text--alert.

这是您的更新代码:

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;
    }
}

希望对您有所帮助。