Web前端首页投稿(暂停使用,暂停投稿)@IT·互联网

【译】BEM CSS命名规范一 Quick start

2016-09-07  本文已影响2987人  Jadyn

BEM 是对 CSS 命名的一种规范,推崇将 WEB 页面模块化,从而提高代码的重用度,减少后期维护的成本。原文

快速开始

简介

BEM(Block,Element,Modifier)是一个基于组件方式的 web 开发方法。
  他的基本思想是将用户界面分为独立的模块。
  即使是一个复杂的 UI 界面,也会使得用户界面开发简单而迅速,,并且允许重用现有的代码,而不是复制粘贴。

内容

<h2 id="block">模块</h2>

一个可重复使用的功能独立的页面组件。在 HTML 中,blocks 通过 class 属性表示。
特征:

例如:

<!-- 正确的,这个 'error' 模块是具有语义上的意义的 -->
<div class="error"></div>
<!-- 不正确的,它描述了模块的外观 -->
<div class="red-text"></div>

这些保证了模块必要的独立性,可以更好地重用模块或者将他们从一个地方移动到另一个地方。

模块使用指南

嵌套关系

例子:

<!-- 'head' 模块 -->
<header class="header">
    <!-- 嵌套 'logo' 模块 -->
    <div class="logo"></div>

    <!-- 嵌套 'search-form' 模块 -->
    <form class="search-form"></form>
</header>

<h2 id="element">元素</h2>

是一个模块的组成部分,且不能脱离模块单独地被使用。

特征:

例子:

<!-- 'search-form' 模块 -->
<form class="search-form">
    <!-- 在 'search-form' 模块内的 'input' 元素 -->
    <input class="search-form__input"/>
    <!-- 在 'search-form' 模块内的 'button' 元素 -->
    <button class="search-form__button"></button>
</form>

元素使用指南

<h4 id="nesting">嵌套关系</h4>

例子:

<!--
     正确的。完整的元素名的结构符合如下模式:
     'block-name__element-name'
 -->
<form class="search-form">
    <div class="search-form__content">
        <input class="search-form__input"/>
        <button class="search-form__button"></button>
    </div>
</form>

 <!--
     不正确的。完整的元素名的结构不符合如下模式:
     'block-name__element-name'
 -->
<form class="search-form">
    <div class="search-form__content">
        <!-- 推荐:'search-form__input' 或者 'search-form__content-input' -->
        <input class="search-form__content__input"/>
        <!-- 推荐:'search-form__button' 或者 'search-form__content-button' -->
        <button class="search-form__content__button"></button>
    </div>
</form>

如果在模块名称上定义了命名空间,也要保证元素名称是依赖于模块的(block_elem)。
  在 DOM 树中,一个模块可以有元素嵌套结构:
例子

<div class="block">
    <div class="block_elem1">
        <div class="block_elem2">
            <div class="block_elem3"></div>
        </div>
    </div>
</div>

然而,在 BEM 的方法论中,这样的模块结构通常表示为一个并列的元素列表:
例子

.block {}
.block_elem1 {}
.block_elem2 {}
.block_elem3 {}

这样在代码中,你可以在不改变每个单独的元素的情况下改变一个模块的 DOM 结构:
例子

<div class="block">
    <div class="block_elem1">
        <div class="block_elem1"></div>
    </div>
    <div class="block_elem3"></div>
</div>

模块的结构改变了,但是元素的规则和他们的名字仍然保持不变。
<h4 id="membership">组成部分</h4>

一个元素总是一个模块的一部分,你不应该单独使用它。
例子

<!-- 正确的。元素都位于 'search-form' 模块内 -->
<!-- 'search-form' 模块 -->
<form class="search-form">
    <!-- 在 'search-form' 模块内的 'input' 元素 -->
    <input class="search-form__input" />
    <!-- 在 'search-form' 模块内的 'button' 元素 -->
    <button class="search-form__button"></button>
</form>

<!-- 不正确的。元素位于 'search-form' 模块的上下文之外 -->
<!-- 'search-form' 模块 -->
<form class=""search-block>
</form>

<!-- 在 'search-form' 模块内的 'input' 元素 -->
<input class="search-form__input"/>

<!-- 在 'search-form' 模块内的 'button' 元素 -->
<button class="search-form__button"></button>

<h4 id="optional">可选性</h4>

一个元素是一个可选的模块组件。并不是所有的模块都必须有元素。
例子:

<!-- 'search-form' 模块 -->
<div class="search-form">
    <!-- 'input' 模块 -->
    <input class="input"/>

    <!-- 'button' 模块 -->
    <button class="button"></button>
</div>

<h2 id="should-i-create-a-block-or-an-element">我应该创建一个模块还是一个元素?</h2>

  1. 如果这段代码可能被重用,并且它不依赖于页面上的其他组件,那你应该创建一个模块。
  2. 如果这段代码在没有父实体(模块)的情况下不能使用,那你应该创建一个元素。

为了简化开发,元素应该被分割成一小部分-子元素。在 BEM 方法论中,你不能创建元素的元素,在这种情况下,你需要创建一个服务模块,而不是创建一个元素。

<h2 id="modifier">修饰符</h2>

一种用于定义模块和元素的外观,状态和行为的实体。
特征:

修饰符的类型

Boolean

例子

<!-- 'search-form' 模块有一个 ‘focused’ 的布尔类型的修饰符 -->
<form class="search-form search-form_focused">
    <input class="search-form__input"/>

    <!-- 'button' 元素有一个 'disabled' 的布尔类型修饰符 -->
    <button class="search-form__button search-form__button_disabled">Search</button>
</form>

键-值

例子

<!-- The `search-form` 模块有值为 'islands' 的 `theme` 修饰 -->
<form class="search-form search-form_theme_islands">
    <input class="search-form__input">

    <!-- The `button` 元素有值为 'm' 的 `size` 修饰 -->
    <button class="search-form__button search-form__button_size_m">Search</button>
</form>

<!-- 你不能同时使用两个具有不同值的的相同修饰符 -->
<form class="search-form
             search-form_theme_islands
             search-form_theme_lite">

    <input class="search-form__input">

    <button class="search-form__button
                   search-form__button_size_s
                   search-form__button_size_m">
        Search
    </button>
</form>

修饰符使用指南

一个修饰符不能被单独使用。

从 BEM 的角度,一个修饰符不能脱离模块或元素而被使用。一个修饰符应该改变实体的外观,行为或者状态,而不是替换它。
例子

<!-- 正确的。'search-form' 模块有值为 'islands' 的 'theme' 修饰符 -->
<form class="search-form search-form_theme_islands">
    <input class="search-form__input">

    <button class="search-form__button">Search</button>
</form>

<!-- 不正确的。'search-form' 丢失了 -->
<form class="search-form_theme_islands">
    <input class="search-form__input">

    <button class="search-form__button">Search</button>
</form>

[为什么需要在元素或修饰符的名称上添写上模块的名称?](Why write the block name in the names of modifiers and elements?)

<h2 id="mix">混合模式</h2>

一种在单一的 DOM 节点上使用不同 BEM 实体的技术。
混合模式允许你:

例子:

<!-- 'header' 模块 -->
<div class="header">
    <!--
        将 'header' 模块的 'search-form' 元素与 'search-form' 模块混合在一起使用
    -->
    <div class="search-form header__search-form"></div>
</div>

在这个例子中,我们将 header 模块的 search-form 元素与 search-form 模块的行为和样式结合在一起。这种方式允许我们在 header__search-form 元素上设置额外的形状和定位,而 search-form 模块仍然是通用的。因此,我们可以在任何环境中使用模块,因为模块没有指定任何填充。这正是我们可以独立调用模块的原因。

<h2 id="filesystem">文件系统</h2>

在 BEM 方法论中采用的组件概念同样适用于项目的文件结构中。模块、元素和修饰符的实现可以被分在独立的文件中,这意味着,我们单独地使用它们。
特征:

例子:

search-form/                           # Directory of the search-form

    __input/                           # Subdirectory of the search-form__input
        search-form__input.css         # CSS implementation of the
                                       # search-form__input element
        search-form__input.js          # JavaScript implementation of the
                                       # search-form__input element

    __button/                          # Subdirectory of the search-form__button element
        search-form__button.css
        search-form__button.js

    _theme/                            # Subdirectory of the search-form_theme modifier
        search-form_theme_islands.css  # CSS implementation of the search-form block
                                       # that has the theme modifier with the value
                                       # islands
        search-form_theme_lite.css     # CSS implementation of the search-form block
                                       # that has the theme modifier with the value
                                       # lite

search-form.css                        # CSS implementation of the search-form block
search-form.js                         # JavaScript implementation of the
                                       # search-form block

这样的文件结构可以很好地支持我们重用代码。

在生产环境中,这些分支的文件结构将会被组合成共享的文件。

遵循这样的文件结构并不是必须的。你可以使用任何可替代的项目结构,根据 BEM 原则来组织你的文件结构,比如:

自己英文水平有限,如果文中有错误,或者歧异,或者不恰当的地方,希望大家提出来,非常愿意接受大家的批评与建议。

上一篇 下一篇

猜你喜欢

热点阅读