变量即将进入 CSS。它们已经有了实现,所以现在无法阻止了。Firefox 已在 29 版中实现了它们,而 Chrome 在 29+ 版中也已取消前缀,前提是您已启用“启用实验性 Web 平台功能”标志。
需要明确的是,无论这是否是一件好事,任何争论都无法改变现状。但我仍然认为这很有趣,所以让我们来谈谈它。
抽象的背景故事
我最近一直在做关于计算中抽象的演讲。回顾编程的历史,有几个明显的节点,我们把抽象提升到了一个新的水平。从机器代码的“1 和 0”,到汇编语言,到编译器,以及那些为我们提供像 C++ 这样的语言的抽象。
浏览器由多个部分组成,例如渲染引擎和 JavaScript 引擎。这些部分是用 C++ 编写的。因此,当我们编写 HTML、CSS 和 JavaScript 等内容时,我们又向上爬了一层抽象的阶梯。HTML、CSS 和 JavaScript 并没有取代它们下面的语言,它们位于它们之上。它们依赖于下面的层来完成它们最擅长的工作。HTML、CSS 和 JavaScript 是我们发明的语言,以便在 Web 上构建我们想要构建的东西:交互式文档。
随着时间的推移,我们希望/期望/需要 Web 平台做更多的事情。浏览器功能只会不断 *添加*,而不会 *删除*。我们吞噬这些新功能并将其发挥到极致。这使得 Web 开发变得更加复杂。我们不喜欢复杂性。它使工作变得更加困难和效率低下。
这种情况已经持续了足够长的时间,以至于我们正在迈向抽象阶梯的下一层。抽象是应对复杂性的自然武器,因此我们使用抽象来降低我们编写的代码的复杂性。
我们在 Web 上最需要的抽象是 HTML。在一个每个页面都存储为完整 HTML 文档的网站上工作将是荒谬的,从 <!DOCTYPE html> 到 </html>,你直接编辑它们。现在没有人这样做了。完整的 HTML 文档通过模板和内容块拼接在一起。
JavaScript 中的抽象是固有的。抽象的工具已经存在。变量、循环、函数等。
最后一种获得抽象处理的 Web 语言是 CSS,并且是以预处理器的形式出现的。CSS 具有极大的重复性,并且几乎不提供任何抽象工具。预处理器提供了我们迫切需要的这些东西,并拯救了局面。
流行度
这里另一个起作用的是 Web 平台的流行度。它是计算机历史上最成功的平台。与任何其他平台相比,更多的人为它构建并使用从它构建的东西。换句话说,HTML、CSS 和 JavaScript 非常成功。这在很大程度上归功于 Web 标准倡导者的努力,但那是另一个故事。
为什么像 CSS 这样的语言如此成功?因为它非常简单。选择器和键/值对。就是这样。是的,有很多小问题和细微差别。是的,真正掌握它需要很长时间。但核心语言非常简单。在十秒钟内,您可以向某人展示一段代码并解释它是如何工作的,从而使他们完全理解。
h1 {
color: red;
}
我相信 CSS之所以如此成功,是因为它的语法易于理解、学习和教授。CSS 有很多值得抱怨的地方,但我认为早期做出了正确的语言选择。
使核心语言复杂化
就像所有语言一样,CSS 随着时间的推移而发展。与 Web 平台中的所有内容一样,它添加了新的功能。Jeremey Keith 指出,@keyframes 代表了 CSS 的重大转变。首次,您可以编写没有意义的 CSS,如果代码中其他地方没有另一块 CSS,则根本无法工作。
/* This means nothing... */
.animate {
animation: my-animation 0.2s;
}
/* ...if not for this, which could be anywhere or nowhere */
@keyframes my-animation {
to { color: red; }
}
正如 Jeremy 所说
因此,CSS 变量(或自定义属性)并不是 CSS 背后设计原则的墙上的第一个裂缝。为了混淆我的隐喻,这条滑坡始于 @keyframes(也许还有 @font-face)。
给定的 CSS 代码块不再保证有意义。
CSS(核心语言)正在走向完全编程化的道路。如果变量有用,那么循环也一样,对吧?我们可以开始想象一个 CSS 版本,它拥有如此强大的编程功能,以至于它不再像它最初的简单、易懂的语言。这种最初使其成功的简单性。
抽象层
我绝对不是反变量或反任何编程概念。我热爱这些东西。它们赋予我作为作者的能力,使我的工作更轻松,并让我能够做更多的事情。所有(好的)抽象层都是这样做的。那么,为什么不将这些概念保留在抽象层中,而不是改变语言的核心原则呢?
再次引用 Jeremy 的话
感谢 Sass 等预处理器,我们可以鱼与熊掌兼得。
并非所有抽象都很好
本着来回博客的精神,请允许我再次回复 Jeremy。
……并非所有抽象都是好的抽象。
他继续比较 Sass 和 Haml,宣称 Sass 很好而 Haml 不好。我大体上同意这一点。我使用过一点 Haml,但从未从中获得过太多价值,而我每天从 Sass 中获得大量的价值。我在这里有两点要说明。
Chris 为抽象本质上是一件好事进行了辩护。
这里的语境需要是“随着时间的推移”。当历史上出现这些我们向上攀登抽象阶梯的节点时,总会有语言争夺在历史上占据一席之地。开发人员争论不休(就像我们现在在 CSS 预处理器市场上看到的那样),随着岁月的流逝,“赢家”出现,拥有绝大多数的“市场份额”,如果这个术语在这里适用的话。
赢家是好事,因为它们已经证明了自己。失败者(可能是)不太好的抽象。
我的第二点是,我相信存在主要抽象和次要抽象。也许这些不是很好的术语,但我的意思是,存在一种抽象提供了作者最需要和最有价值的东西(主要抽象),然后存在提供一些小细节的抽象(次要抽象)。
如上所述,HTML 的主要抽象是存储在数据存储中的模板和内容。Haml 是一种次要抽象,为特定类型的开发人员提供了更舒适的语法。CoffeeScript 也是 JavaScript 本身抽象工具的次要抽象。
Sass(或者随着时间的推移最终会成为赢家的任何东西)是 CSS 的主要抽象。
谁说浏览器必须用 C++ 编写?
好吧,没有人,但浏览器至少需要用半低级/低级语言编写,以便能够很好地管理内存,从而创建与现有产品相当的性能。
浏览器目前具有高级功能,例如 JS 的运行时编译器、内存管理器和垃圾回收算法,尽管它们可以用其他东西实现,但很难很好地控制系统并仍然生成快速的浏览器。因此,需要 C++、C 或类似的与系统集成的语言。
C/C++ 是编写浏览器的最合适的语言。为什么要用其他语言编写它。它需要跨平台运行。任何需要在许多不同操作系统上运行并需要移植才能实现的应用程序都将用 c/c++ 编写。
浏览器功能只会不断添加,而不会删除。
还记得
<blink>吗?http://boingboing.net/2013/08/07/firefox-nukes-the-blink-tag.html Chrome 也禁用了<frameset>,这真是可惜,因为我正好有一个完美的用例需要用到它。我完全赞成抽象化。直到抽象化妨碍我完成需要完成的事情。那时,你手上就有了“抽象干扰”。
当我读到这句话时,这也是我首先想到的事情。
而且我想不出有什么事情是只能用 frameset 做到,而不用它做不到的(至少在现代浏览器中)。
不过你的观点仍然有效。许多 HTML 标签、属性和 JavaScript 函数已被移除或进行了重大更改。来自浏览器和规范。
我理解你的观点,但是关键帧和变量都存在,但可选,css 仍然很容易学习。
css 变量不像 Sass 中的变量,在我看来非常有用。
我在 Firefox nightly 中测试了变量,它们在 RWD 中似乎非常有用。
我在 :root 中定义了字体和底部边距(用于垂直节奏)和 gutter 宽度,然后在 :root 中再次定义,但在更大的屏幕的媒体查询中。
这很棒,我们不需要在 MQ 中覆盖很多属性,并将这些设置保留在顶部。
样式表更轻量级且 DRY。
有些人不懂块级格式上下文或 display table、table-layout……但他们可以编写和学习 HTML。
我不知道如何在 JavaScript 中使用 promise 或使用节点服务器。但我可以用我所知的 JavaScript 的一小部分来进行一些 DOM 操作。
在我看来,css 也将如此。
拭目以待。
& 欢迎变量;)
什么?!在我学习的所有语言和语法中:CSS、Javascript、C#、HTML、VB.NET、SQL 等等等等——CSS 一直是最难完全理解的,坦率地说也是使用起来最混乱的。它之所以流行,是因为我们没有更好的替代方案。
从你作为一名会编码的人的角度来看,这是有道理的。CSS 违反了许多编程规则。我认为 Chris 的观点是,变量使得 CSS 对设计师或业余爱好者来说不那么容易上手,这可能是真的。但是,你也可以对编程语言本身说同样的话。编程基础,嗯,非常基础。
CSS 从未被设计成一种程序语言。它仅仅是一页补充标记的样式。
CSS 最终正在成长。
也许你指的是高级选择器或浮动页面布局?我认为这些与语言本身关系不大。
我很难相信,如果你已经完全学习了 javascript,你会发现 CSS 作为一种语言/语法更难理解。
清除浮动之类的概念?也许吧。
他指的是语法。我认为你提到的任何语言都没有比 CSS 更简单的语法。
如果没有 CSS 变量,预处理器将变得越来越复杂,CSS 的易用性将会受到影响。看看 javascript。在 jQuery 等库抽象了使 javascript 能够一致可靠地工作所需的所有管道之前,javascript 从未真正成为一种超级流行的语言。在此之前,它纯粹是复制粘贴和早期采用者的领域。
是的,CSS之所以流行是因为它非常简单,但CSS也阻止了许多基于系统的逻辑思维者在其中进行任何工作。许多后端开发人员讨厌 CSS,因为它与计算的本质背道而驰。存在太多的实现难题和浏览器渲染不一致问题。存在太多的 hack(浮动模型,任何人)和反模式。他们不是因为讨厌设计而讨厌它,他们讨厌 CSS 是因为这是一个不能一直工作的工具。
预处理器是一群接受逻辑训练的人讨厌 CSS 的重复和冗余的结果。他们聚在一起开发了 SASS 和 LESS 来修复 CSS。从本质上讲,它们是 CSS 的 jQuery。它们允许 CSS 在没有采用痛苦的情况下向前发展。开发人员已经在 CSS 中采用了变量和循环。
你可能会看到更多 CSS 的工程化。大多数设计师可能会减少对 CSS 的涉猎,无论好坏……但最好的设计师仍然会寻求了解他们的工具。
我一直在使用 php 和 php 变量来玩 css 的抽象。这主要是因为我希望在迭代品牌创意时易于管理颜色。每当我们想尝试新事物时,都需要更改黑色、灰色、红色和蓝色,这很糟糕。因此,到目前为止,用于颜色的 php 变量对我来说效果很好。
我认为我们正在亲眼见证一门成熟语言的自然发展过程,因为它最终被视为重要或“真正的代码”。我们意识到它需要更多的东西才能使其变得更好并随着复杂性的增加而保持可维护性。
无论任何人在抽象方面有什么感受,无论负责的“CSS 人员”是否有能力,你都会有一些人挥舞着他们的 CSS 宝剑——为什么因为有些人不能而要限制那些可以利用这些工具和功能的人?
Chris,你的观点很好,阐述得很好。
我完全接受你关于好的抽象需要时间才能形成的澄清。Haml 和 Coffeescript 与 Sass 之间的比较非常到位。
我同意该说法,并认为这是朝着正确方向迈出的一步。
我经历过很多项目,其中 CSS 是事后才考虑的,或者被当作不是一门真正的语言(出于同样的原因
Armstrongest 提到的)。CSS 的职责被留给了设计师或那些不太了解如何正确使用 CSS 宝剑的开发人员——这对项目的可维护性、性能和成功产生了巨大影响。这完全是疯了!CSS 可以说是最终产品中最重要的部分(它影响客户看到的内容),你永远不会像对待 CSS 代码一样对待后端代码。
“伙计们,我厌倦了处理这个 [插入后端语言] 东西,让实习生来处理它……”
或者
“这只是一行代码,跳过测试,直接上线看看是否有效……”
或者
“这个页面将被 100 万 IE 用户看到,好吧,让从未打开过 IE 的 logo 设计师来处理它。”
CSS 需要被更多地视为程序语言(至少是它的感知方式),这些工具、预处理器等不仅仅是工具,它们是感知和最佳实践,可以使 CSS 代码变得更好……
对我来说,CSS 从未真正成为一种语言,而更像是一种数据格式。浏览器消耗 CSS 数据就像 JavaScript 消耗 JSON 对象一样。
因为它实际上只是数据,所以我认为它完全可以进行修订。
不过,就你的观点而言,数据始终具有一定的语法,而像关键帧这样的东西确实会弄乱它。
我不确定我为什么认为 SASS 可以拥有抽象,而 CSS 不行。
如果每个人都使用 SASS(和其他预处理器和抽象),那么 CSS 没有它们实际上对任何人都没有好处——没有人编写纯 CSS。此外,一般来说(有很多例外!),那些编写纯 CSS 的人将无法与所有拥有这些抽象来帮助他们的人处于同一水平。
两全其美的方法是让 CSS 拥有这些抽象,但使它们可选且向后兼容。不想要额外的复杂性?不要使用它。你能理解它们吗?利用它们!
请注意,这取决于规范是否允许新规则可选且兼容,也许这是不可能的或不理想的。但这似乎是我们至少应该努力争取的圣杯。
我赞同这一点。
我完全可以接受 SASS 在浏览器中直接替换 CSS。
只要我不必使用 scss 语法。:)
我当然支持 Sass,甚至可能支持 Sass 替换 CSS。但是,我确实认为维护 CSS 核心编译语言的简单性是有意义的。
将抽象层保留在核心语言之外的主要好处是,它使浏览器在处理过程中无需执行另一步骤。通过将抽象移入 CSS,浏览器现在承担了预处理器所承担的责任——在解析和渲染方面为客户端增加了更多工作。至少对于 Sass 等,这些额外步骤发生在构建时或构建之前。
此外,淘汰旧浏览器(IE)需要时间。完全支持最新的 CSS 规范可能需要数年时间。在此期间,我们将不得不使用 polyfill(读取:预处理器)来实现相同的结果。
我非常喜欢这篇文章。看到人们对 CSS 的态度两极分化,一些人热爱它,一些人厌恶它,这很有趣。在阅读了另一篇文章关于 CSS 变量的内容并观看视频后,它确实表明了我们在实现“完美网页”之前还有很长的路要走。
问题:如果我们如此热爱 Sass 和其他预处理器,为什么我们不抛弃 CSS,直接从 Sass 渲染而无需转换所有内容呢?我个人认为,CSS 将变得越来越像 Sass(或许会比 Sass 更好),人们会放弃 Sass,因为使用它将毫无意义。那么,我们能否跳过使它们变得相似所需的步骤,直接使用我们现有的工具呢?
这本电子书由Nicholas Zakas撰写,是一篇关于类似主题的有趣读物(它是关于 JavaScript 的,但我认为它可以应用于 CSS)……
本质上,他探讨了为什么仍然使用 jQuery 等库或在 CSS 上下文中使用 Sass 等预处理器是一个好主意。他继续解释了抽象原生 API 的优势,即使浏览器内置了与库具有类似功能的原生 API……
总之,我认为这是一篇必读文章……
目标网页
http://chimera.labs.oreilly.com/books/1234000001655
在线阅读
http://chimera.labs.oreilly.com/books/1234000001655/ch01.html
在我看来,CSS/Sass 非常容易扩展的原因在于,到目前为止,实现更复杂功能所需的一切都只是建立在一个基本框架之上。
你可以用简单的 CSS 创建一个外观很棒的网站。但如果我想让它易于管理,我会使用 Sass 并使用变量/混合器等。这不是必需的,但它使我的生活更轻松,工作效率更高。
在更抽象的语言中,根据给出的示例,这些语言似乎更面向对象,需要抽象才能发挥作用。仅代表个人观点。也许我误解了这篇文章的要点。
在 C++ 和 PHP 中,你需要立即理解变量和编程结构以及语法。然而,根据 CSS 的发展方向,我认为只要基本基础保持不变,人们就会继续掌握它,并能够随着他们越来越熟悉而扩展他们的知识。
但除此之外,使用预处理器的意义何在呢?除了获得抽象之外。
我认为这些是所谓的常量,而不是真正的变量。你只为一个标签分配一个任意值,然后在任何需要使用该值的地方使用该标签。浏览器在页面加载时解析一次 CSS,并在看到标签的任何地方替换该值。该值在“运行时”或页面显示期间不会改变。
SASS 既有常量也有变量。常量使用 $name:value 语法创建,并在整个 CSS 中以相同的方式使用。变量是你传递给混合器函数的内容——但它们仅对 SASS 编译器而言是变量,因为 CSS 输出将包含硬编码的实际计算值。
真正的变量允许值在“运行时”(即页面显示期间)根据某些环境或用户触发的参数而改变。这将允许 CSS 中几乎任何属性响应不断变化的环境,而无需脚本或媒体查询。它使 CSS 从相当静态的状态转变为一段可重入代码。我不知道这是否应该是它的最终形式。
我使用 SASS,我唯一真正的问题是,一旦你走上了这条路,你就被锁定在其中了,并且参与项目的每个人都必须使用它。如果有人直接修改 CSS,那么你可能也应该丢弃你的 SCSS 源文件。这就像有人修改已编译应用程序的二进制文件一样。
将其内置到 CSS 语法中将允许你丢弃预处理器。我们拥有它们的原因仅仅是因为 CSS 本身不支持我们想要做的事情。就我个人而言,我不反对 CSS 变得更像 SASS,只要简单的语法保留下来,对任何人都不会构成问题。
我从未以这种方式想过抽象。仔细想想,如果没有循环或变量,CSS 就像我所想象的低级机器顺序指令的样子。
但展示一个非常简单的例子并说任何人都可以理解它,这是具有误导性的。
h1 {
color: red;
}
这段代码很容易理解,因为 CSS 具有人类喜欢且易于理解的视觉效果。但它的效果与以下 JavaScript 代码一样复杂甚至更复杂
javascript:alert('hi!')
看看大多数网站有多丑陋和破碎,这证明了 CSS 很糟糕。它不应该只是易于使用,它应该易于用它创建可靠的漂亮界面。
这让我想起了 Jens Meiert 之前说过的话:CSS 还远未被作者理解。我们可以更有效地使用 CSS 并编写更好的代码,但没有人愿意这样做,因为每个人都在呼吁更多的东西,而 CSS 工作组一直在不断提供。
我认为除了消除对 Sass 或 LESS 等预处理器语言的需求之外,没有其他必要性。
当然,我自己也来自编程背景,引入这个功能将是一个巨大的节省时间的机会,但是它并没有真正添加任何特殊的东西,这些东西已经存在了。
目前使用 SASS,易用性非常好,变量、数学计算、混合器,节省了 SOooooo 多时间。它极大地减少了开发时间,并避免了你一遍又一遍地编写相同的内容。我目前很乐意使用第三方软件/语言来编译生成有效的 CSS 文件。我确实相信添加变量最终会进一步减慢网站渲染速度,因为现在浏览器必须执行 CSS 代码并适当地处理变量。
总的来说,作为一个程序员,CSS 和 Web 开发作为一个整体让我感到非常恼火,因为你必须用 9 种不同的方式编写相同的代码片段才能使其在每个浏览器中正常工作,但这是另一个话题了。