CSS命名规范和模块化的思考

之前曾经考虑过这个问题,尝试过把可能通用的部分都写在了main.css中,后来发现想起来使用的时候很少。
最近因为页面中多次设置.btn按钮样式,发生了样式混淆,来来回回改了几遍,这个对了却不小心连带修改了另一个btn按钮样式。这次反复的修改让我意识到自己的css命名带来的潜在问题。
我在网上查询了关于CSS样式命名和模块化的资料。最后决定写一份自己的规范以供使用。

比较常见的概念与思想:Sass 、SCSS、LESS、BEM、OOCSS、AMCSS

BEM:

什么是BEM?

BEM的意思就是块(block)、元素(element)、修饰符(modifier),是由Yandex团队提出的一种前端命名方法论。这种巧妙的命名方法让你的CSS类对其他开发者来说更加透明而且更有意义。BEM命名约定更加严格,而且包含更多的信息,它们用于一个团队开发一个耗时的大项目。BEM 命名会使得 Class 类名变长,但经过 gzip 压缩后这个带宽开销可以忽略不计。

块(block):一个独立的有实际意义的组件或者模块,每个块在逻辑上和功能上都是相互独立的。比如button、nav、tab这些,我们在以后的其它项目中也可以直接套用这个组件。对着block我们应该根据功能来命名如btn-warning,不要根据可以变动的样式来命名btn-red。

元素(element):属于块的一部分,它没有独立的意义。任何元素在语义上都要绑定到它的块上。比如鼻子是block,element是DNA。在 BEM 命名规范中,Element 的命名规范是使用 __。如tags__news__items。这种看起来很长的命名规范会给你更好的保障。在scss中,简化这种写法可以用&__items。
修饰符(modifier):是块或元素的标志。我们可以使用它们来更改其外观,行为或状态。tabs__nav__items--blue或者tabs__nav__items--warning。

使用BEM你需要克服对于多余的丑陋的写法的不适性。scss改进BEM方法:
  • 这个命名方法可以变形为org-ComponentName--modifiername。我认为在我们的项目里,这个要更为好写和美观。
  • 使用'&'选择器时我们可以在保持有很好的组织性和可读性的同时避免嵌套带来的样式冲突:

.aboutSection { &__wrapper { max-width 108rem; padding: 3rem 0; }}

复制代码

这个模块看上去像是嵌套但并不会带来嵌套所造成的权重差异等问题。

  • @extend指令,我们不仅可以消除BEM命名的冗余,而且可以修剪下来你的标记。关于这个建议你向上继承而不要向下引入:

<li class="nav__item nav__item--active"></li>
&__item { color: white; &--active { @extend .nav__item; border-bottom: 1px solid red; } }复制代码
  • 永远不应该链式命名 BEM 元素。 如果你的 class 最终像这样 .form__row__input是错误的。


命名空间:

我认为这可以应用在我们的项目中,提高了代码的可读性。
  • p-页面(Page) (应用于body元素的类),对可维护性不是那么重要的静态页面十分有用 —应该避免嵌套使用 (例: p-Homepage);
  • l-布局(Layout), 比如列(columning),包裹(wrappers) 和容器(containers)等等(例: l-Masthead, l-Footer);
  • c-组件(components )(例: c-Dropdown, c-Button…);
  • u-公共类(Utility classes) — 不会发生改变, 在代码的任何地方都不能重载。(例: u-textCenter, u-clearfix…);
  • js-JavaScript钩子,永远不应该出现在CSS中。
这些命名空间暂不使用。
  • is-,has-:表示一种状态或条件样式。如 .is-active
  • o-:表示一个对象(Object),如 .o-layout。
  • t-:表示一个主题(Theme),如 .t-light。
  • s-:表示一个上下文或作用域(Scope),如 .s-cms-content。

CSS的scoped实现?

使我们的css具有模块化性质,不会污染到其他模块。
一直以来,文档上的STYLE元素通常都是作用域全局的,选择器按照全局的CSS优先规则来设置的。要实现局部的选择需要先选到容器元素,再用后代选择器来实现。scoped属性可以让STYLE元素不再作用于全局,而从当前STYLE元素所在的容器开始选择后代。
但是这种方法只有在火狐浏览器才生效,在vue项目中,这种方法的实现是vue在编译的时候,把带有scoped属性的的模块,加上了一个唯一的属性,然后通过类名+属性选择器的方法来实现模块化。
在子组件中使用*{background: red;},测试加scoped和不加scoped的效果即可明白。

CSS究竟该不该嵌套?

过深的嵌套会带来风险。
scss只是个框架,最终呈现的还是原生css,而你这样嵌套后最后解析出来的代码十分臃肿。并且DOM紧密耦合,你修改一条可能就会影响其他。层级嵌套过度的与页面中的某一部分耦合了。我们在软件工程的思想中追求的就是解耦。
不要让你的嵌套层级多余三个。嵌套的太多自己看着就蒙逼。(之前我的代码从开始使用scss之后,嵌套深如大海……)
在你的结构中不要添加超过两个类名。如果你需要覆盖一些样式的时候请使用有意义的名称。
在Sass中还提供了一个@at-root 的功能,可以让你直接跳出去。这样也可以避免嵌套层级过深。

该不该使用元素标签?

没想清楚~

原则:

  1. CSS 命名要求:语义化易于理解,可重用性高,后期维护容易,加载渲染快。
  2. 以英文单词命名,避免无意义的缩写,以 - 连接。根据BEM规范,命名格式为block-element--modifier。
  3. 在你的结构中要尽量减少类名。
  4. 不要让你的CSS嵌套层级多余三个。
  5. 包裹容器如何命名:container/list - wrap - item - header - content
  6. 如果样式的命名让你自己瞄一眼都看不懂又无法改变,请务必注释。
  7. 所有的<template>中的包裹的最高级唯一元素为<article>,因为在<article>中标签可以自动补齐,<div>不可以。
  8. 使用有意义的或通用的ID和class命名。ID和class的命名应反映该元素的功能或使用通用名称,而不要用抽象的晦涩的命名。反映元素的使用目的是首选;使用通用名称代表该元素不表特定意义,与其同级元素无异,通常是用于辅助命名;使用功能性或通用的名称可以更适用于文档或模版变化的情况。


写在后面:

这个规范特别违背本能,一般来说希望越简单越方便越短越好,这个都不占。刚刚写感觉很别扭,不过确实非常规整,语义上更容易理解,写得好的话看到命名就知道是在哪里了。现在的代码就是太乱了,开始尝试使用一段时间,我的理解是这个规范写得熟练了应该并不麻烦,而且让你对自己的代码了解的更加的清晰,后期组件化完成高重构性会使代码有种拼贴的简单。现在开始尝试,慢慢改进然后确定。


转载于:https://juejin.im/post/5c10cd06e51d457c5336062e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值