关于bem代码命名规范的一些记录

381 阅读2分钟

本周,针对于我们公司前端项目每个人的代码风格各不相同,在稍大型的项目中会出现维护困难,代码格式不统一等一系列问题,统一规定了前端的css规范使用bem规范,在这已此文作为记录。 首先,什么是bem命名规范,Bem是块(block)、元素(element)、修饰符(modifier)的简写,由Yandex团队提出的一种前端CSS命名方法论。命名方法如下:

.block__element--modifier {
    display: flex;
}
.block--modifier {
    display: flex;
}
.block__element {
    display: flex;
}
​
<p class="header">
    <p class="header__body">
        <button class="header__button--primary"></button>
        <button class="header__button--default"></button>
    </p>
</p>

而bem的好处呢就是让你的前端代码更容易阅读和理解,更容易协作,更容易控制,更加健壮和明确,而且更加严密。 下面详细介绍一下3个组成部分的含义

1.block

block 代表一个更高级别的抽象或者是一个组件,它仅仅作为一个边界。它主要的功能有下面三点:

  1. 负责描述功能的,不应该包含状态。
  2. 不影响自身布局,不包含具体的样式,也就是block里面不应该加样式
  3. 不能使用元素选择器和ID选择器
2.element

element 代表一个块的元素

  1. 是用一个双下划线隔开
  2. 表示的是目的,而不是状态,如下例子:目的是在header下面定义三个区域 body、logo、title,但是并没有指定任何状态。
  3. 不能脱离Block父级单独使用
3.Modifier
  1. 表示的是一个状态,是用双横杠分开的。
  2. 不能单独使用 下面记录一下bem在scss预处理中的使用
@import 'function';

$B: ''; // block名称

/* Scrollbar
 -------------------------- */
@mixin scroll-bar {
    $--scrollbar-thumb-background: #b4bccc;
    $--scrollbar-track-background: #fff;

    &::-webkit-scrollbar {
        z-index: 11;
        width: 6px;

        &:horizontal {
            height: 6px;
        }

        &-thumb {
            border-radius: 5px;
            width: 6px;
            background: $--scrollbar-thumb-background;
        }

        &-corner {
            background: $--scrollbar-track-background;
        }

        &-track {
            background: $--scrollbar-track-background;

            &-piece {
                background: $--scrollbar-track-background;
                width: 6px;
            }
        }
    }
}

/* Placeholder
-------------------------- */
@mixin placeholder {
    &::-webkit-input-placeholder {
        @content;
    }

    &::-moz-placeholder {
        @content;
    }

    &:-ms-input-placeholder {
        @content;
    }
}

/* BEM
 -------------------------- */
@mixin b($block) {
    $B: $block !global;

    .#{$B} {
        @content;
    }
}

@mixin e($element) {
    $E: $element !global;
    $selector: &;
    $currentSelector: '';
    @each $unit in $element {
        $currentSelector: #{$currentSelector +
            '.' +
            $B +
            $element-separator +
            $unit +
            ','};
    }

    @if hitAllSpecialNestRule($selector) {
        @at-root {
            #{$selector} {
                #{$currentSelector} {
                    @content;
                }
            }
        }
    } @else {
        @at-root {
            #{$currentSelector} {
                @content;
            }
        }
    }
}

@mixin m($modifier) {
    $selector: &;
    $currentSelector: '';
    @each $unit in $modifier {
        $currentSelector: #{$currentSelector +
            & +
            $modifier-separator +
            $unit +
            ','};
    }

    @at-root {
        #{$currentSelector} {
            @content;
        }
    }
}

@mixin configurable-m($modifier, $E-flag: false) {
    $selector: &;
    $interpolation: '';

    @if $E-flag {
        $interpolation: $element-separator + $E-flag;
    }

    @at-root {
        #{$selector} {
            .#{$B + $interpolation + $modifier-separator + $modifier} {
                @content;
            }
        }
    }
}

@mixin spec-selector(
    $specSelector: '',
    $element: $E,
    $modifier: false,
    $block: $B
) {
    $modifierCombo: '';

    @if $modifier {
        $modifierCombo: $modifier-separator + $modifier;
    }

    @at-root {
        #{&}#{$specSelector}.#{$block
            + $element-separator
            + $element
            + $modifierCombo} {
            @content;
        }
    }
}

@mixin meb($modifier: false, $element: $E, $block: $B) {
    $selector: &;
    $modifierCombo: '';

    @if $modifier {
        $modifierCombo: $modifier-separator + $modifier;
    }

    @at-root {
        #{$selector} {
            .#{$block + $element-separator + $element + $modifierCombo} {
                @content;
            }
        }
    }
}

@mixin when($state) {
    @at-root {
        &.#{$state-prefix + $state} {
            @content;
        }
    }
}

@mixin extend-rule($name) {
    @extend #{'%shared-' + $name};
}

@mixin share-rule($name) {
    $rule-name: '%shared-' + $name;

    @at-root #{$rule-name} {
        @content;
    }
}

@mixin pseudo($pseudo) {
    @at-root #{&}#{':#{$pseudo}'} {
        @content;
    }
}