给恐龙们解释一下当今的CSS(译文)

恐龙 ,远古时代的动物,指的应该是像我这样,因为Internet的出现,20年前就知道,接触过CSS,但还好没有”入坑”的程序员。

原文: Modern CSS Explained For Dinosaurs

0

对于web开发人员,CSS被认为是其中一个最容易也是最难学习的语言。上手肯定是比较容易的 - 你可以定义CSS的属性和其对应的值,让后把它们应用到某些HTML元素,然后,没有然后啦。但是,在一个大型的项目中,当你想把一大坨CSS代码组织好,一切就会变得纠缠不清和十分复杂。当你想通过CSS只改变一个页面中的某个元素的样式,结果任何一行CSS的变动往往也会导致其它页面、其它元素的样式发生意想不到的改变。

CSS样式具有复杂的内在继承性,为了对付这种复杂性,各种最佳实践应运而生,但问题是,大家对这些最佳实践没有明显的统一认识,而且很多最佳实践是互相抵触的。如果你是第一次学习CSS,这肯定会让你摸不着头脑。

本文的目的是回顾各种CSS的编写方法和工具如何演化到今天(2018年)的样子。通过了解过去,让我们更容易理解各种CSS的编写方法以及如何让它们为我们工作。好,让我们开始吧!

使用CSS实现简单样式

让我们从一个很简单的网页开始,只有简单的 index.hml和 index.css文件,index.html是这样的:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Modern CSS</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<header>This is the header.</header>
<main>
<h1>This is the main content.</h1>
<p>...</p>
</main>
<nav>
<h4>This is the navigation section.</h4>
<p>...</p>
</nav>
<aside>
<h4>This is an aside section.</h4>
<p>...</p>
</aside>
<footer>This is the footer.</footer>
</body>
</html>

目前我们的HTML中没有使用classes或ids,只用了HTML的tags。在完全没有CSS样式的情况下,这个网页看起来是这样的(在线演示版):

1

一点问题都没有,只是不好看,让我们加入CSS首先来改变字体,下面是index.css:

/* BASIC TYPOGRAPHY */
/* from https://github.com/oxalorg/sakura */
html {
font-size: 62.5%;
font-family: serif;
}
body {
font-size: 1.8rem;
line-height: 1.618;
max-width: 38em;
margin: auto;
color: #4a4a4a;
background-color: #f9f9f9;
padding: 13px;
}
@media (max-width: 684px) {
body {
font-size: 1.53rem;
}
}
@media (max-width: 382px) {
body {
font-size: 1.35rem;
}
}
h1, h2, h3, h4, h5, h6 {
line-height: 1.1;
font-family: Verdana, Geneva, sans-serif;
font-weight: 700;
overflow-wrap: break-word;
word-wrap: break-word;
-ms-word-break: break-all;
word-break: break-word;
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;
hyphens: auto;
}
h1 {
font-size: 2.35em;
}
h2 {
font-size: 2em;
}
h3 {
font-size: 1.75em;
}
h4 {
font-size: 1.5em;
}
h5 {
font-size: 1.25em;
}
h6 {
font-size: 1em;
}

上面的这段CSS主要是改变字体样式(字体的大小,行高,等等),还有文本颜色和居中显示。当然你得学习CSS才知道如何给这些CSS属性取适当的值(上面的样式来自sakura.css)。好在上面的CSS不至于复杂到读不懂。加入上面的CSS后,页面看起来变成这样(在线演示版):

2

看起来不一样吧 - 这就是CSS的作用,简单地把样式加入到一个文件里,不需要编程,也不需要复杂的逻辑。不幸的是,当我们想控制的不只是字体和颜色的样式时,事情开始会变得焦头烂额。

使用CSS实现页面布局

在90年代,在CSS被广泛采用前,没有什么可选择的办法来控制布局。HTML最初设计是用于纯文本的,没有动态网页,没有侧边栏,等等。在早期,页面的布局依靠表格来实现 - 整个网页就是一个大HTML表格,其中的内容编排在表格的不同行和列中(注:通过HTML表格的行、列可以让文本对齐)。这个方法可行,但网页的内容和样式是紧耦合的(在一个HTML文件里),如果想改变一个网站的网页布局格式,需要改写大部分HTML代码。

一旦CSS登场,网页的内容(写在HTML里)和样式(写在CSS里)就很有必要分开了。大家会想办法把所有和样式相关的代码移入CSS里(不再有HTML表格)。但非常需要注意的是,CSS也非真的设计用来控制页面布局的,所以早期这种解耦的尝试都没有找到什么好办法。

让我们用上面的例子看看CSS实际上如何解耦内容和布局。我们首先要重置边距(margin)和补白(paddings)- 它们会影响到布局设计时需要做的计算。同时给网页上不同的区块(section)设置不同的颜色 - 不需要好看,主要是测试不同的布局时,视觉上能分辨出不同的区块(这样就可以看出布局的效果)。

/* RESET LAYOUT AND ADD COLORS */
body {
margin: 0;
padding: 0;
max-width: inherit;
background: #fff;
color: #4a4a4a;
}
header, footer {
font-size: large;
text-align: center;
padding: 0.3em 0;
background-color: #4a4a4a;
color: #f9f9f9;
}
nav {
background: #eee;
}
main {
background: #f9f9f9;
}
aside {
background: #eee;
}

现在这个网页看起来像这样(在线演示版):

3

好,我们现在可以开始使用CSS控制网页内容的布局了。我们将按出现的时间顺序介绍三种不同的布局方法,从经典的float布局开始。

float布局

CSS float属性最早引入是让图片定位在文本栏的左边或者右边(就像你看到的新闻报纸)。Web开发者发现并利用了一个事实 - 可定位的其实不只是图片,可以是HTML元素 - 通过定位整个div元素里的内容,可以想象把网页纵横分割成不同的部分。因为这种纵横分割是通过想象的,随意的,所以很难保持准确一致的分割。

在2006年,A List Apart上发表了一篇文章In Search of the Holy Grail(寻找圣杯),该文章介绍了一种详尽的,所谓圣杯的布局方法(注:圣杯指的就是至高无上,完美) - 这就是经典的三栏式布局,布局包括三部分 - 头部(header),三栏主体部(3 columns),和注脚部(footer)。这么简单的布局居然被冠以“圣杯”,真是难以置信,可想而知在当时的技术条件下,想要通过CSS产生一致性的布局难度确实是很大的。

下面展示的就是把这篇文章所描述的float布局应用到前面的例子上:

/* FLOAT-BASED LAYOUT */
body {
padding-left: 200px;
padding-right: 190px;
min-width: 240px;
}
header, footer {
margin-left: -200px;
margin-right: -190px;
}
main, nav, aside {
position: relative;
float: left;
}
main {
padding: 0 20px;
width: 100%;
}
nav {
width: 180px;
padding: 0 10px;
right: 240px;
margin-left: -100%;
}
aside {
width: 130px;
padding: 0 10px;
margin-right: -100%;
}
footer {
clear: both;
}
* html nav {
left: 150px;
}

看上面的CSS代码,你会发现不少CSS“黑”技巧(margin是负值,clear:both,宽度width是硬算出来的,等等),A List Apart的那篇文章很好的解释了这些“黑”技巧的细节和原因。下面是效果(在线演示版):

4

看起来还不错,但你会注意到3栏的高度是不一致的,而且页面也没有和屏幕等高。这个问题来源至float - float只能定位到左边或右边,但无法得知被定位区域内容的高度。这个问题好多年都没有比较直接的解决办法,直到好多年后flexbox布局的出现。

flexbox布局

CSS flexbox属性的第一次出现是在2009年,但被广泛的采纳则到了2015年。flexbox被用来定义那些必须横跨不同行或列的区域,从这点上要比float更适合于页面布局。对于开发人员讲,在用来近10年的float布局后,在页面布局上终于可以不再需要借助于各种float的“黑”技巧。

下面就是我们上述例子的flexbox布局,采纳了Solved by Flexbox所描述的技巧(该网站专门展示各种flexbox布局的例子,很受欢迎)。注意到我们增加了一个div容器,把之前的三栏包含其内:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Modern CSS</title>
<link rel="stylesheet" href="index.css">
</head>
<body>
<header>This is the header.</header>
<div class="container">
<main>
<h1>This is the main content.</h1>
<p>...</p>
</main>
<nav>
<h4>This is the navigation section.</h4>
<p>...</p>
</nav>
<aside>
<h4>This is an aside section.</h4>
<p>...</p>
</aside>
</div>
<footer>This is the footer.</footer>
</body>
</html>

下面是flexbox布局的CSS代码:

/* FLEXBOX-BASED LAYOUT */
body {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex: 1;
}
main {
flex: 1;
padding: 0 20px;
}
nav {
flex: 0 0 180px;
padding: 0 10px;
order: -1;
}
aside {
flex: 0 0 130px;
padding: 0 10px;
}

这下比float布局紧凑多了。flexbox的属性和值初看有点让人困惑,但我们不用像float布局那样需要搞出一些“负”边距的事情 - 真是巨大的进步,下面是效果(在线演示版):

5

三栏都齐高而且充满了整个页面,看起来挺完美了,不过该布局方法有一些小缺陷。一个是浏览器支持,目前只有较新的浏览器支持flexbox,旧的则不行。当然,浏览器厂商正在更尽力地停止对旧浏览器的支持,让网页设计者们有比较一致的开发体验。另一个是我们得加入这段 <div class=”container”>,最好的办法应该是不用 - 理想情况下,任何的CSS布局不应该改变任何原有HTML文本。

最大的问题应该还是CSS代码本身 - flexbox避免了float的“黑”技巧,但是CSS代码变得没有那么直观 - 没有看上去像是用于定义布局的。flexbox代码不易阅读,也无法让开发者对于各个元素在页面上的布局状况产生视觉上的印象。这样导致在编写flexbox布局代码时,编写人员得不断地臆想和测试。

非常重要的一点是,flexbox是本身设计用来针对一个行或列内的页面元素所占位置的大小进行调节,而非整个页面的布局!虽然它可以为布局工作而且也比float好,但是我们有针对整个页面 - 多行多列布局而发展出来的CSS规范,这个规范就是CSS grid!

grid布局

CSS grid规范第一次提出是在2011年(其实也就在flexbox规范提出后不久),但是却花了超长时间获得不同浏览器的支持。直到2018年初,CSS grid才在大多数较新的浏览器上得到支持(其实要和过去一、两年比,这是个巨大的进步)。

下面是grid布局,采用了这篇文章(CSS tricks)中介绍的第一种方法。注意在同样的例子里,我们去掉了 <div class=”container”>(那是为了flexbox布局而加入的),HTML是原装不动的,下面是CSS:

/* GRID-BASED LAYOUT */
body {
display: grid;
min-height: 100vh;
grid-template-columns: 200px 1fr 150px;
grid-template-rows: min-content 1fr min-content;
}
header {
grid-row: 1;
grid-column: 1 / 4;
}
nav {
grid-row: 2;
grid-column: 1 / 2;
padding: 0 10px;
}
main {
grid-row: 2;
grid-column: 2 / 3;
padding: 0 20px;
}
aside {
grid-row: 2;
grid-column: 3 / 4;
padding: 0 10px;
}
footer {
grid-row: 3;
grid-column: 1 / 4;
}

从视觉效果看,和flexobox布局一样。但是,相关的CSS代码易读而且清楚的表明了所需要达到的页面布局效果。行、列的总体大小和形状定义在body这个选择器里,而各个grid中的东西则分别定义。

有一个比较令人困惑的是 grid-column 属性,它定义了开始/结束栏。令人困惑是因为这个例子里,总共3栏,但数字确是从1到4,看了下面这张图就比较容易理解了(在线演示版):

6

第一栏从1开始到2结束,第二栏是2到3,第三栏是3到4。而头部(header)是1到4,横跨整个页面,nav只是1到2,横跨第一栏,等等。

一旦你习惯于grid的语法,它很显然就是你表达页面布局的最佳方法。唯一的困难是浏览器支持,不过如上所述,近年来已有巨大进步。说CSS grid是第一个真正为页面布局设计的CSS工具一点都不为过。网页设计者对于创造性的网页布局设计往往不得不保守(想得到却不能做),因为之前种种CSS工具非常脆弱,而且还需要各种“黑”技巧以及打补丁的做法。现在因为CSS grid到来,以前从未可能实现过的、创造性的网页布局设计,很有可能会来上一大波,这实在让人兴奋。

7

使用CSS预处理器

到此我们讨论了用CSS来实现简单样式以及布局。现在我们进入工具讨论,那些帮助提高CSS开发体验的工具(视CSS为计算机的一种语言),从CSS预处理器(css preprocessor)开始。

CSS预处理器让你使用另一种语言,但会将之转化为CSS,这样浏览器才能理解。 这个非常重要,因为早期浏览器在支持新的特性方面脚步都非常缓慢。第一个重要的CSS预处理器是Sass,在2006年发布。它的优点是更简洁的语法(用缩进取代括号,取消分号,等),并加入了一些CSS没有的语法特性,例如变量,helper functions,calculations。下面是上面的例子中颜色的部分用Sass的变量来实现:

$dark-color: #4a4a4a
$light-color: #f9f9f9
$side-color: #eee
body
color: $dark-color
header, footer
background-color: $dark-color
color: $light-color
main
background: $light-color
nav, aside
background: $side-color

变量可以重用并且是用$符来定义的,括号和分号没有了,看起来更干净。除了干净的语法,Sass对CSS引入变量等特性在当时是具有突破性的,因为它开启了编写更简洁和更易维护的CSS代码的可能性。

要使用Sass,你必须先安装Ruby,该编程语言用来把Sass代码编译成正常的CSS代码。然后你还得安装Sass gem,然后运行命令行把你的.sass文件变成.css文件:

sass --watch index.sass index.css

上面的命令把index.sass里的Sass代码转成index.css里正常CSS代码,–watch的作用是当有任何代码改变时(文件会发生变化),自动重跑该命令,这在使用中非常方便。

上面这个处理过程被称为一个构建步骤,对于早在2006年的前端开发人员,想上手是一个不小的障碍。如果你熟悉像Ruby这样的编程语言,这个处理当然是很显然的。但是对于当时大多数前端开发人员,因为只习惯使用HTML和CSS,没有使用这种的工具的需要。而要想获得CSS预处理器的新特性,则必须学习相关工具生态链,所以这对于任何想上手的开发人员,必须有较大的推力才行。

在2009年,Less 预处理器发布了。它也是Ruby编写的,和Sass也很类似。主要区别在语法上,它更接近于CSS语法。任何CSS代码都是合法的Less代码,下面是Less代码(同样的例子):

@dark-color: #4a4a4a;
@light-color: #f9f9f9;
@side-color: #eee;
body {
color: @dark-color;
}
header, footer {
background-color: @dark-color;
color: @light-color;
}
main {
background: @light-color;
}
nav, aside {
background: @side-color;
}

和Sass的例子差不多(用@符而非$符定义变量),但没有Sass代码漂亮,因为保留了CSS的括号和分号。当然因为更接近CSS所以更容易让开发人员采纳它。在2012年,Less用Javascript重写(取代了原来的Ruby),这让Less的编译更快,同时更吸引开发人员,特别是那些已经采纳、使用Node.js的。

要把上面的代码转成正常的CSS代码,你首先要安装Node.js,然后安装Less,接下来跑命令:

lessc index.less index.css

类似的,上面的命令把index.less里的代码转成index.css里正常CSS代码。注意的是,不像sass命令,lessc没有-watch选项,意味着你必须安装和使用额外的工具来取得同样的效果。这对于那些习惯命令行的编程人员不是什么难事,但对于那些只想使用CSS预处理器的开发人员上手又增加了一道实实在在的门坎。

当Less获得大家的认可时,Sass的开发人员也做出了调整,在2010年增加了一种新的语法 - SCSS(和Less类似是CSS的超集)。他们还发布了新工具LibSass,用C/C++实现Sass Ruby编译引擎,这让它更快并且在其它编程语言里也能够使用。

另一个CSS预处理工具是Stylus,在2010年出现,用Node.js开发,和Sass、Less比较关注在更简洁的语法上。基本上CSS预处理的讨论不外乎这三个使用最广泛的工具。它们所提供的特性也很类似,最终你任选一个都不会错。

当然,有人会对CSS预处理的必要性提出质疑,因为浏览器正在而且最终会实现它们的特性(如变量,calculations)。更进一步,有一种不同的处理方法 - CSS后处理让CSS预处理变得不再需要(当然这个观点不无争议)。接下来我们就谈谈后处理。

使用CSS后处理器

CSS后处理器是使用Javascript分析并把“你的CSS”转换成真正的CSS代码。从这点看,和CSS预处理非常像,你可以想象成用不同的方法处理同样的问题。 它们的区别是,CSS预处理器用特别的语法来标记哪些代码需要转换,而CSS后处理器则是把正常的CSS代码转换成任意代码而无需引入特别的语法。这个最好就是通过例子来展示。 让我们看看上面例子中header部分原来的CSS代码:

h1, h2, h3, h4, h5, h6 {
-ms-hyphens: auto;
-moz-hyphens: auto;
-webkit-hyphens: auto;

hyphens: auto;
}

黑体的部分称为“浏览器开发商前缀”(vendor prefixes)。它的作用是让浏览器识别出这些是实验性的新增特性,开发人员可以采用之,虽然它们还没有彻底被浏览器实现。这里-ms前缀是给微软IE的,-moz是给Mozilla火狐浏览器的,-webkit是给采用webkit渲染引擎的(谷歌的Chome,Safari,新版的Opera浏览器都采纳之)。

为了使用这些CSS新增特性,要记住这些不同的vendor prefixes,这是挺烦人的。当需要的时候,如果能有一个工具自动把vendor prefixes加入就太好了。当然我们可以通过CSS预处理,例如像下面这样(SCSS):

@mixin hyphens(\$value) {
-ms-hyphens: \$value;
-moz-hyphens: \$value;
-webkit-hyphens: \$value;
hyphens: \$value;
}


h1, h2, h3, h4, h5, h6 {
@include hyphens(auto);
}

这里使用了Sass的 mixins 特性,它让你定义一段CSS,然后在其它地方重用。当这个文件编译成正常的CSS代码时,任何@include的语句将会被匹配的@mixin所定义的CSS代码取代。总的讲,这方法不算坏,但你需要为每一个需要vendor prefixes的CSS特性定义一个mixins。这些mixin代码则需要维护,因为当浏览器支持这些特性时,你就需要移除相应的vendor prefixes。

对比mixins,还有一更好的方法是只写基本的CSS,然后通过工具识别出那些需要加入vendor prefixes的CSS特性,并自动加入。CSS后处理器就是可以做这个的。举个例子,如果你使用PostCSS和其autoprefixer plugin,你就可以只写不带vendor prefixes的CSS,然后让PostCSS做剩下的工作:

h1, h2, h3, h4, h5, h6 {
hyphens: auto;
}

当你运行CSS后处理器时,hyphens: auto 将会被适当的vendor prefixes取代(由autoprefixer plugin决定,无需你操心)。这意味着你可以编写正常的CSS代码,无需为浏览器CSS兼容或者特殊的CSS语法担心。

除了autoprefixer外,PostCSS还有其它plugins让你做一些蛮酷的事情。cssnext让你使用还处于试验性的CSS特性;CSS modules能够自动改变classes以免class命名冲突;stylelint能够识别CSS代码错误并让CSS代码保持风格一致。这些工具都是在过去一两年内出现的,新的开发流程融入了这些新的工具,展示出很多事在过去是完全无法做到的。

当然这有个代价,安装和使用像PostCSS这样的后处理器,和CSS预处理器相比,要花更多的功夫。不只是通过命令行安装和使用它们,还有安装和配置相关的插件(plugins),定义复杂的规则(例如目标针对哪种浏览器)。不停留于简单地运行PostCSS,很多开发人员把后处理器集成到了前端构建体系里,如GruntGulp,和Webpack,这些构建集成工具帮忙前端开发人员管理各种构建工具以及构建流程。

如果你从未使用过任何一种前端构建工具,学习所有必要的构建流程是件很累人的事情。如果你刚开始,请查看我的文章 给恐龙们解释一下当今的Javascipt(译文),那篇文章从前端开发人员角度出发介绍了Javascript工具的现今状况。

值得指出的是关于CSS后处理器是有些争议的。有些人抱怨术语太令人费解 - 有些说它们应该都叫CSS预处理器,有些则主张简单点就叫CSS处理器,等等。有些人认为,CSS后处理器可以完全取代预处理器,有些则认为两者应该共处。不过有一点是清楚的,如果你有兴趣研究到底能把CSS发挥到什么程度,你应该学习一把如何使用CSS后处理器。

8

编写可维护CSS的方法

各种CSS预处理和后处理工具为改进CSS开发体验经过了漫长的道路。但这些工具并”不“足已解决维护庞大CSS代码的问题。为了这个问题,大家开始记录各种指导CSS编写的规范和守则,通常称之为CSS编写的指导方法。

在讨论任何一个特定的CSS编写指导方法之前,很重要的是要搞明白为什么随着时间的推移,CSS代码变得难以维护。一个关键的CSS性质是CSS是全局性的 - 任何一个你所定义的样式将全局性地应用在页面上的任何一个部分。所以你需要做的工作是,你得遵循一套详细的命名规范来维护各个样式类(class)的独立性,或者依赖于特定的判定规则来决定对给定页面元素采用哪个样式。CSS编写指导方法论就是提供这么一套有组织的方式来编写CSS,让你避免编写庞大CSS代码时所遇到的痛点。让我们按照大致的时间顺序介绍一些非常出名的CSS编写指导方法。

OOCSS

OOCSS(Object Oriented CSS)面向对象的CSS 第一次出现在2009年,这个方法基于两个原则。第一个是结构(structure)和皮肤(skin)样式必须分离。此原则意味着定义结构(如布局)的CSS代码不应该和定义皮肤的(如颜色,字体,等)混在一起。 这样更容易进行“换肤”。第二个原则是容器和内容必须分离。此原则意味着要把页面元素当作可重用的对象 - 对象意味着它无论在页面的任何位置上看起来都是一样的。

OOCSS提供了深思熟虑的原则,但在实行上并没有太具体的规定,后来的SMACSS继承了它的核心概念,但加入了很多细节让其在实践中更容易上手。

SMACSS

SMACSS(Scalable and Modular Architecture for CSS)模块化并可扩展的CSS 第一次出现在2011年,这个方法让你基于五个分类规则编写CSS - 基本规则(base rules)布局规则(layout rules)模块规则(modules)状态规则( state rules), 以及主题规则(theme rules)。SMACSS也推荐一定的命名规范,如对于布局规则,布局相关样式类,名字一律加前缀 l- 或者 layout- ;对于状态规则,样式类名字则加入相关状态描述前缀,例如 is-hidden 或者 is-collapsed。

和OOCSS相比,SMACSS虽然有着更具体详细的规定,但是要求使用者想清楚采纳哪种具体的CSS规则,放入哪种分类当中。后来的方法如BEM让CSS编写者无需为其中的一些事情考虑,这使得它们的上手更容易些。

BEM

BEM(Block,Element,Modifier)第一次出现是在2010年,基本思想是把用户界面分成独立的几大块。块(block)指的是一种可重用东西,例如搜索表单 - 被定义为 <form class=”search-form”> </form>。元素(element)指的是块里的一部分,本身不能单独拿出来重用,例如搜索表单里的按钮 - 被定义为 <button class=”search-form__button”>Search</button>。修改者(modifier)指的是那些可以改变块或者元素的东西,这些改变包括块或元素的样式,状态,以及相关允许的动作,例如一个搜索表单禁用按钮 - 被定义为 <button class=”search-form__button search-form__button–disabled”>Search</button>。

BEM比较容易理解,有着一套命名规范让新手使用而无需做太多复杂的考虑。但不好的另一面是,有些样式类名超长,和传统所提倡的CSS命名有冲突 - 传统上提倡CSS的样式类名对人来讲最好有意义。下面看看Atomic CSS如何把这种非传统做法带到另一个层次。

Atomic CSS

Atomic CSS(也被称为Functional CSS)第一次出现是在2014年,其方法围绕这一个思想:每个类(class)都是小型,单一目的的,而且类名就是基于视觉函数。这个方法和前面的OOCSS,SMACSS,BEM完全的不同,不是把页面元素当作可重用的对象,Atomic CSS完全忘掉了这些对象而通过可重用的、单一目的的工具函数类来对页面元素做样式处理,像前面的 <form class=”search-form”> </form> 变成了<button class=”f6 br3 ph3 pv2 white bg-purple hover-bg-light-purple”>Search</button>。

如果上面的例子让你惊恐地萎缩了一下,那么是正常的,很多人都认为这个是与已有的CSS最佳实践相违背的方法。然而,网上对此有着大量精彩的讨论 - 质疑所谓的CSS最佳实践是否在不同的情形下都成立。这篇文章对此做了很好的功课并强调指出传统的关注点分离导致了CSS最终依赖于HTML(即使采用了象BEM这样的方法)。而象Atomic这样采用函数型的方法则会让HTML依赖于CSS。两者都没有错,如果你仔细审视之,你会明白让HTML和CSS两者关注点分离到目前还没有完全实现!

其它方法如下面的CSS in JS实际上就是包含了这个概念 - HTML和CSS就总是相互依赖的,当然,这也是至今最具争议的指导方法 …

CSS in JS

CSS in JS 第一次出现是在2014年,它不是把CSS分开放在样式表里,而是直接放在各个组件里。它是由React Javascript框架引入的(该框架另一个同样有争议的做法是把HTML定义的组件放在Javascript文件里而不是HTML文件中)。最初React是把样式直接内嵌,后来才采用通过Javascript产生相关的CSS(根据组件产生独立的CSS类名)然后将之插入到文件里并带上样式标签。

CSS in JS的做法和关注点分离的CSS最佳实践完全违背。这里的原因是,我们使用web的方法随着时间的推移已经完全不同了。早期的web主要是大量的静态网站 - 把HTML的内容从CSS样式中分离出来是有道理的。现阶段则变成了动态的web应用 - 开发人员应该把东西分成不同的、可重用的组件。

CSS in JS的目的是想把组件定义成有严格的界限,它自身的HTML/CSS/JS都是内含的 - 一个组件的CSS代码完全没有可能去影响另一个组件。作为一个被广泛采纳的Javascript框架,React就是要表达并追求这个目的,它影响着并让其它的框架如Angular,Ember,Vue也跟随这种做法。必须指出CSS in JS的做法还比较新,现阶段广泛地对web采用了组件开发方式,开发人员们正努力为此建立新的CSS最佳实践,并为此做各种尝试和试验。

现阶段各种不同的CSS方法很容易让人招架不住,但重要的是,我们必须认识到没有唯一正确的方法 - 当你的CSS代码足够的复杂时,它们只是你可能采用的不同的CSS工具或选项。你必须根据自己的工作情况深思熟虑,作出有利的技术选项。从长远讲,在CSS这个领域内,现阶段的各种方法,各种尝试都会让每一个开发人员受益。

结语

上面就是当今CSS的综述。我们介绍了如何用CSS来控制简单的样式如字体样式,如何采用CSS的float,flexbox,以及grid来布局,如何用CSS预处理器来处理变量和mixins,用CSS后处理器支持转换功能如增加vendor prefixes,以及介绍不同方法来编写可维护的CSS以克服CSS全局性的问题。 我们还没有深入其它众多的CSS功能/特性,如选择器selector,过渡transition,动画animations,形状shapes,动态变量dynamic variable,这些功能/特性可以一直列下去。关于CSS有太多的东西可讲,任何人如果想说CSS是容易的,恐怕他还不了解其中的一半。

当今的CSS技术还在快速地发展着,要想在工作中运用好该技术肯定是件让人很受挫的事。重要的是记住web在不同的历史阶段如何演变以及当时的技术状况,从中就知道有不少聪明的技术人员创建了实实在在的CSS工具和编写方法让CSS的最佳实践随着web技术的发展而发展。在现阶段做个开发者是个无比兴奋的事,我希望这篇文章能在你成神的路上给予你指导性的帮助!

Gitment评论
0%