Skip to content

[译]编写模块化的CSS(第三部分)—CSS文件组织结构 #24

Description

@stuxt

编写模块化的CSS(第三部分)—CSS文件组织结构 | Zell Liew

本文转载自:众成翻译
译者:stuxt
链接: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文件存储在不同文件夹的方式,因为:

  1. 我习惯了使用这种结构。

  2. 用我的方法,我可以很容易的找到我使用的组件。

  3. 无论我写的是网站项目还是webapp项目,这种方式能很容易的使项目目录保持高度一致。

  4. 我习惯把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 中声明了所有我在项目中使用的库文件。想知道我用了什么库文件的话,下面列的就是喽。如下所示:

  1. Normalize.css

  2. Mappy-breakpoints (媒体查询 临界点 使用的库)

  3. Typi (排版相关的一个库)

  4. Themify (如果我项目中使用了一个主题的话)

helpers/ 文件夹

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

variables/ 文件夹

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

  1. breakpoints

  2. colors

  3. typography

  4. 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的所有的样式。相比文件大小,模块化和清晰度是更值得我们去关注的点。

我们来总结一下!

总结

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

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

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

(如果你喜欢这篇文章,并分享了这篇文章,我会很感激。 [分享文章](http://twitter.com/share?text=Great article by @zellwk: Writing modular CSS (Part 3) — CSS file structure.&url=https://zellwk.com/blog/css-architecture-3/&hashtags=).)

(译者注:由于水平有限,如有异议,欢迎指正,谢谢~)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions