×

CSS在大型项目中的结构设计

96
Bing573
2016.09.10 21:39* 字数 1447
CSS is awesome

写CSS简单,但写出可维护的CSS却很难。

这句话你可能早已听了上百遍。之所以说CSS代码难以维护,因为在CSS中所有的成员都是全局的。如果你是一名C语言程序员,你应该清楚全局变量的坏处。而只要是程序员就该知道隔离和可组合的模块是搭建可维护系统的关键所在。

有多CSS的风格指南被创建出来用于指导人们写出可维护的CSS代码,SMACSS, OOCSS, BEM, ITCSS, ACSS, CCSS, Atomic Design, Maintanable CSS, rscss, 以及更多

那么,问题出在哪儿呢?

span {
  font-size: 11px;
}
.header-right {
  font-size: 22px;
  text-align: right;
}

上面CSS代码声明的样式作为全局成员,将会影响到所有页面中的span和class为header-right的元素。没有封装,也没有隔离了的模块。

在标准的编程语言中,你只需要引入需要的模块来完成特定的功能。

# Python modules
import requests
from Flask import ur
// Node modules
var express = require(‘express’)

采用这种形式,你能够准确地知道什么将会影响你的代码,因为会对你正在实现的功能产生影响的只有你显示引入的模块。

然而在CSS中,情况反了过来。每当我写出一行CSS代码,都可能潜在地影响项目中的其他部分,除了我正着手修改的页面,其他页面的外观也可能被意外地改变。泄露已不足以形容CSS样式对我整个应用带来的影响,这些样式如洪水一般渗入到应用的每个角落。

这其实是可以理解的,特别是对一些基本的样式如印刷格式、简单的表单输入框样式以及天生就应该是全局的样式,采用这种方式是有意义的。HTML和CSS一开始本来为出版而生。为了能更好的理解隐藏在这两门语言本后的思想,我常常会设想对一本书进行排版,你会希望书中的每一页都看上去不一样吗——当然不会,你要的是简单且统一的风格,不是花里胡哨的东西。所以会有<H1>到<H6>,<section>等标签,和一直存在的全局样式。

然而,世界在改变,WEB也在跟着在变。我们创建的不再是网页,而是网页应用。HTML和CSS为出版而生的说法已不再适用于今天的WEB了。

我们需要新的方法来指定样式,或者新的方法来搭建WEB程序。不过现在我们仍然需要HTML和CSS, 这意味着我们需要谨慎的对待它们,以一种能创建出可管理和可维护的web应用的方式。

Peergrade.io处理CSS的方式

为class名称提供前缀

在Peergrade.io,我们所有的class都有.pg前缀。在CSS代码中不使用前缀是自找麻烦,原因是没有前缀的样式名称最终会和导入的样式发生冲突。比方说你需要一个datepicker, 你当然不会想自己从头写一个,所以你选择导入第三方代码。现在你向代码里导入了.prev, .next和.separator等样式声明,如果你没有为你自己声明的样式使用前缀,冲突随时都可能发生。

不要嵌套选择器

在Peergrade.io我们使用Sass,使用Sass,你的样式声明结构很快就会变得和你的HTML结构一致。就像下面一样:

#user-profile-page
    .profile-description
        h3
        ul
            li
                a

一段时间以后,你可能感觉还不错,但终会意识到这种样式结构是多么的脆弱。一开始,你或许认为在.profile-description下只会有一个列表,但一两个月之后你才意识到下面还会有其他的列表,很快样式结构就会打破你的一系列假设。

另外,这样的声明方式会将样式应用于父元素下的所有子元素,而不是按结构层级一一对应的方式。

为组件使用BEM命名方式

采用BEM的命名方式为class命名,尽可能创建可隔离的组件。我们并没有完全遵循BEM指南——只是采用了其命名方式,形式如下:

.block__element--modifier

在Sass中,我们是这样做的

.pg-deadline
  &__date
    // becomes `.pg-deadline__date`
    color: $color-gray
  &__header
    // becomes `.pg-deadline__header`
    font-weight: 700
    &--highlight
      // becomes `.pg-deadline__header--highlight`
      color: $color-green

在Sass中,我们采用嵌套的方式创建了遵守BEM的样式声明,虽然有点违反直觉,但编译过后会生成没有嵌套结构的CSS代码,全是顶级的样式声明。

作为第二条规则的例外,我们允许class名称采用.block-modifier形式。

.pg-deadline--editable
    .pg-deadline__header
        background-color: $color-blue
    .pg-deadline__date
        color: $color-black

在这个特殊例子中,我们允许存在一层CSS选择器嵌套。这使得我们只能为块(block)指定修饰器(modifier),从而不用为块(block)的每一个子元素(BEM中的E)指定修饰器(modifier)。

想要更好的了解BEM的命名方式,可以参考Harry Roberts的CSS指南中BEM命名方式部分

向前看

似乎至今还没有人真正找到一种方式可以很好的处理CSS(Hacker News上的相关文章),但至少,我们相信我们找到了一种可持续发展的基础——尽管还有可改善的空间。

原文链接:https://medium.com/peergrade-io/structuring-css-in-large-projects-37f1695f5ec8

前端技术
Web note ad 1