【译】如何更好的编写CSS

原文:How to get better at writing CSScss

做者:Thomas Lombarthtml

译者:JeLewine前端

废话很少说,我们就开门见山吧:想写出优质的CSS代码将会是很是痛苦的。不少开发者都不想作CSS开发。我能够作你想作的一切,可是,除了CSSnode

当我在构建应用时,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吧。

注意:这不是关于如何设计优雅应用程序的文章。它是关于学习如何编写和组织可维护的CSS代码的。

SCSS

在这篇文章里我将会用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代码:BEM方法论

我已经记不清有多少次在个人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

一些笔记

  • 当您使用BEM时,你为类命名,也只能是为类命名。没有ID,没有标签。只有
  • 块/元素能够嵌套到其余块/元素中,但它们必需要能彻底独立。记住这个词:独立。所以,请不要由于你想将按钮放在标题下就将margin写在按钮上,不然您的按钮将与您的标题彻底绑定。请改用其余公用类来代替这个操做。
  • 是的,你的HTML文件将会过载。但不要担忧,与BEM带给您带来的好处相比,这是一个小小的缺点。

一个例子

下面是一个对你的小练习。转到你最喜欢或最经常使用的网站,并尝试使用BEM。

例如,下面就是我在Google商店中的想象:

谷歌商店BEM

轮到你了。要保持好奇人们如何能够作的更好。你必须本身去搜索,尝试和创造,这样才能更好的贴合你本身的需求。

将它们合在一块儿

你会发现下面的一些例子充分的展现了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;
  }
}
复制代码

样例1

<!--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;
    }
  }
}
复制代码

样例2

【译者注:原文是在文章中插入了codepen。为了方便阅读,直接对输出结果进行了截图。有兴趣的读者能够直接访问这两个地址:样例1样例2

组织CSS文件:7-1模式

你坚持看到这儿了?优秀! 如今让咱们看看如何组织CSS文件。这部分将真正帮助你提升工做效率,并可以让你当即找到必需要修改的CSS代码的位置。

为此,咱们将了解7-1模式。

你可能会想这是个什么玩意【译者注:711便利店?233】。

相信我,这很简单。你只须遵照下面2条规则:

  1. 将全部的局部文件写入7个不一样的文件夹中。
  2. 将它们所有导入位于根级别的一个main.scss文件中。

就是这样。

7个文件夹

  • base:在这里,把全部的脚手架代码都放进去。经过脚手架,我指的是每次启动一个新项目时要写的全部CSS代码。例如:排版规则、动画、公用(公用类,我指的是margin-right-largetext-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个文件夹了!

接下来,你又两个选择:

  1. 你但愿你的CSS代码组织遵循7-1模式,所以你保留了abstactcomponentslayoutbase
  2. 你更喜欢有一个大文件夹,把全部的局部文件和你的main.scss文件放在一块儿。因此你会产生如下相似的东西:
sass/
  _animations.scss
  _base.scss
  _buttons.scss
  _header.scss
  ...
  _variables.scss
  main.scss
复制代码

这彻底取决于你本身。

你把我说服了!可是我该怎么用呢?个人意思是,浏览器并不支持SCSS,不是吗?

说的好!如今到了咱们的最后一步了。咱们将学习如何将SCSS文件编译成CSS。

从SCSS到CSS

为此,你须要先安装Node.jsNPM(或Yarn)

咱们将使用一个名为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"
  },
  ...
}
复制代码
  • 将包括那些已编译的CSS文件的引用连接添加到你的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代码的准备。我但愿你喜欢这篇文章。若是是这样的话,请随时在评论中给我反馈。那么,下次再见啦!

相关文章
相关标签/搜索