如何在Sass中正确使用BEM

4

我开始使用BEM方法论[BLOCK, ELEMENT, MODIFIER],但是我有疑虑。

在一个名为“参与”的部分中,我有一个表单,因此:

<section class="participate">
  <form class="participate__form">
    <label for="name" class="participate__form__label"></label>
    <input type="text" id="name" name="participate__form__input"/>

  </form>
</section>

以下是CSS代码:

.participate {
 &__form {
   // css here
 }
 &__form__label {
   // css here
 }
 &__form__input {
   // css here
 }
}

表单内的类太多了,所以建议将其嵌套一层:

<section class="participate">
  <form class="participate__form form">
    <label for="name" class="form__label"></label>
    <input type="text" id="name" name="form__input"/>

  </form>
</section>

但是我应该如何为它设置样式呢?
我是这样使用它的:
.participate {
 .form {
   // CSS HERE
   &__label {
   // CSS HERE
   }
   &__input {
   // CSS HERE
   }
 }
}

但我真的相信这不是正确的方法。请问,有人可以在这里给我一些提示吗?

这种方法让你感到不舒服的原因是什么? - Alohci
使用点号来定位类是必要的。我正在寻找BEM + Sass,并且使用它的开发人员从不使用点号来定位类,因此我的代码似乎在某种程度上是错误的... @Alohci - user4002542
“我不知道给我的东西起什么名字”不是真正的问题。 - cimmanon
非常好的评论Cimmanon。谢谢! - user4002542
@cimmanon 我不同意,知道该如何命名事物是编程中最大的问题之一。然而,这个问题主要基于观点,不适合在SO上讨论。 - Stephan Muller
显示剩余4条评论
2个回答

6

首先,你不需要级联使用.participate .form。最好在同一个DOM节点上使用mix:.participate__form + .form

participate__form__label也是BEM方法不正确的用法。使用participate__form-label,或者participate-form__label,或者仅使用form__label

我会这样做:

<section class="participate">
  <form class="participate__form form">
    <label for="name" class="form__label"></label>
    <input type="text" id="name" name="form__input"/>
  </form>
</section>

participate块和__form元素的样式:

.participate {
  &__form {
    // outer styles here
  }
}

以及针对表单(form)本身的样式

.form {
  &__label {
    // inner styles here for label
  }
  &__input {
    // and input customization
  }
}

如果您仍需要在“参与”上下文中自定义表单,则可以使用修饰符:

.form--god-bless-participation {
  .form__label {
    // label customization
  }
}

这样,您就可以在需要时自由使用您的表单,甚至可以用另一个表单或类似于form的块替换participate块中的原始表单。


1
<section class="participate">
  <form class="participate__form">
    <label for="name" class="participate__form__label"></label>

在上面的代码中,您使用了两次 participate,一次是作为容器(父类),另一次是作为表单前缀。
当使用 participate 作为父类时,您不需要前缀。 HTML:
<section class="participate">
  <form class="form">
    <label for="name" class="form__label"></label>

sccs:

.participate {
     form {
        &__label {
        }
     }
}

或者,另一种选择是:
<section>
  <form class="participate__form">
    <label for="name" class="participate__form__label"></label>

sccs:

.participate {
     &__form {
        &__label {
        }
     }
}

但是当你的块被participate修饰时,你的HTML可以根据http://www.integralist.co.uk/posts/bem.html的示例,看起来如下所示:
<section class="participate">
  <form class="participate__form">
    <label for="name" class="participate__input participate__input--label"></label>
    <input type="text" id="name" name="participate__input participate__input--text"/>
  </form>
</section>

你的 SCSS 代码如下:

.participate {
    &__form {}
    &__input {
        &--label {
        }
        &--text {
        }
    }
}

3
“--label” 语法表示修饰符而非元素。在我看来,“--label” 和 “--text” 不是同一元素的修饰符,它们是不同的元素。我认为你最后给出的例子不符合 BEM 约定。 - Stephan Muller
@StephanMuller 感谢您的评论。您认为符合BEM标准的标签有什么例子吗? - Bass Jobsen
个人而言,我会使用.participate.participate__form.participate__label。这表明标签确实是.participate类的子元素,但在DOM中放置的深度有一定的自由度。虽然它通常也是form的子元素,但我认为在所有类中都指示精确结构并不是必要的。 - Stephan Muller
@StephanMuller 谢谢。确实应该可以。 - Bass Jobsen
1
看了你提供的例子,我认为 --text 可能是一个有效的修饰符,因为你可能会有不同变体的类似 __input 元素,比如 --number--file - Stephan Muller
1
个人而言,我会采取更加灵活的方法。与@Alex的建议类似,我认为将form视为一个块而不是一个元素是更好的实践。特别是当您考虑到网站上可能有其他表单时。我建议首先设计通用表单,然后使用“参与”作为修饰符:.form--participate。这将使您的代码更加清晰简洁:http://sassmeister.com/gist/487fbee21edceb11f7e9 - Ed B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接