编写模块化的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搜索文件
这种方式百试不爽,因为我不需要太多的搜索就能正确的找到我要找的文件。
现在,我们来看一下每一个子文件夹中都包含什么内容。
lib/ 文件夹
lib/
文件夹只包含一个文件 — _lib.scss
。 _lib.scss
中声明了所有我在项目中使用的库文件。想知道我用了什么库文件的话,下面列的就是喽。如下所示:
- Normalize.css
- Mappy-breakpoints (媒体查询 临界点 使用的库)
- Typi (排版相关的一个库)
- Themify (如果我项目中使用了一个主题的话)
helpers/ 文件夹
helpers/
文件夹中放置的是项目中使用的封装的方便使用的mixins
和 functions
。很多这种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,
);
从$breakpoints
map中提取临界点的值,我用的是我创建的方法库(Mappy breakpoints):
.component {
@include mappy-breakpoint(small) {/* styles here */}
}
我不会使用其他的文件,因为其他的文件和_breakpoints
文件是基本一样的文件。
我们继续看其他的文件夹.
base/ 文件夹
base/
文件夹是存放我开发的除了Normalize.css之外的所有resets。例如:我会强制的重置 margins
、paddings
和输入框、按钮等元素的样式,如下所示的那样:
// 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
, button
和 typography
。
注: 我关于对象和组件的定义和其他人不同,如果你还没有阅读了我之前的文章,请阅读了我之前的文章。
就对象和组件而言,我总是从对象开始编写。每当一个对象增长到包含另一个对象或者一个组件的时候,我都会借助Sublime Text的查找替换工具把所有的.o-object
重命名为.c-object
。
Sublime Text的查找替换工具
utilities.scss 文件
_utilities.scss
文件是用来存放我编写的 公用命名空间类 ,例如: .u-text-center
。
我们继续。
最小/大文件的大小应该是多少?
根据代码行数来决定一个文件的大小不是最好方法。一些人对于只有两行的代码文件感到反感,认为文件太小没有必要单独为一个文件。另外有一些人讨厌在一个有着300行代码的文件中去纠正修复其中存在的bug。
我觉得文件的大小不是我们应该关心的,我通常鼓励大家在一个文件中写尽可能多的代码,因为那是有意义的。例如,在components/_component-a.scss
文件中编写你需要的.c-component-a
的所有的样式。相比文件大小,模块化和清晰度是更值得我们去关注的点。
我们来总结一下!
总结
文件结构和组织是一个主观决定的事情。不同的人对此会有不同的想法,也就是说不同人会有适合自己的不同组织形式。与其沉溺于寻找一种最好的文件组织结构,不如选择一个你认为最好的并坚持使用它。目标都是一致的,每一次你都能很方便的找到你要找的文件。
如果你觉得你现在使用的结构不够好,你就会厌烦其中的一部分并发现其中为问题,然后你就有了可改进的空间。
你喜欢这篇关于文件结构的文章吗?你觉得这篇文章如何呢?你是如何组织你的文件的?读完我的这篇文章后,会有什么感觉不同和改变吗?我希望在下面的评论区听到你的想法:)Nike SB Hyperfeel Koston 3