命名多个复杂修饰符的 BEM 约定

BEM convention for naming multiple complex modifiers

我一直困惑于寻找命名多个修饰符的最佳方式, 我知道这种方法的基本规则,并且我阅读了官方 BEM 快速入门文档 (bem.info/methodology/quick-start)

当我在一个块中有一些修饰符时,我在命名修饰符时遇到问题,其中一个修饰符对另一个修饰符有一些影响(换句话说,一个修饰符除了修改主块之外,还修改了另一个修饰符那个街区)

我没有解释问题,而是针对这种情况使用了一个简单的例子,所以请告诉我以下哪个例子是正确的和最好的选择:

解决方案 1)

SCSS:

.btn {
    font-size: 14px;

    &--primary {
        background: blue;
    }
    &--secondary {
        background: black;
    }
    &--outline {
        background: transparent;
    }
    &--outline#{&}--primary {
        border: 1px solid blue;
    }
    &--outline#{&}--secondary {
        border: 1px solid black;
    }
}

已编译CSS:

.btn {
  font-size: 14px;
}
.btn--primary {
  background: blue;
}
.btn--secondary {
  background: black;
}
.btn--outline {
  background: transparent;
}
.btn--outline.btn--primary {
  border: 1px solid blue;
}
.btn--outline.btn--secondary {
  border: 1px solid black;
}

HTML 中的用法示例:

<a href="#" class="btn btn--primary btn--outline>...</a>

解决方案 2)

SCSS:

.btn {
    font-size: 14px;

    &--primary {
        background: blue;
    }
    &--secondary {
        background: black;
    }
    &--outline {
        background: transparent;
    }
    &--outline#{&} {
        &--primary {
            border: 1px solid blue;
        }
        &--secondary {
            border: 1px solid black;
        }
    }
}

已编译CSS与解决方案1相同

HTML中的用法示例也与解决方案 1 相同

实际上我只是在修饰符中嵌套以防止重复 "outline",


解决方案 3)

SCSS:

.btn {
    font-size: 14px;

    &--primary {
        background: blue;
    }
    &--secondary {
        background: black;
    }
    &--outline {
        background: transparent;

        &--primary {
            border: 1px solid blue;
        }
        &--secondary {
            border: 1px solid black;
        }
    }
}

已编译CSS:

.btn {
  font-size: 14px;
}
.btn--primary {
  background: blue;
}
.btn--secondary {
  background: black;
}
.btn--outline {
  background: transparent;
}
.btn--outline--primary {
  border: 1px solid blue;
}
.btn--outline--secondary {
  border: 1px solid black;
}

HTML 中的用法示例:

<a href="#" class="btn btn--outline btn--outline--primary">...</a>

解决方案 4)

SCSS:

.btn {
    font-size: 14px;

    &--primary {
        background: blue;
    }
    &--secondary {
        background: black;
    }
    &--outline {
        &--primary {
            background: transparent;
            border: 1px solid blue;
        }
        &--secondary {
            background: transparent;
            border: 1px solid black;
        }
    }
}

已编译CSS:

.btn {
  font-size: 14px;
}
.btn--primary {
  background: blue;
}
.btn--secondary {
  background: black;
}
.btn--outline--primary {
  background: transparent;
  border: 1px solid blue;
}
.btn--outline--secondary {
  background: transparent;
  border: 1px solid black;
}

HTML 中的用法示例:

<a href="#" class="btn btn--outline--primary">...</a>

如您所见,此解决方案更易于在 HTML 中使用,但我们在每个主要和次要修饰符中复制相同的 CSS 属性(在这种情况下,我们复制背景: transparent; in other modifiers ), 你可能认为这无关紧要,但在实际情况下,我们可能有很多 属性 在许多地方重复,所以这个解决方案肯定会对这个开发产生重要问题未来的组成部分


解决方案 5)

SCSS:

.btn {
    font-size: 14px;

    &--primary {
        background: blue;

        &--outline {
            background: transparent;
            border: 1px solid blue;
        }
    }
    &--secondary {
        background: black;

        &--outline {
            background: transparent;
            border: 1px solid black;
        }
    }
}

已编译CSS:

.btn {
  font-size: 14px;
}
.btn--primary {
  background: blue;
}
.btn--primary--outline {
  background: transparent;
  border: 1px solid blue;
}
.btn--secondary {
  background: black;
}
.btn--secondary--outline {
  background: transparent;
  border: 1px solid black;
}

HTML 中的用法示例:

<a href="#" class="btn btn--primary--outline">...</a>

我们在此解决方案中也有重复的属性(如解决方案 4)

所以它没有一个好的开发结构,它会在一个大的组件中打扰程序员

我只是想知道哪种解决方案是最佳选择,或者如果您对此问题有其他解决方案,请根据此按钮示例编写。

另外我再提一下这一点: 我在一个非常小的真实组件中编写了这个例子,所以在这个例子中似乎不关心任何属性或 类 名称的重复,但在真实项目中更复杂的情况下它会是组件开发的一个严重问题。

链接属性选择器似乎很适合您的特殊情况。 假设我们有至少包含 .btn 的所有按钮。 这样,您既可以在专用 css 规则中保留每个修改案例的逻辑,也可以将重复项降至最低。

假设你有一个

<button class="btn--primary--outline"></button>

那么你可能会写 css 规则如下:

[class^="btn"] {
 font-size: 14px;
}

[class^="btn"][class*="--primary"] {
 background: blue;
 border-color: blue;
}

[class^="btn"][class*="--outline"] {
 border: 1px solid;
}