更多 vs 更少 - 简单比较
神奇的是,虽然在标签里面放那么多类让我非常不爽,可是人们爱哈利,因为他太特么能说了。提倡的某些东西,比如说 OOCSS 和单一责任原则,从我自己创建的一系列日益复杂的网站来看,我可以说这确实值得对样式行为进行解耦,不过直到最近我才找到一种让我觉得满意的方式来实现它。
我原先有做过一个 BEM 的版本,它强调了独立高于重用 ‐ 每个新的块默认是没有样式继承的,允许组件独立开发并且可以避免打乱页面其它样式的风险。不过代价就是碎片化(fragmentation) ‐ 忽然你会发现你有了 10 种不同的样式链接,12 种不同的蓝色,18 种差别细小的按钮样式等。妮可?沙利文,OOCSS 的作者,去年在墨尔本做了一个超赞的演示,讲到了这个问题是有多普遍,以及怎么解决它。
对我来说,我觉得可以接受的解决方案是,深入 CSS 的预处理机能,从而取得 BEM 的独立性以及 OOCSS 的一致性。比如说,下面这样的:
- <a class='btn large rounded'>
- .btn { /* button styles */ }
- .large { /* global large-type modifier */ }
- .rounded { /* global rounded-border modifier */ }
应该改成这样:
- <a class='btn btn--large btn--rounded'>
- .btn { /* button styles */ }
- .btn--large { @extend %large-type;}
- .btn--rounded { @extend %rounded-borders;}
我成功终结了充满了占位符的文件,比如满眼都是那些_typography.scss 和 _brand.scss,这不但让我有能力控制碎片化,同时还能默认保持了样式的对每个新组件的独立性。所有的东西都挺好的,起码有那么一段时间是这样。
修饰符: M 是怎样破坏 BEM 的
只要你做关于 CSS 类的命名 & 维护方面的任何研究,你一定会要看到尼古拉斯.加拉格尔的杰作"关于 HTML 的语义和前端架构"。其中一部分特别吸引我,他称之为修饰符的 '单类模式' vs '多类模式'。简单的说,你的 HTML 会有两个版本,看起来像这样:
这通过两个备选的 CSS 模式实现:
- /* Single class */
- .btn, .btn--large { /* base button styles */ }
- .btn--large { /* large button styles */ }
- /* Multi class */
- .btn { /* base button styles */ }
- .btn--large { /* large button styles */ }
这两个模式的差别在于 btn--large 是否只要它自己就足够了,还是说它需要依赖类 btn 。单类模式说”可以”,它看起来更简单而且可以避免有人忘记把 btn 包含进来的情况。而且它也不啰嗦,配合 SASS 的 @extend 方法,它对 CSS 来说不像一个负担,只不过它有一个致命伤。
上下文重写
我们假设你的所有按钮都有背景色,除了你顶部导航栏那些没有。在多类模式下,所有的按钮,大的小的,圆的方的,等等之类,都会包含类 btn,所以你可以这样写:
- header > nav > .btn { background: none; }
而在单类模式中,我们不知道哪种按钮会被重写,所以你只好这样:
- header > nav { .btn, .btn--large, .btn--rounded { background: none; }}
很显然,这不理想 - 追加一个按钮变体也就意味着要检查所有地方的按钮样式重写以及添加一个新类。用属性前缀选择器 ^=,可以检查你的属性是否以特殊字符串开头,比如:
- <a class='btn--large'>
- [class^='btn'] { /* base button styles */ }
- .btn--large { /* large button styles */ }
- header > nav > [class^='btn'] { /* Overrides for all buttons */ }
这实现了单类模式下的简单的上下文重写,不过它还是太弱了,不是一个可以托付的选择。最致命的是,如果另一个类在 btn--large 出现,而且前缀选择器还没匹配到它,那么之后的所有的都完蛋了。而且,它还没有显式的