css – 一个元素的BEM方法可以属于和看起来不同,取决于块?

假设我有一个风格的复选框(认为材料设计,有一些将要实现所需的复选框风格).哪个块负责修改父系依赖的子块?

示例组件 – 复选框

所以我有以下:

<div class="CheckBox">
    <label class="CheckBox__label">
        <input class="CheckBox__input" type="checkBox" checked=true />
        <span class="CheckBox__icon glyphicon glyphicon-ok"></span>
        <span class="CheckBox__text">{label}</span>
    </label>
</div>

我在框中的每个元素的基础复选框.在应用程序的上下文中,复选框块可以生活在许多其他块(具有自己的BEM结构)中.

其他块的例子

当在“紧凑型面板”中说出时,复选框略有差异:

<div class="Panel Panel--compact">
    <p>disclaimer.. [text]</p>
    <CheckBox label="I Agree" /> 
</div>

选择一 – 父母“知道”关于孩子

那么,紧凑型小组应该如何“意识到”各种儿童街区,并为他们设计风格,所以:

// CheckBox.scss 
.CheckBox {
    margin: 15px;
    // .. other
}


// Panel.scss
.Panel {
    &.Panel--compact {
        margin: 0;
        padding: 2px;
    }
    &.Panel--compact .CheckBox {
        margin: 0;
        padding: 1px;
    }
}

选择二 – 孩子“知道”关于父母

或者,面板没有意识,复选框检查父范围.

// CheckBox.scss 
.CheckBox {
    margin: 15px;
    padding: 15px;
    // .. other
}
.Panel.Panel--compact .CheckBox {
    margin: 0;
    padding: 1px;
}


// Panel.scss
.Panel {
    &.Panel--compact {
        margin: 0;
        padding: 2px;
    }
}

选项三 – ?

也许还有其他的选择.

解决方法

通常BEM如果看起来不同,它们是不同的.

通常.

使用BEM处理上下文和状态有许多不同的选择.每个都有不同的利弊,所以你使用的将在很大程度上取决于你的用例.

我提到的第一个选项是使用后代选择器.你已经确定了这个选择,并且遇到了常见的“代码在哪里”的问题?

对于以下示例,我将依靠LESS语法,这只是为了使我更容易地演示代码中的关系.

后置选择器

如果要使用后代选择器,我建议将代码与子块分组.

widget.less

.widget {
  &__container {
    ...
  }
  ...
}

checkBox.less

.checkBox {
  &__label {
    ...
  }
  ...

  // using inversion to override checkBox styles in a widget
  // this will render to `.widget .checkBox` instead of
  // `.checkBox .widget` due to the `&` placement
  .widget & {
  }
}

我建议将样式与内部块相关联的原因是因为样式会影响复选框,并且级联顺序将很重要.

如果样式与父级关联,则相对于子样式重新排序父样式可能会不利地影响样式呈现的方式.

考虑这个包含顺序:

site.less

@import 'widget';
@import 'checkBox';

如果这些样式是小部件的一部分,那么可以在checkBox.less中被同样特异性的选择器覆盖.

修饰符

我建议使用修饰符状态.我通常不会将位置或上下文视为“状态”,因此修饰符可能不合适.此外,同一元素上的多个修饰符可能难以推理,因此难以设计.

假设您没有在复选框上使用修饰符,那么为面板中使用的情况添加修饰符可能会更简单.

.checkBox {
  &__label {
    ...defaults...
  }
  ...defaults...

  &--alt {
    &__label {
      ...overrides...
    }
    ...overrides...
  }
}

当然,这需要为面板中使用的特定情况更新标记,但是它也会打开您使用其他地方使用相同样式的复选框.

不同的选择器

我要重申我的第一点:如果他们看起来不同,他们是不同的.

这并不意味着你必须从复选框开始. BEM允许面向对象的样式.来一个新的名字,并扩展*复选框:

checkBox.less

.checkBox {
  &__label {
    ...
  }
  ...
}

复选框,2.less

@import (reference) 'checkBox';
.checkBox-2 {
  .checkBox;

  &__label {
    ...overrides...
  }
  ...overrides...
}

* in LESS我正在使用mixin,因为它通常比使用语言的扩展功能更适合扩展和覆盖样式.随意使用:扩展功能,只要注意选择器顺序就很重要.

重塑需求

有时我会遇到我想使用后代选择器或修饰符的情况,因为我需要在一个容器中为块定位.

在这些情况下,我经常发现容器本身是应该改变的.我通常会告诉它是容器,当我需要更新孩子有不同的:

>边距
>填充
>位置
>顶部,右侧,底部,左侧
>宽度
>身高
> flex

重构带来了其他挑战,但是我经常最终使用容器div来对包含其他块的块的插入区域进行规范化;因人而异.

我应该选哪个?

你可以(合理地)更新标记吗?

是的:如果您可以轻松更新标记以使用不同的类,我建议将复选框添加为新块.命名的东西很难,所以一定要记录哪一个是哪个地方.

否:如果您不能轻松更新类,使用修饰符也不是一个很好的选择.我建议跳过那个,然后回到好的后裔选择器.在BEM中,您真的想避免后代选择器,但有时候它们是工作的正确工具.

相关文章

Css3如何实现鼠标移上变长特效?(图文+视频)
css3怎么实现鼠标悬停图片时缓慢变大效果?(图文+视频)
jquery如何实现点击网页回到顶部效果?(图文+视频)
css3边框阴影效果怎么做?(图文+视频)
css怎么实现圆角边框和圆形效果?(图文+视频教程)
Css3如何实现旋转移动动画特效