编写模块化的CSS:CSS文件组织结构

发布于 大漠

本文转载自:众成翻译 译者:@小天同学 链接:http://www.zcfy.cc/article/3048 原文:https://zellwk.com/blog/css-architecture-3/

在之前两篇文章中我们已经讨论过如何使用BEM和Namespace来编写模块化的CSS。这篇文章中,我想避开把CSS选择器作为CSS文件结构和组织的依据的方法。

如果你思考过关于什么是文件组织的最佳实践,或者怎样能够在项目目录中更容易的找到你要找的CSS文件,或者一个文件应该是多大或者多小合理等问题,那么这篇文章就是为你写的。

让我们先看下你一般组织资源的两种方法。

你可以使用两种方式来组织你的资源。

本文中我所说的资源,是指CSS文件和JS文件。我们不能忽视他们两种之间的任何一种,特别是在今天这样的互联网环境下。

有两种主流的存储CSS文件和JS文件的方式。

第一种 是根据CSS和JS不同的文件类型存储在不同的文件夹里。这是一种大多数开发者所习惯的传统方式。如下所示:

- project/
    |- js/
    |- sass/

第二种 是根据他们分属的不同的组件来存储CSS和JS文件。使用这种方法,文件结构就像如下所示的结构:

-project/
    |- component-a/
        |- index.scss
        |- index.js
    |- component-b/
        |- index.scss
        |- index.js

这种方式经常会被用React这类框架开发Webapp的开发者使用,因为这类开发者通常把HTML直接写在JavaScript文件里。使用Webpack你可以很简单的使用require来引用你所需要的样式,如下所示:

import css from './index.scss';

你应该使用哪一种方式呢?

老实说,这两种方式之间没有太大的差别。最好的方式就是那个能使你清楚了解你组件结构的方式。

基于这一点,我更倾向于使用传统的把CSS和JS文件存储在不同文件夹的方式,因为:

  • 我习惯了使用这种结构。
  • 用我的方法,我可以很容易的找到我使用的组件。
  • 无论我写的是网站项目还是webapp项目,这种方式能很容易的使项目目录保持高度一致。
  • 我习惯把CSS文件和JS文件尽可能的分开。

就像上文说的,我有我偏好的方式。你也可以有你偏好的方式。这完全是可以的,因此,选择一种你喜欢的方式并坚持用下去。

我如何组织我的项目

我会尽可能的把我开发的代码放在src/ (源文件)文件夹里。src/文件夹里的文件经过编译、替换后会被放在用于生产环境使用的dist/文件夹里。因此,我的项目初始化目录结构 如下所示:

- project/
    |- dist/ # 用于生产环境
    |- src/  # 所有的开发源代码
        |- js/
        |- scss/
        # 模板和其他必须的文件(templates and other stuff as required)

从这一点开始,我会着重讲scss/文件夹,因为js/文件夹跟CSS是同样的道理(可能东西比CSS更少)。

scss/文件夹包含7个子文件夹,可能还会有一个公共部分scss文件和一个主要的入口scss文件,如下所示:

- scss/
    |- lib/
    |- helpers/
    |- variables/
    |- base/
    |- layouts/
    |- objects/
    |- components/
    |- styles.scss
    |- _utilities.scss

首先,我们来看下在styles.scss文件里都有什么内容。这是MP(理解为我们读者的项目)项目参考的重点,具体内容如下所示:

// Libraries and helpers
// ---------
@import 'lib/lib';
@import 'helpers/helpers';

// Variables
// ---------
@import 'variables/colors';
@import 'variables/typography';
@import 'variables/breakpoints';
@import 'variables/themes'; // only when necessary

// Reset and base files
// --------------------
@import 'base/base';

// Layouts
// -------
@import 'layouts/layouts';

// Objects
// -------
@import 'objects/buttons';
@import 'objects/input';
@import 'objects/typography';
// Other objects as necessary

// Components
// ----------
@import 'components/component-name-1';
@import 'components/component-name-2';
@import 'components/component-name-3';
@import 'components/component-name-4';
// Other components as necessary

// Utilities
// ----------
@import 'utilities';

// Shame
// -----
@import 'shame';

一目了然,在styles.scss文件里你可以知道,在项目中你使用了“4种变量”、“3个对象”和“4个组件”。

这种列出变量、对象和组件的声明方法,是scss组织结构的核心和灵魂。这种方式可以让我立即知道我的项目中用了什么。

当我想要找一个组件的时候,我总是可以打开styles.scss文件,然后在Sublime Text’s的搜索框中输入“组件C的名字”去搜索组件。

用Sublime Text搜索文件

用Sublime Text搜索文件

这种方式百试不爽,因为我不需要太多的搜索就能正确的找到我要找的文件。

现在,我们来看一下每一个子文件夹中都包含什么内容。

lib/ 文件夹

lib/文件夹只包含一个文件 — _lib.scss_lib.scss 中声明了所有我在项目中使用的库文件。想知道我用了什么库文件的话,下面列的就是喽。如下所示:

  • Normalize.css
  • Mappy-breakpoints (媒体查询 临界点 使用的库)
  • Typi (排版相关的一个库)
  • Themify (如果我项目中使用了一个主题的话)

helpers/ 文件夹

helpers/文件夹中放置的是项目中使用的封装的方便使用的mixinsfunctions。很多这种mixins的例子,如: 清除浮动的hack, 元素的显隐和CSS开发的形状(如三角形)等等。

variables/ 文件夹

variables/ 文件夹是存储我在项目中使用的变量的地方。从styles.scss文件中你可以知道,我使用了如下的四种变量:

  • breakpoints
  • colors
  • typography
  • themes

我喜欢把这些变量存储在Sass的枚举map中,因为我可以用自己写的functions从Sass map中很方便的取到他们。例如,_breakpoints.scss文件中的内容,如下所示:

$breakpoints: (
    small: 400px,
    med: 640px,
    large: 900px,
    wide: 1100px,
    mega: 1800px,
    ultra: 2800px,
);

$breakpointsmap中提取临界点的值,我用的是我创建的方法库(Mappy breakpoints):

.component {
    @include mappy-breakpoint(small) {/* styles here */}
}

我不会使用其他的文件,因为其他的文件和_breakpoints文件是基本一样的文件。

我们继续看其他的文件夹.

base/ 文件夹

base/ 文件夹是存放我开发的除了Normalize.css之外的所有resets。例如:我会强制的重置 marginspaddings和输入框、按钮等元素的样式,如下所示的那样:

// Resets margins and paddings for headers, ul, ol and p
h1,h2,h3,h4,h5,h6,ul,li,p,blockquote {
    margin: 0;
    padding: 0;
}

// Completely resets form items
// ----------------------------
// Super hard reset that removes all borders
// and radius of all form items.
// ============================
input,
textarea,
button {
    border: 0;
    border-radius: 0;
    outline: none;
    appearance: none;

    &:hover,
    &:active,
    &:focus {
        outline: none;
    }
}

除了重置样式之外,我也会在这个文件里存放我开发的用于整个项目的样式(通常我们所说的全局样式)。例如:

// Use border-box for everything
html {
    box-sizing: border-box;
}

*,
*:before,
*:after {
    box-sizing: inherit;
}

// Set Image and Objects to have a max-width of 100%
embed,
iframe,
img,
object,
video {
    max-width: 100%;
}

你把什么内容存在这里,最红还是取决于你自己。如果你不想像我一样强制的重置一些样式的话,你可以忽略整个base/文件夹不用管它。

layouts/ 文件夹

layouts/文件夹是用来存放我编写的在整个项目中全局使用的布局样式。 如果你不懂我说的内容的话,你可以看看之前我写的一篇对于这块内容解释的文章,点此查看文章

objects/ 和 components/ 文件夹

objects/components/ 文件夹的名字很好的解释了自己的用途。这两个文件夹是分别用来存放我编写的对象和组件的地方。 每一个对象/组件都有自己的文件。所以,从styles.scss中可以看出,我有三个对象文件:input, buttontypography

注: 我关于对象和组件的定义和其他人不同,如果你还没有阅读了我之前的文章,请阅读了我之前的文章

就对象和组件而言,我总是从对象开始编写。每当一个对象增长到包含另一个对象或者一个组件的时候,我都会借助Sublime Text的查找替换工具把所有的.o-object重命名为.c-object

Sublime Text的查找替换工具

Sublime Text的查找替换工具

utilities.scss 文件

_utilities.scss文件是用来存放我编写的 公用命名空间类 ,例如: .u-text-center

我们继续。

最小/大文件的大小应该是多少?

根据代码行数来决定一个文件的大小不是最好方法。一些人对于只有两行的代码文件感到反感,认为文件太小没有必要单独为一个文件。另外有一些人讨厌在一个有着300行代码的文件中去纠正修复其中存在的bug。

我觉得文件的大小不是我们应该关心的,我通常鼓励大家在一个文件中写尽可能多的代码,因为那是有意义的。例如,在components/_component-a.scss文件中编写你需要的.c-component-a的所有的样式。相比文件大小,模块化和清晰度是更值得我们去关注的点。

我们来总结一下!

总结

文件结构和组织是一个主观决定的事情。不同的人对此会有不同的想法,也就是说不同人会有适合自己的不同组织形式。与其沉溺于寻找一种最好的文件组织结构,不如选择一个你认为最好的并坚持使用它。目标都是一致的,每一次你都能很方便的找到你要找的文件。

如果你觉得你现在使用的结构不够好,你就会厌烦其中的一部分并发现其中为问题,然后你就有了可改进的空间。

你喜欢这篇关于文件结构的文章吗?你觉得这篇文章如何呢?你是如何组织你的文件的?读完我的这篇文章后,会有什么感觉不同和改变吗?我希望在下面的评论区听到你的想法:)Nike SB Hyperfeel Koston 3