原文:How to get better at writing CSScss
做者:Thomas Lombarthtml
译者:JeLewine前端
废话很少说,我们就开门见山吧:想写出优质的CSS代码将会是很是痛苦的。不少开发者都不想作CSS开发。我能够作你想作的一切,可是,除了CSS!node
当我在构建应用时,CSS是我挺讨厌的部分。但你没法摆脱它,对吧?个人意思是,正是由于咱们如此的专一于用户体验和设计,因此如今咱们才不能跳过这一部分。ios
在开始一个项目时,一切都很正常。你有一些CSS选择器:.title
input
#app
,这看起来很是的简单。git
可是当你的应用变得愈来愈大时,它就开始变的愈来愈糟糕了。你对CSS选择器感到困惑。你发现你写的像div#app
.list
li.item a
诸如此类的东西,本身在一遍又一遍地在重复相同的代码。你把全部代码都放在文件末尾,由于你根本就不在意。CSS像一坨shit。而后你要狗带了:500行的CSS彻底无法维护。github
我今天有一个小目标:让你更好的去编写CSS。我想让你回首看看本身的旧项目并发出感慨:oh,boy,我怎么能写这么一坨东西?npm
好吧,你可能会想,你说的有道理。可是CSS框架呢?这就是他们的用法,不是吗?这就是咱们编写好CSS代码的方法。json
是的没错,不过这样仍是会有一些缺点:浏览器
不过毕竟,你已经开始在看这篇文章了。这必定是有缘由的,不是吗?因此,不用多说了,让咱们开始学习如何更好的编写CSS吧。
注意:这不是关于如何设计优雅应用程序的文章。它是关于学习如何编写和组织可维护的CSS代码的。
在这篇文章里我将会用SCSS做为例子。
SCSS是一个CSS的预处理器。简单来讲,它是一个CSS的超集:他为CSS添加了一些很酷的功能,例如变量,嵌套,导入和mixins。
我将先谈谈咱们当即会使用到哪些功能。
经过SCSS,你可使用变量了。它带来的主要好处就是可复用性。咱们假设你的应用有一组颜色。你的主色调是蓝色。
因此你的应用处处都是蓝色:按钮的背景颜色,标题的颜色,连接。蓝色无处不在。
忽然之间,你不喜欢蓝色。你更喜欢绿色了。
// 声明变量
$primary-color: #0099ff;
// 引入变量
h1 {
color: $primary-color;
}
复制代码
你还可使用SCSS来嵌套代码。看一下下面的例子:
h1 {
font-size: 5rem;
color: blue;
}
h1 span {
color: green;
}
复制代码
能够变成下面这样:
h1 {
font-size: 5rem;
color: blue;
span {
color: green;
}
}
复制代码
更具备可读性,不是吗?使用嵌套来编写复杂选择器所花费的时间更少。
出于可维护性和可读性方面的考虑,咱们不可能将全部代码保存在一个大文件中。在试验或构建小型应用程序时,这么作也许能够知足你的需求,但在更专业的状况下...请不要这么作。不过幸运的是,SCSS容许咱们这样作。
您能够经过使用前置下划线命名文件的方式来建立局部文件:_animations.scss
,_base.scss
,_variables.scss
等。
至于引入,咱们可使用@import
命令。例如,下面这样是你能够作的:
// _animations.scss
@keyframes appear {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
// header.scss
@import "animations";
h1 {
animation: appear 0.5s ease-out;
}
复制代码
看到这里,你可能会认为这里是否是搞错了。应该是_animations.scss
而不是animations
。
不。当你用这种方式命名时,scss能够很聪明的知道你正在讨论一个局部文件。
以上就是咱们所须要了解到的变量,嵌套,局部文件和引入。SCSS还有一些其余功能,像是mixins,继承指令(@for
,@if
,...)之类的,不过我今天不会在这里介绍他们了。
若是你想了解更多的信息,能够查看他们文档。他们写的很不错,很是容易理解。
【译者注:这是scss中文文档的地址】
我已经记不清有多少次在个人CSS课程里用到这些名称了。你懂的:.button
,.page-1
,.page-2
,.custom-input
。
咱们其实常常不知道该如何去命名。然而这是很是重要的。若是你正在构建一个应用程序,而且因为某些缘由决定将其搁置几个月,该怎么办?或者更糟糕的是,若是有人要交接该项目怎么办?若是你的CSS代码没有一个正确命名,那么很难一目了然地知道你在说什么。
BEM帮咱们解决了这个问题。BEM是一种命名约定,表明着块元素修饰符【译者注:原文为Block Element Modifier。在中文前端圈内发现大部分文章都将block直译为"块",其实译者我的以为翻译为"模块"可能会让人更好理解一点。不过本文仍是选择和已有译法保持一致】。
这种方法可使咱们的代码结构化,更加模块化和可复用。如今让我来解释什么是块,元素和修饰符。
咱们能够把“块”视为组件。你还记得小时候玩的乐高积木吗?【译者注:小时候没玩过,如今我也玩不起...】ok,让咱们回到过去。
你会如何建造一个简单的房子?你须要一个窗户,一个屋顶,一扇门,一些墙壁,就是这样。那些是咱们的块。他们各自有各自的做用。
**命名:**块名称:.block
样例:.card
,.form
,.post
,.user-navigation
如今,你将如何用你的乐高去搭一个窗户呢?这发现其中也许有一些看起很像边框,当你把四个边框组装在一块儿时,一个窗户就搭好啦。那就是咱们的元素。它们是“块”的一部分,它们是构建“块”的必要条件。可是,当它们离开块时就没有用了。
**命名:**块名称 + _
+ 元素名:.block_element
样例:.post_author
,.post_date
,.post_text
如今你已经搭起了一个窗户,不过也许你想要的是一个绿色的或小的。这些就是修饰符。它们是“块”或“元素”上的标志,它们用于改变行为和表现等。
**命名:**块名称或元素名 + -
+ 修饰名:.block_element-modifier
, .block-modifier
样例:.post-important
,.post_btn-disabled
margin
写在按钮上,不然您的按钮将与您的标题彻底绑定。请改用其余公用类来代替这个操做。下面是一个对你的小练习。转到你最喜欢或最经常使用的网站,并尝试使用BEM。
例如,下面就是我在Google商店中的想象:
轮到你了。要保持好奇人们如何能够作的更好。你必须本身去搜索,尝试和创造,这样才能更好的贴合你本身的需求。
你会发现下面的一些例子充分的展现了BEM的功力。
<!--html-->
<div class="post">
<span class="post__author">Thomas</span>
<span class="post__date">3 minutes ago</span>
<p class="post__text">
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Laboriosam sit voluptatem aut quis quisquam veniam delectus sequi maxime ullam, inventore blanditiis quia commodi maiores fuga, facere quaerat doloremque in. Nisi!
</p>
</div>
<div class="post mt-large post--important">
<span class="post__author">Thomas</span>
<span class="post__date">2 hours ago</span>
<p class="post__text">
Voluptatem incidunt autem consequatur neque vitae aliquam, adipisci voluptatum. Ipsum excepturi dolores exercitationem rem ab similique consequatur nesciunt, tempora aut vel unde.
</p>
</div>
<!--SCSS-->
.post {
display: inline-block;
padding: 1rem;
background-color: #ccc;
border: 1px solid #222;
border-radius: 5px;
&--important {
background-color: yellow;
}
&__author {
font-size: 1.2rem;
font-weight: bold;
color: blue;
}
&__date {
float: right;
}
&__text {
line-height: 2rem;
font-size: 1.3rem;
}
}
复制代码
<!--html-->
<div>
<button class="btn">
Click me
</button>
<button class="btn btn--danger">
Danger
</button>
<button class="btn btn--success">
Success
</button>
<button class="btn btn--small">
Small
</button>
<button class="btn btn--big">
Big
</button>
<button class="btn btn--border">
Border
</button>
</div>
<!--SCSS-->
.colors {
font-size: 1.5rem;
font-family: sans-serif;
}
.btn {
background-color: #FF6B93;
color: #fff;
text-transform: uppercase;
padding: 1.5rem 2.5rem;
border-radius: 4px;
transition: all .2s;
font-size: 1.3rem;
border: none;
letter-spacing: 2px;
cursor: pointer;
&:hover {
background-color: #D15879;
}
&:focus {
outline: none;
}
&--danger {
background-color: #FF3B1A;
&:hover {
background-color: #D43116;
}
}
&--success {
background-color: #00D123;
&:hover {
background-color: #00AB1D;
}
}
&--small {
padding: 1rem 2rem;
font-size: 1rem;
}
&--big {
padding: 1.8rem 4.5rem;
font-size: 1.7rem;
}
&--border {
background-color: #fff;
color: #FF6B93;
border: 1px solid #FF6B93;
&:hover {
background-color: #FF6B93;
color: #fff;
}
}
}
复制代码
【译者注:原文是在文章中插入了codepen。为了方便阅读,直接对输出结果进行了截图。有兴趣的读者能够直接访问这两个地址:样例1,样例2】
你坚持看到这儿了?优秀! 如今让咱们看看如何组织CSS文件。这部分将真正帮助你提升工做效率,并可以让你当即找到必需要修改的CSS代码的位置。
为此,咱们将了解7-1模式。
你可能会想这是个什么玩意【译者注:711便利店?233】。
相信我,这很简单。你只须遵照下面2条规则:
main.scss
文件中。就是这样。
base
:在这里,把全部的脚手架代码都放进去。经过脚手架,我指的是每次启动一个新项目时要写的全部CSS代码。例如:排版规则、动画、公用(公用类,我指的是margin-right-large
,text-center
,……之类的类)。components
:这里的名称是明确的。此文件夹包含用于构建页面的全部组件,如按钮,表单,swipers,弹出窗口等。layout
:用于布局页面的不一样部分。也就是说,页眉,页脚,导航,本身的网格等等。pages
:你有时可能会有一个页面会具备一些本身特定的样式。将它们与那些通用的样式分开,而后将它们放在pages文件夹中。themes
:若是你的应用有不一样的主题(黑暗模式,管理员模式等),请将它们放在此文件夹中。abstracts
:将全部函数与变量和mixin一块儿放在这里。vendors
:如今有什么项目是没有依赖外部库的?在vendor文件夹中放入全部不依赖于你的文件。你可能但愿在此处添加Font Awesome文件,Bootstrap和相似的东西。在这里导入你全部的partials。
@import abstracts/variables;
@import abstracts/functions;
@import base/reset;
@import base/typography;
@import base/utilities;
@import components/button;
@import components/form;
@import components/user-navigation;
@import layout/header;
@import layout/footer;
...
复制代码
是的。这看起很庞大。不过我知道你会这么想,这种架构适用于更大的项目,而不是小的。这里有一个适用于较小项目的版本。
首先,你不须要vendors
文件夹。只需将全部外部CSS代码放置在头文件中的连接标签中便可。而后你能够跳过themes
文件夹,由于你的应用可能只有一个主题。最后,你的页面不会有不少特定的样式,因此你也能够跳过pages
这个页面。太好了,只剩下4个文件夹了!
接下来,你又两个选择:
abstact
、components
、layout
和base
。main.scss
文件放在一块儿。因此你会产生如下相似的东西:sass/
_animations.scss
_base.scss
_buttons.scss
_header.scss
...
_variables.scss
main.scss
复制代码
这彻底取决于你本身。
你把我说服了!可是我该怎么用呢?个人意思是,浏览器并不支持SCSS,不是吗?
说的好!如今到了咱们的最后一步了。咱们将学习如何将SCSS文件编译成CSS。
咱们将使用一个名为node-sass
的包,它可以帮咱们将.scss
文件编译为.css
文件。
它的CLI(命令行界面)至关容易使用:
node-sass <input> <output> [options]
复制代码
node-sass
提供了多种选项,不过咱们只须要两个就够了:
-w
: 观察目录或文件。这意味着node-sass可以观察到代码中的任何更改。一旦更改发生时,它会自动编译为CSS。 这在开发时很是有用。--output-style
:CSS文件的输出模式是什么。它能够是如下值之一:nested
|expanded
|compact
|compressed
。咱们将使用它来构建你的CSS文件。若是你是一个有好奇心的人(我但愿你是,开发人员应该保持好奇!),能够到这里查看完整的文档。
如今咱们已经知道了咱们将使用哪些工具。接下来的事就很是简单了。只要跟着下面的步骤走:
mkdir my-app && cd my-app
npm init
node-sass
库:npm install node-sass --save-dev
index.html
和你的main.scss
文件:touch index.html
mkdir -p sass/{abstracts,base,components,layout} css
cd sass && touch main.scss
复制代码
package.json
中你的脚本命令:{
...
"scripts": {
"watch:scss": "node-sass sass/main.scss css/style.css -w",
"build:scss": "node-sass sass/main.scss css/style.css --output style compressed"
},
...
}
复制代码
index.html
文件的head
标签中:<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8"> <meta name=”viewport” content=”width=device-width, initial-scale=1.0">
<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
<link rel=”stylesheet” href=”css/style.css”>
<title>My app</title>
</head>
<body>
<h1 class=”heading”>My app</h1>
</body>
</html>
复制代码
就这样,已经能够跑起来了!当你开始coding并在浏览器中打开index.html
时,记得运行npm run watch:scss
。若是你想要压缩你的css文件,跑一下npm run build:scss
就行了。
你可能在开发中更但愿经过热更新来提升效率,而不是每次都要手动重载index.html
文件。
只要跟着如下几个简单的步骤:
live-server
包:npm install -g live-server
。注意:这是一个全局包npm-run-all
包到你的项目依赖中:npm install npm-run-all --save-dev
。它可以让你同时运行多个脚本命令。package.json
中:{
...
"scripts": {
"dev": "npm-run-all --parallel liveserver watch:scss ",
"liveserver": "live-server",
"watch:scss": "node-sass sass/main.scss css/style.css -w",
"build:scss": "node-sass sass/main.scss css/style.css --output-style compressed"
},
...
复制代码
如今,当你运行npm run dev
时,你能够当即看到你的修改,并且无需手动重载任何内容。太棒了,不是吗?
不过你知道更棒的是什么吗?为了方便你快速上手,我为此建了一个repo。
若是你想要知道我是如何将这些技巧应用到个人项目中的,能够查看这个repo。这里是演示结果。我但愿你能够经过这个例子拥有更深的理解。
这就是今天要说的一切!如今,你已经作好了编写可维护,模块化和可复用的CSS代码的准备。我但愿你喜欢这篇文章。若是是这样的话,请随时在评论中给我反馈。那么,下次再见啦!