浅谈css模块化

时间:2022-03-05 08:45:28

模块化是我们经常听到的一个话题,那什么是模块化呢?从字面意义上我们大概能对它有个初步的判断,那么我今天就根据我自己的想法谈谈css模块化。

背景:起初的css长什么样?

/* index.css */

body {
  margin: 0;
  padding: 0;
  font-size: 18px;
}

.box {
  background: #333;
  color: #fff;
}

.box .list {
  margin-left: 10px;
}

.box .list .item {
  border-bottom: 1px solid #ccc;
}

.box .list .item:last-child {
  border-bottom: 0;
}

.box .list .item a {
  text-decoration: none;
  color: #fff;
}

.box .list .item span {
  color: red;
}

.box .list .item a ... {
  ...
}

  显然,这里存在几个问题:

  1.选择器越来越长,书写累赘(选择器冗长)

  2.dom的空间顺序繁杂,不容易分清元素关系(层级结构不清晰)

  3.我们很难做到复用,假设另一个页面也需要用到这个box,那么我们必须将box有关的部分粘贴一份,然后去另一个页面复制。(代码难以复用)

这里的问题1,2我们先放一放,看看问题3代码复用怎么解决:

  要实现代码复用很简单,我们只需要提供一个公共css库,来存放我们的公共样式以及公共模块即可:

/* common.css */

body {
  background: #fff;
  color: #333;
  font-size: 16px;
}

.box ... {
  background: #333;
  color: #fff;
  ...
}

.another-box ... {
  ...
}

  然后只要我们在html页面中引入这个css文件和index就可以了,很完美对么。可是如果你在实际中这样操作过就会发现几个问题:

  1.如果项目非常大,那么我们只要是有复用需求的css代码,我们都会往common中放,这样会导致common体积过大。

  2.假设有一个页面内容非常少,比如404页面,可能只需要用到少量公共样式,但是为了维护问题,我们还是要引入common,这就显得不够“轻”。

  3.由于common越写越大,每个页面的私有css样式的可用的名称就越来越少。

总结上面的问题其实只有两个:冗余,污染。冗余的问题在所难免,重就重些,但也不是燃眉之急。污染的问题确实迫在眉睫,如何用一套规范来组织我们的代码?

首先我们把页面分成三个部分:框架,模块,元件

  框架

框架是指构成页面的基础结构,它是一个页面的筋骨。我们假设有个页面index.html,它的整体最外围表现为一个class为.g-index的div,然后它由页头(.g-hd)、主体(.g-bd)、页脚(.g-ft)三个部分组成:

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>index</title>
</head>
<body>
  <div class="g-index">
    <div class="g-hd"></div>
    <div class="g-bd"></div>
    <div class="g-ft"></div>
  </div>
</body>
</html>

  模块:

模块是页面上数量最多,同时也是最重要的部分,它是代码复用的主体部分,是一个个按照功能划分的区域,如导航栏、轮播图、登录窗口、信息列表等等,模块之间相互独立,分布在页面上,嵌在框架的各个位置上,组成一个丰富多彩的页面。

还是以index.html为例,我们假设页头有个导航栏模块(.m-nav),主体有个新闻列表模块(.m-news),页脚有个版权声明模块(.m-copy_right)

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>index</title>
</head>
<body>
  <div class="g-index">
    <div class="g-hd">
      <div class="m-nav">
        nav
      </div>
    </div>
    <div class="g-bd">
      <div class="m-news">
        news
      </div>
    </div>
    <div class="g-ft">
      <div class="m-copy_right">
        copy_right
      </div>
    </div>
  </div>
</body>
</html>

  元件:

元件是独立的、可重复使用的,并且在某些情况下可以作为模块的组成部分的一种细颗粒。比如一个按钮,一个logo等等。某种意义上说,它其实可以等同于模块,因为它们两者的区别只是规模不同而已。模块更强调一个功能完整的整体,而元件则更强调独立性。

我们假设这个页面还需要在页头放个logo(.u-logo),在导航栏中放置一个登录按钮(.u-login_btn):

<!-- index.html -->

<!DOCTYPE html>
<html>
<head>
  <title>index</title>
</head>
<body>
  <div class="g-index">
    <div class="g-hd">
      <img class="u-logo" alt="logo">
      <div class="m-nav">
        nav
        <a href="/logoin" class="u-login_btn">登录</a>
      </div>
    </div>
    <div class="g-bd">
      <div class="m-news">
        news
      </div>
    </div>
    <div class="g-ft">
      <div class="m-copy_right">
        copy_right
      </div>
    </div>
  </div>
</body>
</html>

  这样子分类的用处是什么呢?第一,让结构更加清晰。第二,我们常说的语义化。第三,一定程度上减轻了命名空间的“负担”。

  但是公有模块和私有模块还是有一定程度上的冲突,于是乎我们可以把共有模块的开头都改为cm-news,私有模块用m-news,这样就不会冲突了。但是我们在页面制作中会遇到过这样一个问题:一个模块一开始是私有模块,但是后面的一个页面也用到了这个模块,于是这个模块应该要变成共有模块(还是维护问题)。但是有一个问题,有时候我们在做一个页面的模块时,根本想不起来之前还有页面中有用到一个相同的模块。怎么办?

  索性我们可以顶一个这样的规定:如果不是确定是私有模块,一律设置为公有模块。但是这有一定程度上的引起了common样式的重。

回到一开始的两个未解决的问题

1.选择器冗长

2.结构层级不清晰

:如何解决?

: 你听说过LESS/SASS么?