【青训营】- CSS· BEM简介

634 阅读2分钟

前言

CSS方法论是为了提高CSS的可维护性和拓展性,而衍生出来的一种CSS样式名的原则和概念以及命名规范,CSS方法论并没有涉及到任何代码方面的知识.不是样式库或者框架,仅仅是一种理论和范式指导开发者开发出更加优秀,方便管理的易于拓展的CSS.
BEM方法相对其他来说简单易用,却仍然能够提供良好的架构和易于识别的术语.

Block(块)

逻辑和功能独立的模块,在block中应该封装行为(javascript)模板(html)和样式(css)等静态资源,独立可复用的.block描述了模块是什么,但不描述模板的外观和特性. block可以包含其他block

Element(元素)

每个element都应该是block的一部分,并且只能包含在block中不能单独存在,element也是用来描述dom是什么而不是DOM的外观和特性.element中不能包含任何element.在bem中element就是最小的组成元素

Modifier(修饰符)

block和element是描述DOM的定义,而modifier则是用来定义block和element的状态的(比如外观/样式/属性等特性类似html中属性或者样式的概念),通过添加modifier的我们可以区分不同的block和element
BEM种两种定义modifier的命名方式,布尔值方式(例如:disabled,focused),键值对命名方式来描述dom的某些属性是什么

<input type="radio" class="input_type_radio">
// 描述 input type 为单选按钮时样式
<input type="text" class="input_type_text">
// 描述 input type 为输入框时的样式
<input type="checkbox" class="input_type_checkbox">
// 描述 input type 为多选框时的样式

BEM最核心的命名范式是什么?

  • 经典范式
    • 样式命名全部小写
    • 同一类型的单词使用短线-连接
    • block和element之间使用两个下划线__连接二modifier和它们使用一个下划线_连接
<header class="header"> // 头部区域(block)
    <img class="logo"> // logo(block)
    <ul class="tab-list"> // tab列表(block)
        <li class="tab-list__item"> // 每个tab选项(element)
            <a class="tab-list__link tab-list__link_selected" /> 
            // 每个tab选项中点击连接(element)
        </li>
        ...
    </ul>
</header>

转换为BEM树

<block:header>
    <block:logo/>
    <block:tab-list>
        <elem:tab-list__item>
            <elem:tab-list__link/>
        </elem:tab-list__item>
    </block:tab-list__item>
    <block:search/>
    <block:user/>
</block:header>
  • bem-like风格范式
    • 双短线范式
    • 驼峰命名范式
    • React命名范式
// 双短线范式
Block__Element--Modifier
Block__Element--Modifier_type--Modifier_value
// 驼峰命名范式
.block-name__elem-name_mod-name_mod-val{...} // 经典命名范式
.blockName-elemName_modName_modVal{...} // 驼峰命名范式
// React命名范式
.block-name__elem-name_mod-name_mod-val{...} // 经典命名范式
.BlockName-ElemName_modName_modVal{...} // React命名范式

工具

为了简化BEM的CSS命名范式带来的复杂度和工作量,可以通过工具来解决一些问题

  • CSS Modules
import styles from './button.css'
buttomElem.outerHTML = `<button class=${styles.normal}>Submit</button>`
// css-module处理后
<button class="35zsasdasdafasdASDAF-DOIEF">submit</button>
  • css-loader
// webpack css-loader
module.exports = {
    module: {
        rules: [
            {
                test:/\.css$/i,
                loader: 'css-loader'
                options: {
                    // modules: true // 开启CSS Modules功能
                    modules: {
                        localIdentName: '[name]__[local]__[hash:base64:5]', // 自定义命名样式规则
                    }
                }
            }
        ]
    }
}

脑图

参考