BEM在SASS中的实践

近几年web应用的发展可以用疯狂来形容,依靠浏览器的支持以及前端技术和框架的发展,很多应用已经把大量的逻辑从服务器端迁移到了浏览器端,使用前后端分离技术,浏览器端与用户进行交互来完成复杂的逻辑。由于这个发展趋势,Web应用的前端代码的复杂度大大提高,尤其是 JavaScript 和 CSS 代码的数量大幅增加,面对空前庞大的css和js代码量,形成科学的代码组织方法和命名规范迫在眉睫。

好的命名规则应该满足以下几个优点:

  • 安全的命名,不会干扰其它css
  • 我需要很快知道一个 class 位于这个伟大工程的什么位置
  • class 尽可能少,且结构清晰
  • 嵌套不可以太深,否则会形成难以维护的“谜”之样式

BEM 是一种前端项目开发的方法学,由 Yandex 公司提出。BEM 的名称来源于该方法学的三个组成部分的英文首字母,分别是块(Block)、元素(Element)和修饰符(Modifier)。这三个不同的组成部分称为 BEM 实体。

Block——块:

块即是通常所说的 Web 应用开发中的组件或模块。每个块在逻辑上和功能上都是相互独立的。块中封装了组件相关的 JavaScript、CSS 代码和 HTML 模板。由于块是独立的,可以在应用开发中进行复用,从而降低代码重复并提高开发效率。块可以放置在页面上的任何位置,也可以互相嵌套。

Element——元素:

元素是块中的组成部分。元素不能离开块来使用。BEM 不推荐在元素中嵌套其他元素。

Modifier——修饰符:

修饰符用来定义块或元素的外观和行为。同样的块在应用不同的修饰符之后,会有不同的外观。

具体之前也写过BEM命名方式,所以这次不是主要介绍BEM的。

这次在封装饿了么组件的时候,发现饿了么团队已经在SASS中使用BEM了,感觉特别方便,所以就拿出来分享一下:

$elementSeparator: '__';
$modifierSeparator: '--';

@function containsModifier($selector) {
    $selector: selectorToString($selector);
    @if str-index($selector, $modifierSeparator) {
        @return true;
    } @else {
        @return false;
    }
}

@function selectorToString($selector) {
    $selector: inspect($selector); //cast to string
    $selector: str-slice($selector, 2, -2); //remove brackets
    @return $selector;
}

@function getBlock($selector) {
    $selector: selectorToString($selector);
    $modifierStart: str-index($selector, $modifierSeparator) - 1;
    @return str-slice($selector, 0, $modifierStart);
}

@mixin b($block) {
    .#{$block} {
        @content;
    }
}

@mixin e($element) {
    $selector: &;
    @if containsModifier($selector) {
        $block: getBlock($selector);
        @at-root {
            #{$selector} {
                #{$block+$elementSeparator+$element} {
                    @content;
                }
            }
        }
    } @else {
        @at-root {
            #{$selector+$elementSeparator+$element} {
                @content;
            }
        }
    }
}

@mixin m($modifier) {
    @at-root {
        #{&}#{$modifierSeparator+$modifier} {
            @content;
        }
    }
}

具体可以点击这个查看。

添加新评论