Less-js-学习指南-全-
Less.js 学习指南(全)
原文:
zh.annas-archive.org/md5/de52e13e0bfb1bcb13725f55d8f07f79
译者:飞龙
前言
想象一下这样的场景——现在是下午 5 点,一天快要结束了,你的客户想要不可能的事情……
你知道那种场景——你已经创建了一个很酷的网站,但客户对你网站上使用的按钮颜色不满意。他们说使用的颜色阴影不够,需要调整。一个合理的请求,对吧?除了……网站上到处都是按钮,其中大多数使用不同的颜色……哦,天哪……那肯定不可能提前完成……
或者,有没有可能呢?确实有——如果我们能改变几个值,它就会自动为你更改每个按钮呢?听起来很疯狂,对吧?
错了,这是绝对可能的。欢迎来到 CSS 预处理器和 Less 的世界!Less 的力量意味着我们可以设置一些可以应用于任何数量元素的值(例如按钮)。而无需手动更改所有按钮,我们只需更改值,然后点击一个按钮来重新编译我们的代码。哇!代码立即更新,按钮显示新的颜色。
在这本书中,我们将遇到 Less 库,学习如何使用它,并将其应用于多个现实世界的场景,例如更新按钮以构建 CMS 系统(如 WordPress)的完整主题。我们将探讨动画、颜色管理、抽象框架以及为响应式网站创建媒体查询等主题。
这将是一次伟大的旅程,充满了曲折和转折——问题是,你准备好了吗?如果是的话,让我们开始吧……
本书涵盖的内容
第一章, 介绍 Less,带我们了解了 HTML 和 CSS 所扮演的角色,并探讨了使用 CSS 作为技术的固有局限性。我们的旅程从审视 CSS 预处理器所扮演的角色以及如何使用 Less 作为解决一些这些限制性问题的方案开始。
第二章, 构建 Less 开发工具包,是我们第一次了解 Less,通过了解我们如何将其纳入我们的代码,探索其语法,并创建一些基本样式。我们将探讨将 Less 编译成有效 CSS 的不同方法,以及为什么最好预先编译代码而不是在浏览器中动态使用。
第三章,开始使用 Less,深入探讨了可用于与 Less 一起工作的各种工具和应用程序,这些工具和应用程序可能非常有用;本章将提供一些提示和技巧,说明如何构建一个有效的 Less 工作工具包,你可以将其集成到自己的开发工作流程中。
第四章, 使用变量、混入和函数,从我们在第二章中留下的地方继续,探讨了 Less 的一个关键概念——混入。我们将探讨这个极其强大的工具,它将帮助你在开发 Less 时节省大量时间;我们还将介绍如何创建变量和函数,以便在处理 Less 时创建 CSS 样式。
第五章, Less 中的继承、覆盖和嵌套,探讨了通过一些前瞻性的思考和精心设计,我们可以如何利用 Less 的强大功能来创建基于现有样式的新样式,而无需重复现有代码。我们还将看到 Less 如何允许我们将样式表拆分为更小、更易于管理的文件,其中我们可以将常见的样式分组在一起,使开发管理更加容易。
第六章, 将您的网站迁移到 Less,包含了众多开发者开始使用 Less 时提出的问题的答案:我如何将其整合到现有网站中?我们将探讨一些我们可以使用的技巧和窍门,以逐步将网站迁移到使用 Less,同时仍然保留现有的 CSS,直到它被转换为 Less 等价物。
第七章, 使用 Less 操作字体,探讨了如何通过一些简单的技巧,在 Less 的帮助下轻松维护我们网站中使用的任何字体样式;我们将看到,通过一点小心规划和计划,我们可以进行最小限度的更改,从而快速更新整个网站中的字体样式。
第八章, 使用 Less 的媒体查询,探讨了如何利用媒体查询的强大功能,通过 Less 快速有效地构建响应式网站。我们将简要了解媒体查询的工作原理,然后转向探讨在与客户沟通时如何设定期望并决定应支持哪些功能,在使用 Less 构建查询之前。
第九章, 在 CMS 中使用 Less,展示了 Less 在管理当今任何内容管理系统中的样式时可以发挥的巨大作用。在本章中,我们将以 WordPress 为例,看看 Less 如何首先直接在代码中或通过使用插件被整合。然后我们将转向转换过程,探讨如何将 WordPress 网站转换为使用 Less,以及如何使用 Grunt 插件来消除手动编译样式的需求。
第十章, 使用 Less 与 Bootstrap 一起使用,继续我们的框架之旅,探讨了流行的 Bootstrap 系统以及它是如何使用 Less 来创建样式的。我们将查看其文件结构以及它使用的一些混合函数,然后在配置用于在演示网页上使用作为使用 Less 与 Bootstrap 一起开发工作流程的一部分之前,对其进行查看。
第十一章, 使用 Less 抽象 CSS 框架,展示了使用框架的一个陷阱,即提供的代码可能是不具语义的且效率低下。在本章中,我们将了解为什么框架并不总是解决所有问题的答案,以及如果我们想要改变,它们可能会使过渡到不同的解决方案变得困难。我们将探讨如何使用 Less 来帮助简化复杂的样式,保持 HTML 的整洁,并最终使框架为我们工作,而不是相反。
第十二章, 使用 Less 进行颜色处理,涵盖了任何网站最重要的一个方面——颜色!CSS 样式可能会使维护颜色变得困难。在本章中,我们将探讨如何使用 Less 将图像处理的力量带到我们的 CSS 开发中。我们还将了解如何通过一点小心,我们可以开始减少对如 Photoshop 之类的图形包的依赖,作为我们开发工作流程的一部分。
第十三章, 使用 Less 进行动画,带我们踏上旅程,展示 Less 如何被用来帮助简化在网页上动画元素和对象时所经历的痛苦。在本章中,我们将了解动画是如何工作的,简要介绍不同类型的动画,并查看 Less 如何简化标记,然后查看如何使用我们的技能制作一个简单的动画菜单,该菜单可以用于任何网站。
第十四章, 扩展和贡献 Less,是我们穿越 Less 世界的旅程的最后一章,我们将探讨如何为项目做出贡献并进一步发展库。我们将了解如何报告错误,在哪里可以找到库的文档,以及如何为库贡献代码修复或改进。
附录, Less 中的颜色函数,列出了每个函数的详细信息,包括四个定义颜色格式、引导颜色、执行颜色操作和混合颜色的组。
您需要这本书的内容
要完成本书中的大多数示例,你只需要一个简单的文本或代码编辑器、Less 库的副本和一个浏览器。我建议你安装 Sublime Text——无论是版本 2 还是 3——因为我们将会讲解如何配置它以用于 Less,包括语法和编译目的。
一些示例使用了额外的软件,例如 WordPress 或 Crunch!——相关细节包含在适当的章节中,并附有从源下载应用程序的链接。
本书面向对象
本书面向需要快速学习如何使用 Less 以更高效地编写 CSS 样式的前端开发者。为了最大限度地利用本书,你应该对 HTML、CSS 和 JavaScript 有良好的实际知识,并且最好对使用 jQuery 感到舒适。
惯例
在本书中,你会发现多种文本样式,用于区分不同类型的信息。以下是一些这些样式的示例及其含义的解释。
文本中的代码词汇、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 处理方式如下所示:“在我们的示例中,我们添加了对 Less 对象的引用,然后使用 modifyVars
方法将 object.less
中指定的 @button-color
变量的颜色更改为 #61783F
。”
代码块设置如下:
header {
margin-bottom: 25px;
nav {
height: 25px;
a { color: white }
}
}
当我们希望将你的注意力引向代码块中的特定部分时,相关的行或项目将以粗体显示:
.shape1 {
color: #5cb100;
border: 1px solid #5cb100;
}
.shape2 {
background: #fff;
color: #5cb100;
}
.shape3 {
border: 1px solid #5cb100;
}
任何命令行输入或输出将如下所示:
npm install -g grunt-cli
新术语和重要词汇将以粗体显示。你在屏幕上看到的单词,例如在菜单或对话框中,将以如下方式显示:“点击继续以开始安装。”
注意
警告或重要注意事项将以如下方式显示在框中。
提示
技巧和窍门如下所示。
读者反馈
读者反馈总是受欢迎的。让我们知道你对这本书的看法——你喜欢什么或可能不喜欢什么。读者反馈对我们开发你真正能从中获得最大价值的标题非常重要。
如要向我们发送一般反馈,请简单地将电子邮件发送到 <feedback@packtpub.com>
,并在邮件主题中提及书名。
如果你在一个领域有专业知识,并且你对撰写或为本书做出贡献感兴趣,请参阅我们的作者指南 www.packtpub.com/authors。
客户支持
现在你已经是 Packt 书籍的骄傲所有者,我们有许多事情可以帮助你从你的购买中获得最大价值。
下载示例代码
你可以从你购买的所有 Packt 书籍的账户中下载示例代码文件。www.packtpub.com
。如果你在其他地方购买了这本书,你可以访问 www.packtpub.com/support
并注册,以便将文件直接通过电子邮件发送给你。
错误清单
尽管我们已经尽一切努力确保内容的准确性,但错误仍然可能发生。如果你在我们的书中发现错误——可能是文本或代码中的错误——如果你能向我们报告这一点,我们将不胜感激。通过这样做,你可以帮助其他读者避免挫败感,并帮助我们改进本书的后续版本。
如果你发现任何错误,请通过访问 www.packtpub.com/support
,选择你的书籍,点击错误提交表单链接,并输入你的错误详情。一旦你的错误得到验证,你的提交将被接受,错误将被上传到我们的网站,或添加到该标题的错误清单中。任何现有的错误都可以通过从 www.packtpub.com/support
选择你的标题来查看。
盗版
互联网上版权材料的盗版是一个跨所有媒体的持续问题。在 Packt,我们非常重视我们版权和许可证的保护。如果你在网上遇到我们作品的任何非法副本,无论形式如何,请立即提供位置地址或网站名称,以便我们可以寻求补救措施。
请通过 <copyright@packtpub.com>
与我们联系,并提供疑似盗版材料的链接。
我们感谢你在保护我们的作者和提供有价值内容的能力方面的帮助。
问题
如果你在本书的任何方面遇到问题,可以通过 <questions@packtpub.com>
联系我们,我们将尽力解决。
第一章。介绍 Less
你厌倦了为客户网站编写相同的旧 CSS 样式,却发现你只是在重复自己?希望你能减少你写的代码量,同时仍然产生相同的结果…?
嗯,你可以。欢迎来到 CSS 预处理器的世界,特别是 Less!Less 这样的 CSS 预处理器旨在帮助你重新组织你的样式,使其成为更小、更易于管理的可重用代码块,你可以根据项目需求存储和引用这些代码块。
Less,作为 CSS 的超集或扩展,旨在使你的开发工作更加容易——它结合了在脚本语言(如 JavaScript)中更常见到的变量和函数,同时仍然编译成有效的 CSS。虽然一开始想到与代码一起工作可能会让你感到害怕,但你很快会发现 Less 实际上只是 CSS,但增加了一些有助于使开发更容易的功能。Less 将帮助你减少开发时间,因为你可以从一项项目中重用代码到另一项——具体多少取决于你!
在本章中,我们将涵盖以下主题:
-
HTML 和 CSS 的作用,以及使用 CSS 的局限性
-
为什么需要 CSS 预处理器
-
为什么你应该使用 Less
-
CSS4 的出现,以及这对 Less 的意义
HTML 和 CSS 的作用
如果你为客户开发网站,你很可能已经使用 HTML 和 CSS 来创建你的杰作。
HTML 是在 1990 年创建的,一直是放置网页内容的事实上的标准。多年来,它已经发展成我们现在所知道的 HTML5,我们可以用它来制作一些非常详细的网站或在线应用程序。用烹饪的比喻来说,HTML 有效地是蛋糕底座的制作;它是任何互联网浏览器都能理解的内容。HTML 构成了互联网上任何网站的基石——它看起来可能不太吸引人,但它将包含你需要的所有元素,例如标题、段落和图像,以产生格式良好的页面。格式良好的页面由两个元素组成:可访问性和验证。
可访问性相当于建造一座新房子,我们可以添加斜坡或使门道比正常更宽,以便让每个人都能进入。基本可访问性并不困难或复杂,但它必须成为开发过程的一部分;如果让它自行发展,它将使那些需要额外帮助的人在家中移动变得更加困难!与可访问性相伴而来的是验证,这非常类似于烹饪的物理学;如果我们遵守验证规则,我们就能创作出杰作,而如果超出最佳实践,很可能会导致灾难。
尽管如此,没有某种形式的装饰很难制作出一个网站;仅使用 HTML 无法产生非常吸引人的效果!正因为如此,我们才使用 CSS 来为我们的网站添加最后的修饰,我们可以调整位置、添加动画或改变页面元素的色彩。就像你不能没有水泥建造房子一样,你也不能在网站创建过程中某个时刻不使用 CSS。
使用 CSS 并非没有限制——随着它多年的发展,其功能支持已经发生了变化。有人可能会说,自从 1996 年诞生以来,它已经走了很长的路,但它的核心始终会存在一些基本缺陷。让我们更详细地看看这些。
使用 CSS 的限制
如果你曾经花时间使用过 CSS,你会知道在处理 CSS 时遭受的痛苦和心碎——这一切都是为了创建一个完美的网站!对于那些对使用 CSS 还不太熟悉的人来说,他们迟早会遭遇 CSS 的一些限制,包括:
-
CSS 高度依赖于浏览器的功能——不可能以相同的方式在所有浏览器中显示相同的内容。我们可以解决这个问题,但不是不付出代价的,这需要添加供应商前缀语句。这可能导致页面中有很多重复的代码,使页面变慢且难以维护,即使是微小的更改也需要大量的努力。
-
并非每个浏览器都支持 CSS 中的每个功能——这一点在 CSS3 中尤为明显。这意味着如果我们想保持某种形式的访客体验,我们需要为受影响的浏览器实现某种形式的优雅降级。
-
CSS 的出现使得在杂志网站上创建列等功能的操作变得容易得多,尽管它仍然不完美。要实现完美的列,我们需要使用 JavaScript 或 jQuery 来调整代码,这使得页面更难以访问(例如,对于那些使用屏幕阅读器的人来说)。它还对渐进增强的使用产生了影响,内容应该使用 CSS3 或 jQuery 等功能进行增强,而不是依赖于它们。
-
没有改变标记以包含占位符,就无法针对特定内容范围进行定位;如果这些占位符发生变化,那么相关的 CSS 也必须相应更改。
-
我们不能在另一个 CSS 样式中包含一个规则,也不能命名一个规则——后者可能会被客户端脚本使用,即使被引用的选择器发生了变化。
到现在为止,你可能认为使用 CSS 时一切都是厄运和阴霾;别担心,我们可以借助 CSS 预处理器来帮助我们更有效地开发。
使用 CSS 预处理器的好处
如果你花时间使用过 CSS,你可能会问自己第一个问题是“为什么我需要使用预处理器?”这是一个合理的问题,你肯定也不是第一个问这个问题的人!让我更详细地解释一下。
CSS 被称为声明性语言——这意味着我们用来声明元素如何显示的规则将是浏览器用来在屏幕上绘制结果的规则。例如,如果我们想让一段文本,比如一个打印的注释,显示为斜体,我们将使用类似于以下代码的东西:
.comment {
font-style: italic;
font-size: 12px;
}
浏览器然后将这段文本以 12 像素的斜体形式渲染到屏幕上。
这个例子非常直接——它可以在任何地方使用。问题是,我们可能需要在其他地方指定相同的样式属性。我们可以使用.comment
类,但如果我们想更改大小怎么办?或者,也许我们想将文本以粗体显示呢?
为了适应一个元素而更改样式规则可能会破坏原始元素的样式,这并不是理想的情况。相反,我们需要创建多个适用于特定元素的样式规则,但这些规则会重复这段代码——这可能会导致非常冗长的 CSS!想象一下,我们最终可能需要创建一个如下所示的选择器:
.article #comments ul > li > a.button {
...some style rules...
}
这个选择器并不容易理解,更不用说应用样式了,对吧?我们可以通过使用 Less 来消除这种重复问题——在 Less 样式表的开始处设置一个样式块,然后可以在代码的每个实例中重用这个样式,就像你可能在 Word 文档中使用autotext
函数根据关键词添加预定义文本一样。如果我们进行更改,我们只需要做一次——Less 会自动更新我们的代码,避免手动操作的需要。想象一下,如果你在一个电子商务网站上可能有数十个按钮,这样做的好处将很快显现出来!
在 CSS 中,这可能会显得很陌生——毕竟,我相信我们都习惯于手动编写代码,并花费许多小时来完善它。你可能会对使用 CSS 预处理器来处理一些繁琐的工作有所顾虑,尤其是当你为客户完成那件令人惊叹的 CSS 艺术品时,这会让人感到满足。这是很自然的——让我们花点时间来考虑一些关于使用 CSS 预处理器的一些常见顾虑。
为什么不直接写正常的 CSS 呢?
许多人经常会问,“如果我们正在生成 CSS,为什么我们不直接编写它呢?”这是一种常见的反应;毕竟,我们每天都在使用 CSS 来解决我们在构建美丽响应式网站时遇到的任何布局问题。我们最不希望的就是看起来不知道自己在做什么,对吧?
让我从一开始就明确:使用 Less 的目的不是编写更好的 CSS。如果您现在还不懂如何使用 CSS,那么 Less 不会帮助您填补这个空白。它将帮助您更快、更轻松地编写 CSS,同时使样式表更易于管理。让我们更详细地探讨一些我们应该切换到使用 CSS 预处理器(如 Less)的原因:
-
CSS 预处理器,如 Less,不会破坏浏览器兼容性——每个 CSS 预处理器都产生有效的 CSS。
-
CSS 预处理器有助于使我们的 CSS DRY(不要重复自己)——我们可以从可重用的 CSS 属性中创建变量,这有助于我们使代码更具可扩展性和可管理性,因为我们可以将它分解成更小的文件,这些文件会自动编译成一个更大的样式表。
-
如我们在整本书中将要看到的,CSS 预处理器包含一些有用的功能,可以帮助我们在编写 CSS 样式时自动化一些低价值任务,从而减少一些常见的繁琐工作。
-
我们可以利用 CSS 预处理器的嵌套功能,这导致了一种更自然的编写风格,我们可以使用一种简写形式来产生所需的效果。
现在我们已经探索了一些使用 CSS 预处理器的优势,让我们深入探讨并首次了解 Less。我们将进行一次快速浏览,以便让您对 Less 的预期有所了解。如果您现在还不理解,请不要担心;我们将在整本书中详细讲解所有内容。
介绍 Less 作为解决方案
Less 首次由 Alexis Sellier 在 2009 年创建,最初是用 Ruby 编写的动态样式表语言;很快,由于在 JavaScript 中重新构建库所获得的显著速度提升,它被弃用了。它旨在由客户端和服务器端使用——后者通过 Node.js 的帮助,我们将在第三章 Chapter 3 中介绍,Less 入门。
Less 是作为 CSS 的超集构建的,这意味着它包含比传统 CSS 更高级的工具。这允许我们在编写更少的代码的同时,仍然将其编译成有效的 CSS。这个关键在于我们如何使用 Less 来产生更有组织、更易读的代码。为了在实践中学到这一点,让我们看看一个快速示例,说明我们的意思。
想象一下,您已经编写了以下 CSS 代码示例——它是一个完全有效的 CSS,尽管实际上它不会产生任何可用的结果:
header {
margin-bottom: 25px;
}
header nav {
height: 25px;
}
header nav a {
color: #151b54;
}
您可能已经注意到,我们不得不重复一些内容,这并不理想,但在编写此类样式时是必要的恶行。在我们的例子中,代码是可读的,但如果我们将它发展到任何程度,选择器的重复性(如 header nav div.first div.thumb .img-wrapper img
)可能会使代码更难理解。
Less 的一个核心概念是在编写代码时使用 DRY 原则——我们可以利用其嵌套元语言语法通过嵌套我们的语句来减少代码。如果我们用 Less 重新组织前面的代码块,它将看起来如下:
header {
margin-bottom: 25px;
nav {
height: 25px;
a { color: #151b54; }
}
}
在这里,我们将编译成我们刚刚看到的 CSS。
注意我们如何通过分组样式和采用更自然的流程,减少了必须编写的代码量,同时使代码更容易阅读。嵌套元语言是基于层次结构的,我们可以将相关的声明分组在一起,并以某种形式对它们进行重新排序,这种形式抽象了每一级,同时包括了高级别。Less 会自然地将这些相关的声明分组在一起,如果 CSS 样式表由多个人编辑,这将是一个巨大的好处。
注意
如果您想了解更多关于嵌套元语言的信息,您可能想浏览到en.wikipedia.org/wiki/Metalanguage#Nested_metalanguage
。请注意,这是一个相当枯燥的参考资料(有意为之!)
为了证明这确实编译成有效的 CSS,您可以看到编译前面 Less 代码在 Crunch!中的结果。Crunch!是一个 Less 的 CSS 编辑器和编译器,我们将在第二章中更详细地介绍它,构建 Less 开发工具包。Chapter 2。您可以在 Crunch!中像以下截图所示进行编码:
如果嵌套代码现在看起来并不那么伟大,请不要担心——我们将在第四章中更详细地介绍嵌套,使用变量、混合和函数。Chapter 4。这是 Less 中许多将帮助革命化您的 CSS 开发的函数之一。让我们进一步深入探讨您应该使用 Less 的一些原因,更详细地了解。
为什么你应该使用 Less
我们已经看到,Less 旨在帮助使 CSS 更容易管理和维护。让我们更详细地探讨一些关键特性,这将让您对 Less 的预期有所了解,并展示 Less 如何使编写 CSS 变得更加容易。
使用变量减少冗余
你在需要声明 CSS 中颜色值的网站上工作过多少次,比如#ececec
?10 次?20 次?您很少能一次就得到正确的颜色;更有可能的是,您需要对其进行修改,这在 CSS 中工作时可能会造成真正的负担。不管它最终变成多少次,有一点是肯定的:记住每个颜色的十六进制值并不容易。
Less 可以通过允许我们使用更具记忆性的名称定义颜色作为变量来帮助我们。变量仅仅是一个引用值的机制;请看以下三个示例:
@red: #de1446;
@blue: #4a14de;
@green: #32de14;
Less 的美妙之处在于,一旦我们定义了这些变量,如果我们在以后更改十六进制值,Less 会自动更新它们被使用的任何实例。
理解变量的语法
在 Less 中,@
符号表示我们正在定义一个变量;紧随其后的是变量名(没有空格),冒号表示变量名的结束。之后是值,用分号来结束语句。在这种情况下,@red
变量指的是我们想要的红色颜色的十六进制值。一旦我们定义了这些变量,我们就可以在 Less 样式表中任何地方使用它们,如下所示:
.red-box {
color: @red;
}
当我们编译它时,会生成以下有效的 CSS:
.red-box {
color: #de1446
}
注意
在 Less 中,编译仅仅意味着从 Less 转换到 CSS。我们将在整本书中频繁使用这个术语。
编写和记住变量名比记住不自然的十六进制值要容易得多,对吧?此外,当这些值需要更改时,我们只需要在一个地方更新它们,Less 就会负责更新其他所有内容。不再需要在更改颜色时执行“查找和替换”——这可以节省大量时间!
创建可重用的代码块
所以我们创建了一些变量……但是可重用的代码块?
使用 Less 的一个好处是我们可以将多行代码组合在一起,并将它们转换成一个可重用的代码块,我们可以将其添加到我们的代码中。让我们看看一个例子:
.serif() {
font-family: Georgia, 'Times New Roman', serif;
}
这是一个可重用代码块或 mixin 的非常简单的例子。如果你在开发 JavaScript 或 jQuery 任何时间,你可能会在类形式中认出类似的行为;mixins 以几乎相同的方式工作。
Mixins 本身不会做任何事情,为了使它们变得有用,我们需要从我们的代码中使用占位符来调用它们,如下面的代码所示:
p {
font-size: 10px;
line-height: 1.25em;
.serif;
}
这会编译成有效的 CSS:
p {
font-size: 10px;
line-height: 1.25em;
font-family: Georgia, 'Times New Roman', serif;
}
看看,仅仅用一个简短的单词,我们就让 Less 添加了一些更复杂的内容?有一点需要注意,就是使用括号()
来对 mixin 名称进行操作——Less 会将可重用的代码(或 mixin)编译成有效的 CSS,但它不会在屏幕上渲染编译后的 mixin。不过,最棒的是我们可以简单地调用 .serif;
来在任何需要使用定义的 font-family
属性渲染文本的地方。
自动生成值
在较新的浏览器中,你可能会发现一些网站使用 RGBA(红绿蓝透明度)和 HSLA(色调饱和度亮度透明度)颜色,而不是我们在上一节中看到的典型十六进制值。
并非每个浏览器都支持这些颜色格式——为了解决这个问题,我们可以先声明一个十六进制值,然后是它的 RGBA 或 HSL 等效值。例如,我们可能会编写类似于以下代码的内容,以便将使用 h1
属性设置的文本设置为深棕色:
h1 {
color: #963529;
color: rgba(150, 53, 41, 0.5);
}
如果我们在像 Photoshop 或 GIMP 这样的图形包中选择颜色,我们有时可能会难以同时获得值,可能需要求助于其他方法。幸运的是,Less 没有这个问题,因为它允许我们使用函数自动创建新值。
我们为什么要这样做?答案很简单:我们只需要使用一种格式提供颜色值,例如 RGBA。然后我们可以使用 Less 的函数将其转换为不同的格式——这样我们就可以避免任何关于确保我们提供了正确值的混淆,因为 Less 会自动处理这些值。
让我们快速看一下这将如何工作:
.brown-color {
@rgbaColor: rgba(150, 53, 41, 0.5);
color: fade(@rgbaColor, 100%);
color: @rgbaColor;
}
在这里,我们使用了一个简单的变量来定义基本颜色,然后在rgba
颜色函数中将它转换为其 RGBA 等效值,alpha 值设置为0.5
。如果我们编译 Less 代码,它将生成以下 CSS:
.brown-color {
color: #963529;
color: rgba(150, 53, 41, 0.5);
}
在我们的例子中,alpha 通道设置为 50%。这意味着在支持 RGBA 的浏览器中,我们可以看到颜色背后的 50%的内容。当为网站创建主题时,函数的使用将真正发挥其作用——我们可能只需要两种到三种基本颜色就能创建出一整套颜色!
我们将在本书的第十二章中进一步探讨颜色函数,使用 Less 处理颜色。
忘记供应商前缀
使用 CSS3 的好处是,我们不需要总是使用图像,因为我们经常可以仅使用纯样式就达到相同的效果。问题是,为了适应所有这些新特性,如背景渐变、动画、盒阴影等,我们通常必须使用供应商前缀或不同的语法,以确保网站可以被尽可能广泛的受众查看。
这可能是一个真正的麻烦,但在预处理器中就不会这么麻烦。正如你将在第四章中看到的,使用变量、混合和函数,我们可以创建一个混合或一小块预定义的代码,可以直接混合到我们的 Less 样式表中,并用于创建有效的 CSS。例如,以下代码块用于生成圆角:
.roundcorners {
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
-ms-border-radius: 4px;
-o-border-radius: 4px;
border-radius: 4px;
}
使用 Less,有成百上千的混合函数可以在网上找到(本书后面将详细介绍),我们可以在代码中使用它们。我们不需要记住每种样式在术语前缀和语法方面需要什么,我们只需使用以下代码:
.roundedcorners {
.border-radius;
}
上述代码生成的 CSS 与之前编译的 CSS 完全相同;Less 自动添加所有供应商前缀,这是一个节省时间的好方法。
简单创建媒体查询和动画
移动设备的出现创造了对响应式网站的需求,这些网站只有在满足特定环境条件或断点时才会显示内容。一个很好的例子是在浏览响应式网站时确定正在使用的屏幕大小。
这通常意味着需要为设计中的每个断点编写多个查询。例如,我们可以编写以下(简化后的)CSS 来更改特定设备的排版:
@media only screen and (max-width: 529px) {
h1 {
font-size: 0.7em;
}
}
@media only screen and (max-width: 949px) {
h1 {
font-size: 0.9em;
}
}
@media only screen and (max-width: 1128px) {
h1 {
font-size: 1.1em;
}
}
尽管这只是为了设置h1
属性的尺寸,但看起来需要记住的东西很多。我们可以利用 Less 的强大功能来简化代码:
@smallwidth: ~"only screen and (max-width: 529px)";
@mediumwidth: ~"only screen and (max-width: 949px)";
@largewidth: ~"only screen and (max-width: 1128px)";
h1 {
@media @smallwidth { font-size: 0.7em; }
@media @mediumwidth { font-size: 0.9em; }
@media @largewidth { font-size: 1.1em; }
}
我们首先声明三个变量,每个变量包含一个媒体查询语句。这些是静态值,只有在决定添加或修改任何支持的断点时才会改变。在这个例子中,使用它们并不是必需的,但它们将有助于使嵌套解决方案更容易阅读!
我们随后使用@media
调用每个媒体查询,后面跟着包含我们希望测试的断点的变量。这里的关键点是,尽管看起来@media
被重复了,但我们不能基于@media
来构建嵌套样式,因为代码将无法正确编译。相反,我们需要基于h1
选择器来确保代码能够正确编译。
在多个项目中重用代码
CSS 的一个局限性是,我们经常发现自己需要在构建的每个网站上跨多个元素应用相同的值。在小网站上,这不太方便,但在大网站上,我们可能会错过更新一个值的风险更大,这可能会导致意外的结果。我们已经看到,您可以使用变量来减少(甚至通过良好的规划消除)这种风险——如果我们能够在未来的项目中重用我们的代码会怎样呢?
这并不像看起来那么疯狂——我们可能会为按钮开发一个特定的阴影样式,我们喜欢并希望重用。传统的方法是将它存储在文本文件、数据库或其他类似的地方,然后每次需要重用时都挖出来。即使它确实可行,这种方法也很繁琐——如果我们使用预处理器,就可以消除这种需求。
我们可以将代码简单地存储在文件中,以混合或可重用代码块的形式。如果我们需要重用其中任何一部分,我们只需将文件添加到我们的项目中,并使用以下命令来导入内容:
@import "mixinfile.less";
然而,使用 Less 的美丽之处在于,它只会导入主 CSS 文件中我们项目所需的那些混合。
自动压缩 CSS 以加快网站速度
到目前为止,我们已经讨论了 Less 的一些令人信服的特性——这只是它提供的一部分功能——在本书的其余部分,我们还将探讨一些 Less 的更实际的应用。
在编写 CSS 时,有一件关键的事情我们没有提到:压缩你的样式表作为将网站发布到生产环境的一部分的能力。压缩我们的样式表可以移除空白,并允许我们在一个主 CSS 文件中连接多个文件。
为什么你应该这样做?答案很简单:这将使样式表的大小减少到原始大小的几分之一,这可以节省带宽。虽然这可能对普通互联网连接来说问题不大,但对于那些使用有限带宽的移动设备的人来说,这是至关重要的。
如何压缩你的 CSS?当然,我们可以使用在线工具来压缩,但这意味着使用额外的工具,这会增加你繁忙的开发工作。如果你使用 GUI 工具(如 WinLess)或命令行编译代码,你可以设置它同时压缩代码。
这只是 Less 能提供的一小部分。在我们开始运行使用 Less 所需的发展工具之前,让我们简要地看看 CSS4 将提供什么,以及这可能会如何影响像 Less 这样的预处理器工具。
在 Less 中支持 CSS4 标准
随着 CSS2 和 CSS3 的出现,自然地假设 CSS4 将在未来的某个时刻到来。你可能想知道它会如何影响 CSS 预处理器——让我们看看 CSS4 对 Less 可能意味着什么。
正式来说,并没有所谓的 CSS4。虽然这听起来可能有些奇怪,我们不会看到新的全球标准的出现;CSS4 将被归类到更小的标题下,其中每个标题都有自己的级别。还有很长的路要走,但最接近最终确定的一个分组是 CSS4 选择器。
注意
你可以在 W3C 的草案提案中查看关于 CSS 选择器提议的更多详细信息:dev.w3.org/csswg/selectors4/
。关于使用选择器的可能性有一个有趣的讨论:vandelaydesign.com/blog/design/some-interesting-possibilities-with-css4/
。
虽然这些功能从 CSS 开始就已经存在,但 CSS4 引入了许多新的逻辑运算符,如:not
和:matches
,以及一些新的局部伪类,如:any-link
或:local-link
。特别是后者,为链接的样式提供了有用的功能,如下面的代码示例所示:
nav:local-link(0){
color: red;
}
nav:local-link(1){
color: green;
}
nav:local-link(2){
color: blue;
}
nav:local-link(3){
color: yellow;
}
nav:local-link(4){
color: gray;
}
我们可以使用以下 Less 代码重写:
nav {
&:local-link(0) { color: red; }
&:local-link(1) { color: green; }
&:local-link(2) { color: blue; }
&:local-link(3) { color: yellow; }
&:local-link(4) { color: gray; }
}
如果我们编译这段代码,我们可以在一个带有面包屑导航的页面上看到结果——例如,URL 为http://internetlink.com/2014/08/21/some-title/
,面包屑导航如下所示:
-
首页 (
http://internetlink.com/
) -
2014 年 (
http://internetlink.com/2014/
) -
2014 年 8 月 (
http://internetlink.com/2014/08/
) -
2014 年 8 月 21 日 (
http://internetlink.com/2014/08/21/
) -
文章(
http://internetlink.com/2014/08/21/some-title/
)
第一个链接将是红色,第二个是绿色,第三个是蓝色,然后是黄色,最后是灰色。
在 Less 中支持未来的 CSS 标准
在 Less 中支持未来的 CSS 标准(或通常称为 CSS4)仍然处于早期阶段。在 Less 中已经取得了一些进展,允许使用选择器,这可以通过我们之前在本章“在 Less 中支持 CSS4 标准”部分中看到的使用井号符号来实现。
在撰写本书时,开发者们已经避免为 CSS4 添加太多新特性,因为大多数当前提出的更改仍然处于草案状态,并且可能发生变化。迄今为止添加的主要特性是对属性的支撑,这出现在 Less 的 1.4 版本中——其他特性将在规范最终确定并在多个浏览器中提供支持后出现。不过,需要注意的是,任何使用 CSS3 语法的 CSS4 标准在 Less 中都是自动支持的。
即使 CSS4 标准成为主流,Less 仍然会有需求;Less 将进化以包含新的标准,同时仍然允许我们在编写 CSS 时更加高效。
小贴士
我的浏览器对 CSS4 的支持程度如何?
作为旁注,你可能想测试你选择的浏览器以查看它对 CSS4 的支持程度;浏览到css4-selectors.com/browser-selector-test/
并点击开始测试以查看结果。
摘要
在本章中,我们首先简要地回顾了 HTML 和 CSS 在网页设计中的作用,并讨论了 CSS 在网页元素样式化时的一些局限性。
我们接着讨论了 CSS 预处理器如何帮助解决这些问题;我们涵盖了人们经常提出的关键问题,即当我们完全熟悉编写有效的 CSS 时,为什么还需要使用它们。然后我们介绍了 Less 作为可用的预处理器之一,以及作为解决我们面临的一些 CSS 问题的可能解决方案。
我们通过探讨为什么 Less 应该成为你的开发工具包的一部分,以及一些有助于你管理 CSS 开发的特性来结束本章。在下一章中,我们将更深入地探讨 Less 的语法以及如何将其编译成有效的 CSS。
第二章:构建更少的开发工具包
我们已经介绍了 Less 背后的原理,并看到了它如何通过使用变量、函数和混入来帮助减少管理样式表所需的努力。我们几乎准备好开始编码了,但在我们这样做之前,还有一个小问题——我们需要一些工具!
您可能会想知道是否需要更多工具,鉴于 CSS 只是纯文本,而且我们不需要任何东西来编辑纯文本文件,对吧?好吧,纯文本编辑器可以工作,但正如我们将在本章中看到的,有一些工具包括对 Less 的支持,以便帮助使文件编辑更容易。
在本章中,我们将探讨一些您可能发现对处理 Less 文件有用的工具;我们将安装一些将在本书的练习中使用的工具,尽管您始终可以选择您偏好的包。
在本章中,我们将涵盖以下主题:
-
选择和安装用于处理 Less 文件的编辑器
-
注意 Less 文件的变化
-
在浏览器中进行调试
-
用于编译 Less 代码的工具
-
使用 Node 和 Grunt 等工具自动化开发
注意
本章中安装的软件将适用于 Windows,因为这是作者的首选开发平台;将添加注释以指示是否提供适用于 Apple Mac 或 Linux 的替代方案。
选择 IDE 或编辑器
我们需要从某个地方开始,还有什么地方比编辑器更好呢。毕竟,如果我们没有可以用来编写内容的东西,我们就无法生产任何东西!编辑 Less 文件非常简单——它们是纯文本文件,几乎可以在任何编辑器中编辑。
缺点是,有数十种编辑器可供选择,要么免费,要么付费。然而,有一些编辑器默认包含对 Less 的支持,或者作为附加包提供,包括以下内容:
-
Sublime Text: 这是一个适用于 Windows、Mac 或 Linux 的共享软件应用程序,可在
www.sublimetext.com
获取;在撰写本文时,许可证费用为 70 美元 -
Notepad++: 这是一个适用于 PC 的开源编辑器,可在
www.notepad-plus-plus.org
获取 -
Coda: 仅适用于 Mac,可在
www.panic.com/coda
获取;在撰写本文时,许可证费用为 99 美元 -
Codekit: 这是一个共享软件应用程序,可在
www.incident57.com/codekit
获取;许可证费用各不相同
可用的编辑器更多;您可以在lesscss.org/usage/#editors-and-plugins
查看完整的编辑器列表。
注意
你可能已经注意到我没有提到像 Dreamweaver 这样的 IDE。虽然这些 IDE 可以很好地与 Less 文件一起工作,但它们的工作方式可能会影响学习如何有效地编写 Less 代码的体验。
同时,让我们看看安装我个人最喜欢的编辑器——Sublime Text 2。
安装 Sublime Text 2
Sublime Text 是一款共享软件跨平台文本编辑器,可在 www.sublimetext.com
获取。其流行源于一个简洁的界面,它允许轻松编辑,同时功能强大。Sublime Text 随附基于 Python 的 API,您可以为它编写插件。
要安装 Sublime Text,我们可以从 www.sublimetext.com/2
下载它。适用于 Apple Mac、Linux 和 Windows 的不同版本都可用;请下载并安装适合您平台的版本,接受所有默认设置。
注意
在撰写本文时,Sublime Text 的下一个版本,版本 3,可在 www.sublimetext.com/3
获取;目前它处于测试版,但如果您不介意使用测试软件,它对于使用来说是相当稳定的!
添加 Less 语法支持
接下来,我们需要为 Less 添加语法支持,这需要几个步骤——第一步是安装 Package Control Manager,这是为了安装 Sublime Text 的插件所必需的。让我们首先浏览到 Package Control 网站的安装页面 sublime.wbond.net/installation#st2
。
我们需要复制 Sublime Text 2 标签中显示的代码,然后打开 Sublime Text 2。一旦打开,点击 视图 和 显示控制台,然后将代码粘贴到控制台中。按 Enter 运行安装。一旦您在控制台窗口中看到以下内容,请重新启动 Sublime Text:
我们现在需要为 Less 安装语法支持。为此,您需要一个互联网连接,因此您可能无法在通勤时完成此操作!
假设您可以访问互联网,请按 Ctrl + Shift + P 打开包管理器,然后输入 Package Control: Install Package,并按 Enter,如下截图所示:
在包管理器检索最新可用的包列表时会有短暂的延迟;您可以在状态栏中监控它们的进度。
一旦检索到,将显示包列表;在包名框中输入 LESS
,如下截图所示,然后按 Enter:
Sublime Text 将现在安装该软件包。在安装过程中会有延迟;我们可以在窗口底部的状态栏中监控其进度。一旦完成,您将在状态栏中看到行 1,列 1;软件包 LESS 成功安装的信息。语法支持现在已安装——如果我们打开 Sublime Text 中的一个测试 Less 文件(例如来自第四章, 使用变量、混合和函数,本书附带代码下载的buttons.less
),我们可以看到代码现在已着色,不再是之前的黑白格式:
到目前为止,我们已经准备好开始编辑 Less 文件了——尽管我们还需要查看一些其他工具,才能拥有一个完整的工具集!一旦我们生成了一个 Less 文件,我们需要将其编译成有效的 CSS,因此让我们看看可用于此目的的一些工具。
使用独立编译器编译 Less 文件
一旦我们生成了一个有效的 Less 文件,我们需要将其编译成其 CSS 等价物。为此,我们有两种选择:第一种是从命令行编译;我们将在本章后面的“从命令行编译”部分更详细地探讨这一点。第二种是使用独立的编译器,为此我们可以使用以下可用的编译器之一:
-
WinLess (
winless.org/
) -
SimpLESS (
www.wearekiss.com/simpless
/) -
Koala (
koala-app.com/
) -
Crunch! (
www.crunchapp.net/
)
这些编译器中的每一个都执行编译 Less 文件的基本功能,但方式不同。我建议您尝试每一个,并坚持使用您认为更合适的一个。
我们必须从某个地方开始,所以首先,让我们看看 WinLess。
WinLess
WinLess 是一个基于 Windows 的开源 GUI 前端,用于 less.js
,可以从 winless.org/downloads/WinLess-1.8.2.msi
下载。它包括一个选项,可以自动监控存储在特定文件夹中的任何文件的更改;一旦它们被更改,相应的 CSS 文件就会更新。
SimpLESS
如果对您来说,一个稍微简单一些的工具就足够了,那么您始终可以尝试 SimpLESS,这是一个适用于 Windows、Apple Mac 或 Linux 平台的精简版。
您可以从 www.wearekiss.com/simpless
下载此软件;它设计为静默地从系统托盘运行,并自动更新任何更改过的 Less 文件。
Koala
Koala 是 Less 预处理器场景中的相对新来者。它是一个跨平台的 GUI 应用程序,可以编译大多数可用的 CSS 预处理器,包括 Less。它是使用 Node-Webkit 构建的,因此版本适用于 Mac OS、Linux 和 Windows,并且可以从 www.koala-app.com/
下载。
您可以通过浏览到 lesscss.org/usage/#guis-for-less
来找到可用于 Less 的其他编译器的详细信息。同时,我们将继续安装 Crunch!,作为 Less 可用编译器的一个示例。
安装 Crunch!
Crunch! 是 Less 的跨平台编译器,使用 Adobe AIR 工作。这个编译器与其他编译器不同,因为它允许我们在编译器内直接编辑文件。
安装 Crunch! 是一个两步过程;我们首先安装 Adobe AIR:
-
从
get.adobe.com/air/
下载安装程序,确保您选择适合您平台的正确版本。双击 AIR 安装程序并接受所有默认设置。 -
接下来,请从
www.crunchapp.net
下载 Crunch!。双击 Crunch.1.6.4.air 包,然后在此提示下点击安装按钮。 -
点击继续开始安装;我们可以保持默认设置不变,因为它们将满足我们的需求:
-
几分钟后,Crunch! 的 GUI 将出现,准备使用,如图所示:
从命令行编译
一些用户可能更喜欢不使用独立的应用程序来编译 Less 代码任务;毕竟,谁需要学习另一个应用程序来执行可以轻松自动化并在后台运行的任务呢?
绝对可以;我们不必使用独立编译器,可以使用基于 JavaScript 的平台(即 Node.js)的命令行来执行相同的操作,Node.js 可在 www.nodejs.org
获取。此应用程序的版本适用于 Windows、Linux、Mac,甚至 SunOS 平台。否则,如果您喜欢冒险,您始终可以尝试从源代码编译!让我们更详细地看看我们如何使用它。
要下载和安装 Node.js,请执行以下步骤:
-
浏览
www.nodejs.org
,然后从主页点击下载;这应该会自动确定适合您平台的正确版本。在撰写本文时,Windows 的最新版本是node-v0.10.24-x86.msi
。 -
双击安装程序开始安装过程;您将看到以下欢迎屏幕。点击下一步。
-
在下一屏,选中 我接受许可协议中的条款 复选框,然后点击 下一步。
-
在这一点上,我们需要选择 Node 将安装的位置。对于本书的目的,我们将假设它将安装在默认位置
c:\wamp
,所以请继续点击 下一步。 -
在下一屏,您可以从多个选项中选择以配置 Node。对于本书中的练习目的,这并不是必要的,所以我们只需点击 下一步。
现在我们已经准备好完成安装,所以点击 安装,等待其完成。一旦完成,Node 就已安装并准备好供我们使用。我们现在可以安装用于命令行的 Less,我们将在下一章中介绍,即 第三章,Less 入门。
注意
如果您想了解更多关于 Node.js 的信息,那么您可能会喜欢阅读由 Packt Publishing 出版的书籍 Mastering Node.js,作者是 Sandro Pasquali。
监视 Less 文件的变化
正如我们将在下一章中看到的,从命令行编译 Less 是一个简单的过程;我们可以打开命令提示符,输入一个简单的命令,然后按 Enter 键让它运行。
问题在于我们必须每次都这样做。过了一段时间,这至少会变得令人厌烦!这是一件我们可以轻松解决的问题——我们首先需要安装 Grunt 的命令行界面,然后再通过设置 Grunt 自动监视并重新编译我们的 Less 源文件中的任何更改。
注意
Less 中有一个可选的监视模式,称为 监视。这仍然需要手动配置;我们将在 第三章,Less 入门 中更详细地探讨它。
在以下示例中,我们将通过安装一个名为 grunt-contrib-less
的包来添加对 Less 的支持。让我们首先在 C:
驱动的根目录下创建一个名为 lessjs
的项目文件夹。在这个文件夹内,创建一个名为 package.json
的新文件,并添加以下代码:
{
"name": "my_grunt_project",
"version": "0.0.1",
"devDependencies": {
}
}
接下来,打开命令提示符并输入以下命令:
npm install -g grunt --save-dev
这将下载并安装多个附加包;--save-dev
参数将自动将任何依赖项添加到 package.json
文件中。
如果我们查看 lessjs
文件夹,我们将看到我们的 package.json
文件;如果我们用文本编辑器打开它,它看起来可能像以下代码:
{
"name": "my-project-name",
"version": "0.1.0",
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-less": "~0.8.3",
"grunt-contrib-watch": "~0.5.3"
}
}
如果下载完成且没有错误记录,则运行此命令:
npm install -g grunt-cli
将以下代码添加到新文件中,并将其保存到项目文件夹中,命名为gruntfile.js
。我们将按部分解释该文件,以便了解每个部分的作用:
module.exports = function(grunt) {
grunt.initConfig({
less: {
src: {
expand: true,
src: "*.less",
ext: ".css"
}
}
},
我们以一个标准的 Grunt exports
语句开始文件;在这里,我们通过设置src
来初始化 Grunt,以便查找 Less 文件并将它们编译成 CSS 文件。我们已将 Grunt 设置为在编译时使用expand
属性(设置为true
)不压缩 CSS 文件,这使得我们在开发过程中更容易阅读,尽管实际上,我们将在生产环境中压缩文件以节省带宽:
watch: {
styles: {
options: { spawn: false },
files: [ "*.css", "*.less"],
tasks: [ "less" ]
}
}
});
由于我们定义了多个任务,我们通常会单独在命令提示符中输入任务。相反,我们可以组合我们定义的所有子任务。然后,我们可以在命令行中输入命令grunt
时运行它们作为默认任务,这有助于节省时间:
grunt.loadNpmTasks('grunt-contrib-less');
grunt.loadNpmTasks('grunt-contrib-watch');
// the default task can be run just
// by typing "grunt" on the command line
grunt.registerTask('default', ['watch']);
};
启动命令提示符,切换到项目文件夹,并在命令提示符中输入npm install
。这将下载并安装多个额外的包。完成此操作后,在命令提示符中输入grunt
。Grunt 将开始监视任何更改,如本例所示:
对 Less 文件所做的任何更改都将强制自动重新编译 Less 文件。
小贴士
如果你想深入研究这些包的源代码,你将在 GitHub 上找到许多,网址为github.com/gruntjs
。
随着时间的推移,当你越来越习惯于使用 Less 进行开发时,你可能想尝试一些其他来自 Node 包管理器网站npmjs.org
的监视器包,以下是一些示例:
-
less watch(可在
npmjs.org/package/less-watch
找到) -
less monitor(可在
npmjs.org/package/less-monitor
找到) -
less watcher(可在
npmjs.org/package/lesswatcher
找到)
现在我们已经安装了 Less,并使用 Grunt 自动编译,我们可以跳到下一章,在正常的文本编辑器中创建一些文件,然后手动编译它们。这会工作得很好,但我们还可以进一步自动化编译过程。让我们看看如何通过添加对 Notepad++等文本编辑器的支持来实现这一点,以便我们可以在编辑器内直接编译文件。
直接从文本编辑器编译 Less 文件
可用的文本编辑器有成百上千种;有些是免费或开源的,而有些则需要付费。一个免费的编辑器例子是 Notepad++;在撰写本文时,当前版本是 6.5.3,可以从notepad-plus-plus.org/download/v6.5.3.html
下载。
目前,我们将设置好并准备好使用。您将在第三章“Less 入门”中看到它的实际应用,当我们使用它从编辑器编译代码时。
下载 Notepad++的安装程序,然后双击它以启动安装过程。点击下一步以接受每个默认设置,这对我们的需求足够了。安装完成后,启动 Notepad++,然后从运行菜单中选择运行以启动运行对话框,并添加以下行(包括引号):
"C:\Program Files (x86)\nodejs\node_modules\.bin\lessc.cmd" -x "$(FULL_CURRENT_PATH)" > "$(CURRENT_DIRECTORY)\$(NAME_PART).css"
点击保存将运行命令添加到现有预设命令列表中;在快捷键对话框中,选择CTRL + L快捷键,并为命令添加编译 LESS 文件
,然后点击确定。
当快捷键窗口关闭后,点击保存以保存更改。目前,点击取消以关闭窗口。我们还没有准备好运行我们的快捷键——这将在下一章中发生。Notepad++现在已设置好,我们可以从应用程序内部编译 Less 文件的任何更改。
通过包安装编译支持
到目前为止,我们已经看到如何设置像 Notepad++这样的编辑器,但我们并不局限于必须使用这种技术为每个编辑器设置。对于某些编辑器,已经为这个目的创建了一个扩展或包,因此安装将简化。一个这样的例子是 Sublime Text——存在一个包,我们可以安装它以提供对 Less 的支持。
首先,启动 Sublime Text,然后按Shift + Ctrl + P以打开我们在此章早些时候安装的包管理器,然后输入Package Control: Install Package
并按Enter。
接下来,输入lesscss
——我们需要安装Less2CSS
包,所以当它在自动完成中显示时,点击它并按Enter:
此时,Sublime Text 将安装该包,这可能需要几分钟时间——成功安装后,确认信息将出现在状态栏中。我们现在已经准备好直接在 Sublime Text 中编译 Less 文件了——我们将在下一章中使用这个功能。
在浏览器中调试 Less
任何描述的代码开发的关键部分是修复任何错误或错误;与 Less 代码一起工作也不例外。我们当然可以手动操作或使用像 CSS Lint(www.csslint.net
)这样的 linting 工具,但任何一种可能都需要直接与编译后的 CSS 代码一起工作,这将使追踪错误回您现有的 Less 代码变得更加困难。
幸运的是,我们有一些选项可以帮助我们在这方面——我们可以在 Firefox 中直接使用 FireLESS 插件进行调试,或者我们可以设置一个源映射,将编译后的样式转换回原始 Less 文件中的行号。让我们先看看如何安装 FireLESS,并为我们在下一章开始编写代码做好准备。
使用 Firefox 调试 Less 代码
要启用 Firefox 中调试 Less 的支持,我们首先需要确保 Firebug 已安装;为此,您可以使用 Firefox 插件的正常安装过程从addons.mozilla.org/en-US/firefox/addon/firebug
下载它。
在撰写本文时,Firebug 的最新版本是 1.12.5,它适用于 Firefox 版本 23 到 26。安装过程简单,不需要重启浏览器。
接下来,我们需要安装 FireLESS。首先,浏览到addons.mozilla.org/en-us/firefox/addon/fireless/
,然后点击添加到 Firefox以启动安装。您可能会收到一个提示,允许 Firefox 安装 Firebug—点击允许。Firefox 下载插件后,点击立即安装(如下截图所示)以开始安装:
当提示时,点击立即重启。FireLESS 现已安装;我们将在第三章 使用 Less 入门中了解如何使用它。
使用 Chrome 调试 Less 代码
我们不仅限于仅使用 Firefox 来调试我们的源代码。我们还可以使用 Chrome;为此,我们需要在 Less 中安装对源映射的支持。
源映射是一个相对较新的功能,它可以与基于 JavaScript 或 CSS 的文件一起使用;其概念基于提供一个机制,将编译后的基于 JavaScript 或 CSS 的代码映射回原始源文件。当内容已被最小化时,这一点尤其有效—没有源映射,很难确定哪段代码出了问题!
此示例依赖于使用网络服务器才能正确工作。我们将继续安装 WampServer 以实现此目的,所以现在让我们来做这件事。
安装 WampServer
WampServer 可以从www.wampserver.com
下载—Windows 的各种版本都可以在下载选项卡中找到;请确保您选择适合您平台的版本。如果您在 Apple Mac 上工作,则可以尝试安装 MAMP,您可以从www.mamp.info
下载它。Linux 用户应该可以在他们的发行版中找到一个合适的选项。
首先,打开您之前下载的安装文件。在欢迎提示中,点击 下一步。选择 我接受协议,然后点击 下一步,如图所示:
我们需要指定一个位置来安装应用程序文件(稍后,我们将在这里托管测试页面)。默认情况下,WampServer 将安装到 c:\wamp
——这是理想的,因为它避免了使用空格,否则我们的 URL 中将出现 %20
。
为了本书的需要,我将假设您使用了默认设置;如果您使用了不同的设置,那么您将需要在稍后托管示例文件时记住新的位置。
然后设置将提示您是否想要创建快速启动或桌面图标——在这个时候,您可以选择您更愿意使用的。点击 下一步 将显示 准备安装 屏幕,它给出了我们安装操作的摘要。如果一切正常,点击 安装 以完成过程。
然后,我们将看到 准备安装 窗口,然后 设置 执行安装。在完成之前,您将看到此消息,我们应该点击 否:
此外,我们还需要安装 Grunt 和 Node,正如本章“监控 Less 文件的变化”部分所述。
现在 WampServer 已经安装,打开命令提示符,将位置更改为您的项目文件夹——在这个例子中,我将使用一个名为 lessc
的文件夹,它将存储在 c:\wamp\www\lessc
。
提示
在这个例子中,我们使用了演示文件夹——当在生产环境中工作时,这将是您提供内容的文件夹。
在提示中,输入以下命令:
lessc namespaces.less > namespaces.css –source-map=namespaces.css.map
在这里,namespaces.less
和 namespaces.css
分别是您的 Less 和 CSS 文件的名字。当编译时,lessc
生成一个 .map
文件,浏览器将使用它来查找 Less 文件中与您的代码中的特定 CSS 样式规则相对应的各种定义。
将 namespaces.less
、namespaces.css
、main.html
和 namespaces.css.map
文件复制到您的 Web 服务器的 WWW
文件夹中——在这个例子中,这很可能是 c:\wamp
。
打开 Google Chrome,然后浏览到 http://localhost/lessc/main.html
。如果一切正常,您将看到以下截图,前提是您已经按下了 F12 来显示开发者工具栏:
在这里,您可以查看构成 .mediumbutton
类的各个 CSS 样式;Chrome 显示编译后的输出样式,但代替指示每个规则在 CSS 中的位置,我们可以看到原始规则在 Less 文件中的位置。
我们将能够使用 Opera(因为最近版本现在是基于 WebKit 的)达到相同的结果。Safari 已经引入了对源映射的支持,但仅从版本 7 开始。Internet Explorer(IE)是唯一一个尚未包括任何源映射支持的浏览器。
现在,不必担心源映射是如何工作的,因为我们将在本书的稍后部分更详细地回顾这个问题。
其他有用的工具
我们几乎就要结束这一章了,但在我们开始开发 Less 代码之前,我们应该看看一些在你花了一些时间用 Less 开发 CSS 后可能会觉得有用的工具:
-
Adobe Kuler:你可以在
kuler.adobe.com/
找到这个工具。尽管这个工具与 Less 没有直接关联,但你可能会在为你的网站选择配色方案时发现它很有用。Kuler 有一些有用的工具,可以帮助你从我们可以从中提取并使用颜色值的颜色调色板中选择合适的颜色。 -
Live.js:如果你花了一些时间编辑样式,你将不得不在每次更改后手动刷新页面;如果你做了很多更改,这可能会变得很繁琐!幸运的是,我们可以通过使用 Live.js 脚本来解决这个问题。这个工具由 Martin Kool 开发,可在
www.livejs.com
找到。它会自动强制刷新正在工作的页面,以便我们可以在更改应用后立即看到它们。 -
CSS3 Please:你可以在
css3please.com/
找到这个工具。这是一个很棒的网站,允许你使用自己的值编辑任何列出的 CSS3 规则;它会自动将相同的规则更改应用到该规则的每个供应商前缀上,以便你有一个在每个主要浏览器中都能工作的更新规则。这在我们将在下一章中看到创建自己的混入时尤其有用。 -
SpritePad:你可以在
wearekiss.com/spritepad
找到这个工具。被称为“创建你的精灵最容易的方式”,SpritePad 是一个在线创建图像精灵的优秀工具,它会自动为每个图像生成适当的 CSS。然后我们可以使用这个工具来创建混入——如果我们正在创建一个包含大量小图像且这些图像在网站上经常出现的大型网站,这尤其有用。 -
Prefixr:你可以在
www.prefixr.com/
找到这个工具。尽管这个网站不是为与 Less 一起使用而设计的,但它仍然很有用。我们可以为特定的浏览器(如 Firefox)开发一个网站,然后使用 Prefixr 为任何仍然需要它们的 CSS3 规则添加其他供应商前缀等效项。 -
WinLess Online:您可以在
winless.org/online-less-compiler
找到这个工具。在本章早期,我们提到了使用 WinLess 作为 Less 编译器;它也有一个针对不使用 Windows 作为平台的用户的在线版本。尽管一些配置选项不存在(例如压缩编译后的代码),但它仍然是一个有用的工具。 -
Less2CSS:您可以在
www.less2css.org
找到这个工具。该网站执行与 WinLess Online 相同的功能,但有一些额外的选项,例如添加用于与源映射一起工作的媒体查询。这位开发者还建议,如果您遇到任何需要帮助的问题,请使用此网站验证您的代码。
这是我用于 Less 开发的工具选择之一;可能还有其他与这里列出的同样有用的工具。请随意使用这些工具。如果您对本书未来版本中的其他工具有任何建议,那么它们是受欢迎的!
摘要
当您安装并可在工作流程中使用适当的工具时,使用 Less 进行工作可以非常有益。我们首先查看了一些可用的编辑器;这些包括对 Less 的支持,如 Sublime Text 或 Notepad++。然后我们继续安装 Sublime Text 2 并为 Less 添加了支持。
接下来是关于编译 Less 代码的选项的讨论——第一个选项涵盖了如何使用 WinLess 这样的独立编译器生成最终的 CSS 代码;我们查看每个主要编译器,然后安装了 Crunch!。
我们接下来探讨了如何使用命令行来编译代码——我们分析了使用独立编译器意味着在您的开发工作流程中增加另一层,这并不是理想的选择。我们进行了一个基本的 Node.js 安装,然后首先将其配置为编译 Less 文件,接着添加了自动监视功能,并以查看如何将此与 Notepad++等编辑器链接结束。
我们接着在本章的结尾部分探讨了在浏览器中调试代码的选项。我们分析了 FireLESS 和 Firebug 如何使 Firefox 的使用变得非常简单,而配置 Chrome(和 Opera)则需要更多的工作,以便使用源映射来实现相同的效果。我们还介绍了一些其他您可能发现对使用 Less 进行开发有用的工具,例如 LESS2CSS 或 Adobe Kuler。
在下一章中,我们将真正深入下去,开始生成有效的 Less 代码。我们将查看下载和添加 Less,并在编写一些样式并查看使用命令行或通过独立编译器编译的结果之前,开始检查其语法。
第三章。Less 入门
在本书的前两章中,第一章,介绍 Less 和 第二章,构建 Less 开发工具包,我们学习了 Less 是什么,它的一些好处,以及为什么你应该掌握一个在开发世界中迅速获得重要影响力的预处理器。
在本章中,我们将从下载和安装 Less 开始,然后设置我们可以在整本书中重复使用的基础项目,它已经设置为我们的偏好。虽然这可能看起来有点平凡,但它确实是使用 Less 的一个基本部分!一旦我们的基础项目准备就绪,我们将快速浏览 Less 的一些主要代码功能,然后查看如何将你的 Less 代码编译成有效的 CSS,并看到对 Less 代码所做的任何更改的效果。
在本章中,我们将通过以下主题更深入地探讨 Less:
-
将 Less 集成到你的网站中
-
在客户端使用 Less 的风险
-
探索 Less 使用的语法
-
创建一些基本样式
-
编译代码并查看结果
-
修改 Less 代码并查看更改的效果
准备好了吗?正如他们在时间力学中所说,现在开始是最佳时机...!
创建基础页面
现在我们已经下载了库,下一步是设置我们的基础项目,我们可以在整本书中重复使用它。这将是一个简单的 HTML5 文档,它将包含我们项目所需的基本框架。
对于我的代码编辑器,我将使用 Sublime Text 2,我们已经在 第二章,构建 Less 开发工具包 中设置了 Less 的支持。这个工具包可以从 Sublime Text 的网站 www.sublimetext.com/2
下载,尽管你可以使用你最舒适的任何编辑器。
首先,让我们创建我们的基础项目文件。在一个名为 lessjs
的新文件夹中,创建一个新文件并添加以下代码:
<!DOCType html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet/less" href="css/project.less">
</head>
<body>
</body>
</html>
小贴士
下载示例代码
你可以从你购买的所有 Packt 书籍的账户中下载示例代码文件 www.packtpub.com
。如果你在其他地方购买了这本书,你可以访问 www.packtpub.com/support
并注册,以便将文件直接通过电子邮件发送给你。
将其保存为 project.html
。我们将在整本书中引用这个文件,并且它是使用 Less 时每个项目的基石。
下载和安装 Less
现在我们已经创建了一个测试页面,是时候下载 Less 库了。库的最新版本是 1.7.3,我们将在这本书中引用这个版本。
要获取库的副本,有两种主要选项可用:下载作为独立库的最新版本或使用 Node 编译代码。我们将从下载独立库开始。
在客户端安装 Less
要在我们的代码中使用 Less,我们可以通过浏览到lesscss.org/#download-options-browser-downloads
并点击Download Less.js v.1.7.3按钮从 Less 网站下载它。
将浏览器窗口中显示的文件内容less.min.js
保存在主lessjs
项目文件夹下的一个名为js
的子文件夹中;最终你会得到类似这样的截图(这显示了你在本章后面将创建的文件):
在本章开头创建的project.html
文件副本中,添加如下高亮显示的代码:
<!DOCType html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet/less" type="text/css" href="css/project.less">
<script src="img/less.min.js"></script>
</head>
<body>
就这样——一旦添加了这些,Less 将动态地将样式编译成有效的 CSS 并在浏览器中渲染结果。需要注意的是,为了使 Less 正确编译样式,必须在代码中首先包含对 Less 样式表文件的引用,然后再包含对 Less 库的引用。
提示
我可以获取 Less 的源代码吗?
如果你想要深入了解 Less 库并更详细地检查代码,那么你可能想下载库的非压缩版本,该版本可在github.com/less/less.js/archive/master.zip
找到。
使用 CDN
虽然我们可以下载库的副本,但在生产环境中托管时我们不需要这样做。Less 可在由 CDNJS 托管的 CDN 上使用。你可以在代码中链接到这个版本。
如果你托管了一个网络流量很大的国际网站,使用由 CDN 托管的文件将有助于确保库是从地理位置靠近访客的服务器下载到访客的计算机上的。这有助于使响应更快,因为浏览器将在后续访问页面时使用缓存的版本,从而节省带宽。然而,这不推荐用于开发!
注意
如果你想要使用 CDN 链接,它可以在cdnjs.cloudflare.com/ajax/libs/less.js/1.7.3/less.min.js
找到。
在服务器端安装 Less
作为即时编译代码的替代方案,我们始终可以使用命令行来执行相同的功能——Less 附带一个内置的命令行编译器,该编译器需要基于 JavaScript 的 Node 平台来运行。
使用 Node 安装 Less
我们在第二章构建 Less 开发工具包中探讨了如何安装 Node;我将假设您已经按照该章节中概述的默认设置安装了它。到目前为止,我们现在需要安装 Less 编译器,所以打开一个命令提示符,切换到我们之前创建的项目文件夹的位置,并输入以下命令:
npm install -g less
您将在命令提示符中看到它运行下载和安装 Less 的过程:
安装完成后,我们可以输入以下命令来编译 Less 文件,它使用以下语法:
lessc srcfile [dstfile]
Less 会将输出编译到stdout
;如果我们想使用不同的输出,则可以重定向输出:
lessc srcfile > dstfile
现在,我们已经准备好在命令提示符中编译 Less 文件了——我们将在本章的后面看到这个操作的实际应用。
使用 Bower 安装 Less
除了使用 Node 与命令行之外,我们还可以使用跨平台的 Bower 包管理器系统安装 Less,该系统可在www.bower.io
找到。
基于 Node,Bower 被设计用来帮助安装网络包,例如 jQuery、AngularJS、Font Awesome 图标库,当然还有 Less。让我们看看如何在 Windows 上安装它,因为这需要一个额外的依赖项——Git for Windows,如果我们想使用这个平台,它也必须被安装。
为了充分利用这个演示,您会发现使用本地 Web 服务器,如 WAMP,会更好。出于本书的目的,我将假设它已经按照默认设置安装。
首先,访问msysgit.github.io
并下载最新的安装程序,即写作时的Git-1.8.5.2-preview20131230.exe
。双击安装程序,然后点击下一步以接受所有默认设置,直到到达此屏幕:
将选定的选项更改为从 Windows 命令提示符运行 Git,然后通过点击下一步接受剩余设置的默认值。Git 安装程序将安装和配置客户端,完成后,如果需要,将显示安装说明以供阅读。
在命令提示符中,输入以下命令:
npm install -g bower
这将下载并安装构成 Bower 的各种包——如果安装成功,它将显示确认信息:
Bower 安装完成后,切换到您的网络空间中的www
文件夹,并输入以下命令来安装 Bower 的 Less 包:
bower install less
这将执行一个类似的过程来下载和安装 Bower 的 Less 包,如下面的截图所示:
到目前为止,Bower 已经安装并可供使用。
使用 Bower 包
现在 Bower 已经安装,我们可以在代码中使用它——然而,主要的区别是它不包含 lessc
的版本,所以我们只能将其用于在代码中动态编译,并且不支持依赖于 Node 的代码开发。
考虑到这一点,我们仍然可以在开发中使用它,至少可以证明我们的代码是可行的——为此,我们只需要对我们的代码进行一个更改。如果我们打开一个 project.html
的副本,我们可以将高亮行更改为使用 Bower 版本的 Less,而不是原始版本:
<link rel="stylesheet/less" href="include.less">
<script src="http://localhost/chapter3/bower_components/less/dist/le
ss-1.7.3.js"></script>
<script type="text/javascript">
</script>
当然,我们可以进一步扩展这一点——Bower 运作方式与 Node 非常相似,允许我们产生 .json
包,就像我们在上一章中为 Node 所做的那样。
注意
如果你想了解更多关于为 Bower 生成包的信息,那么 Bob Yexley 在 bob.yexley.net/creating-and-maintaining-your-own-bower-package/
有一个有用的文章。
让我们现在把注意力转向熟悉 Less 语法。在我们这样做之前,有一个重要的观点我们需要注意,那就是在客户端使用 Less 的风险。
在客户端使用 Less 的风险
到目前为止,我们已经介绍了如何在代码中安装 Less 并使用它将代码编译成有效的 CSS,因为每个页面都是这样显示的。
确实,我们应该准备好开始使用 Less,对吧?毕竟,我们已经有了库,我们知道如何添加它,并且对样式编译后的预期有所了解……或者也许不是。我们错过了一个关键点;让我解释一下。
当 Less 首次推出时,它最初是用 Ruby 编写的;这意味着代码必须首先编译,然后才能将其结果包含在网站页面中,作为有效的 CSS。尽管这是一个完全有效的程序,但它使得开发速度变慢,因为需要额外的步骤来编译 Less 代码并将其包含在网页中。
将库重置为 JavaScript 导致速度提高了 30% 到 40%——这导致了直接在代码中包含库和原始 Less 代码的诱惑。这足够好,同时消除了单独编译代码的需要。
然而,出于多种原因,这已经不再被认为是良好的实践,至少对于生产网站来说是这样:
-
JavaScript 可以被关闭——依赖于 JavaScript 来控制网站的样式意味着如果关闭 JavaScript,网站将会出错,导致网站变得混乱!
-
依赖于基于 JavaScript 的库意味着必须向服务器发出另一个 HTTP 请求,这可能导致加载时间增加,尤其是对于脚本密集型网站。
-
在内容丰富的网站上,有很多样式,这可能导致渲染时间的明显增加,因为样式必须在内容渲染之前动态编译。
-
大多数移动平台无法动态处理 Less 的编译(以及相关的 JavaScript 文件),它们将直接终止执行,这会导致混乱。
这并不意味着在客户端编译是完全禁止的,它应该仅限于工作在开发环境中,或者在需要将库本地存储的实例中,例如在 HTML5 应用程序中。
你会注意到,本书中的许多示例将使用 Less 客户端。这是为了确保你,作为读者,能够体验到整个过程;由于我们是在开发/演示环境中工作,这并不是一个问题。当在产品网站上工作时,Less 代码应始终先预编译,然后再添加到网站上。
探索 Less 使用的语法
关于安装的理论就到这里吧!让我们继续,看看构成 Less 的语法。在接下来的几章中,我们将深入探讨库的每个部分;在这样做之前,我们将快速浏览库的一些重要部分,从变量开始。
使用变量
如果我们需要编写 CSS 样式,很可能会包含一个或多个出现在多个地方的风格。一个很好的例子是许多形状,我们可能需要使用相同的值来设置边框或前景色:
.shape1 {
color: #5cb100;
border: 1px solid #5cb100;
}
.shape2 {
background: #fff;
color: #5cb100;
}
.shape3 {
border: 1px solid #5cb100;
}
作为网页设计师,我们可以在代码中简单地使用相同的颜色值,并且在不适当的情况下,这是一个完全有效的选项。然而,如果我们已经设置了一套特定的颜色,却发现它们都需要更改,会发生什么呢?
每个风格都可以单独更改,尽管这假设我们能够更改每个实例——在一个风格繁重的网站上,即使我们尽力,也总会错过一个!
我们可以通过使用变量来存储每个颜色的常量值,并在整个样式表中使用它来轻松解决这个问题:
@my-color: #5cb100;
.shape1 { color: @my-color; border: 1px solid @my-color; }
.shape2 { background: #fff; color: @my-color; }
.shape3 { border: 1px solid @my-color; }
这意味着,如果我们选择更改原始颜色用于其他目的,那么我们只需更改分配给相关变量的颜色值,Less 将自动更新代码中该变量的每个实例。
在我们的例子中,我们设置了一个变量来存储颜色值#5cb100
——如果我们想更改这个值,那么我们只需更改起始处分配的变量即可。然后 Less 将处理更新所有使用该变量的实例,因此我们可以确信更改已在我们整个代码中生效。
我们将在第四章中进一步探讨变量,使用变量、混合和函数。
程序化更改变量
虽然我们可以将变量设置为静态值,但我们可能会遇到需要从代码内部程序化地更改分配给 Less 变量的值的实例。
希望这不会是您需要经常做的事情,但至少了解它是如何工作的是有用的。让我们快速看一下它是如何工作的,使用一个包含几个输入字段和一个简单的 提交 按钮的示例表单。
在一个新文件中,打开我们之前创建的 project.html
文件副本,然后按照所示修改代码:
<link rel="stylesheet/less" href="css/object.less">
<script src="img/less.min.js"></script>
<script type="text/javascript">
less.modifyVars({
'@ button-color': '#61783F'
});
</script>
接下来,在 <body>
标签之间添加以下代码:
<form action="demo_form.aspx">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br>
<input type="submit" value="Submit" id="submitbtn">
</form>
最后,将以下 Less 样式添加到一个新文件中,并将其保存为 object.less
:
@button-color: #4D926F;
input { margin-top: 10px; }
#submitbtn {
background-color: @button-color;
margin-top: 10px;
padding: 3px;
color: #fff;
}
在我们的示例中,我们添加了对 Less 对象的引用,然后使用 modifyVars
方法将 object.less
中指定的 @button-color
变量的颜色更改为 #61783F
。我们将在 第四章 使用变量、混合和函数 中更详细地介绍变量。
创建混合
Less 的下一个关键元素是创建混合,或者说是预定义的 Less 代码块,我们可以将其从一条规则集中重用,作为另一条规则集的一部分。因此,我们以下面的 CSS 块为例:
.green-gradient {
background: #5cb100;
background: linear-gradient(to top, #5cb100, #305d00);
background: -o-linear-gradient(top, #5cb100, #305d00);
background: -webkit-linear-gradient(top, #5cb100, #305d00);
}
在这里,我们向一个名为 .green-gradient
的预设样式规则添加了深绿色的渐变色。到目前为止一切顺利;这将产生一个从绿色到非常深绿色的渐变,完全可用。
我们可以为每个需要类似样式的对象重复这段代码块,但这会迅速导致大量不必要的代码膨胀。相反,我们可以在另一个样式内包含代码块作为混合:
.shape1 {
.green-gradient;
border: 1px solid #ccc;
border-radius: 5px;
}
这将生成以下有效的 CSS——混合代码被突出显示:
.shape1 {
background: #5cb100;background: linear-gradient(to top, #5cb100, #305d00);
background: -o-linear-gradient(top, #5cb100, #305d00);
background: -webkit-linear-gradient(top, #5cb100, #305d00);
border: 1px solid #ccc;
border-radius: 5px;
}
使用这种方法意味着我们可以减少需要编写的代码量,同时仍然产生相同的结果。正如您将在 第四章 使用变量、混合和函数 中看到的,我们将更进一步——通过一些精心的规划,我们可以开始构建一个可以用于未来项目的混合库。关键在于创建足够通用的混合,这样就可以根据需要重用。其他人已经创建了这样的库并在网上提供,我们将使用一些更知名的工具,例如 3L, More or Less 和 LESSHat,在我们的代码示例中。
Less 的好处在于,当我们包含这些混合库时,Less 只会包含那些在我们的代码中被引用的库中的混合。虽然一开始可能看起来我们包含了大量的额外代码,但实际情况是只有一小部分代码被使用——这都归结于我们如何精心规划需要使用多少代码!
Less 中的嵌套样式
接下来,让我们将注意力转向 Less 库的另一个关键部分:嵌套样式的功能。不,我并不是在谈论鸟类的习性(如果您不介意这个双关语),而是一种在创建样式时减少重复的方法。让我详细解释一下。
想象一下,你有一块类似于以下代码的代码块,其中为子元素相对于其父元素创建了一系列 CSS 样式:
#header { color: black; }
#header .navigation { font-size: 12px; }
#header .logo { width: 300px; }
从表面上看,这似乎是正常的代码,对吧?绝对没错,它没有任何问题。然而,我们可以做得更好——在定义每个子元素的类样式时,每个样式规则中都有必要的重复程度。
使用 Less,我们可以更有效地嵌入或嵌套我们的样式。我们的代码将看起来像这样:
#header {
color: black;
.navigation {
font-size: 12px;
}
.logo { width: 300px; }
}
承认这一点可能并不总是能减少在编辑器中编写代码所需的行数。然而,这并不是练习的目的——关键在于使代码更易于阅读,因为与特定元素相关的样式被分组在一起,这样就可以更清楚地了解它们的作用。你会发现,尤其是在较大的网站上,这有时意味着我们需要编写的行数会减少——这都取决于周密的计划!我们将在第五章中更详细地介绍嵌套,Less 中的继承、覆盖和嵌套。
使用操作符计算值
到目前为止,我们的快速预览已经带我们了解了创建变量、基本混合和通过嵌套重新排序代码。现在,我们将进一步提高难度,看看代码中使用操作符的情况。
操作符?惊讶吗?我确信你会的。让我们看看当我们把它们用在代码中会发生什么。想象一下,屏幕上有几个形状,它们的大小和位置都恰到好处。我们可以为每个元素使用单独的样式规则,但这需要仔细的计算来确保所有元素都在正确的位置,尤其是如果任何元素需要重新定位的话。
相反,我们可以使用简单的数学来自动计算每个元素的大小和位置,基于一个或多个给定值:
@basic-width: 100px;
.shape1 { width: @basic-width; }
.shape2 { width: @basic-width * 2; }
当然,这需要每个计算都要完成,但一旦完成,我们只需要更改初始值集,它将自动更新其他所有值。
注意
值得注意的是,在 Less 中有一个严格的数学选项可用,它只计算括号内封装的数学表达式,例如以下代码:
.class {
height: calc(100% - 10px);
}
你可以在lesscss.org/usage/#command-line-usage-strict-math
了解更多关于这个选项的信息。
在我们的例子中,我们设置了一个初始变量 @basic-width
为 100 px,然后使用它来加倍 shape2
的宽度。一旦代码被编译,它将生成以下 CSS:
.shape1 { width: 100px; }
.shape2 { width: 200px; }
如果我们将 .shape1
的值更改为例如 75px
,那么 .shape2
的宽度将被重新计算为 2 x 75px,即 150px
。我们将在本书的后面部分更深入地探讨操作符的使用。
在 Less 中扩展现有样式
这是 Less 中的一个相对较新的功能,它几乎与正常 mixin 完全相反。它需要一点时间来习惯,所以让我们看看一个简单的例子——想象你有一个使用以下样式规则的div
标签:
div { background-color: #e0e0e0; }
div
标签产生的背景颜色是浅灰色。我们可以用这个来扩展另一个元素:
p:extend(div) { color: #101010; }
这会编译成以下代码:
div, p { background-color: #e0e0e0; }
p { color: #101010; }
与将 mixin 类的所有属性添加到现有类中不同,它将扩展选择器添加到现有选择器中,这样扩展类的输出将包括两组样式。
这种方法的优点是它产生的效果与使用 mixins 类似,但不会像使用 mixins 时有时会出现的膨胀。它是通过获取现有选择器的内容,在这个例子中是background-color: #e0e0e0
,并将其分配给新选择器p
来实现的。这样,我们可以更精确地重用现有元素中的样式,而无需引入新的 mixins。
提示
注意,extend 不会检查重复。如果你扩展了同一个选择器两次,它将添加两次该选择器。更多详情,请参阅lesscss.org/features/#extend-featureduplication-detection
。
编译代码并查看结果
现在我们已经看到了 Less 的语法,让我们改变方向,关注如何将 Less 样式编译成有效的 CSS。有几种方法可以实现这一点,其中一些我们在第二章中提到过,构建 Less 开发工具包。目前,我们将专注于使用 Crunch!来编译我们的代码;我们将在本节的后面部分切换到使用命令行。
使用独立编译器
我们将从本章前面展示的变量示例开始。让我们首先启动 Crunch!,然后在主代码窗口中点击New LESS file按钮。默认情况下,它将创建一个名为new.less
的新占位符文件;将示例中的代码粘贴进去。
按Ctrl + S保存文件,然后将其保存在我们之前创建的lessjs
项目文件夹中,命名为variables.less
:
点击Crunch File查看编译代码的结果——它会提示你分配一个文件名,所以请使用默认名称,即与 Less 文件相同的名称,或者在这个例子中,variables.css
:
这很简单,对吧?每次我们修改我们的 Less 文件时,我们只需要保存它,然后点击Crunch File,文件就会自动更新。让我们通过更改分配给@my-color
变量的颜色值来测试这一点。
在variable.less
文件中,按照以下方式修改@my-color
所显示的值:
@my-color: #3f004b;
保存文件后,点击Crunch File——variable.css
标签会短暂闪烁,表示已更新。点击它以查看更改:
如我们所见,Crunch!已成功更新了我们的代码更改——如果存在错误,它会在代码底部显示错误消息,例如这个,以指示代码末尾缺少}
:
在这个例子中添加缺失的}
将修复问题,并允许 Crunch!重新编译我们的代码而不会出现任何问题。现在让我们改变策略,专注于执行相同的操作,但这次使用命令行。
使用命令行编译器
到目前为止,我们使用独立编辑器来编译(或者 Crunch!——这是个双关语!)我们的代码。它已经成功地为我们生成了一些有效的 CSS,如果需要的话,可以在正常的 HTML 页面中使用。这很好,但可能不是每个人的首选选择!
我们不必使用独立编译器,而是可以通过使用命令行来实现相同的结果。虽然这有点手动,但它确实给了我们机会将编译过程作为可以直接从大多数文本编辑器中运行的命令挂钩。
使用命令行编译 Less 文件
通过命令行编译 Less 文件的过程非常简单。首先,打开命令提示符,并将位置更改为我们之前创建的项目文件夹,即lessjs
文件夹。在命令提示符中,输入以下命令,然后按Enter:
lessc variables.less variables.css
基本编译所需的就是这些。现在 Less 将编译variables.less
文件,并将结果保存为同一文件夹中的variables.css
。这意味着你可以将这个会话在后台保持开启状态,每次想要对代码进行更改时,都可以重新运行该命令。
注意
当使用命令行中的lessc
时,Less 提供了一些其他选项。要查看它们,请在命令提示符中输入lessc
以显示完整列表。
监视监视模式中的更改
在这个练习中,我们将查看一个简单但实用的功能,称为监视模式。这允许我们在开发过程中对任何 Less 文件进行更改,并且无需从服务器强制完全重新加载页面即可重新加载页面。值得注意的是,监视模式可以与本地文件系统或 Web 服务器一起使用——两者都将产生相同的效果。为了本书的目的,我们将假设使用后者;在这种情况下,我们将使用 WampServer,这是我们之前在第二章中介绍的,构建 Less 开发工具包。如果你是 Mac 用户,则可以使用 MAMP;Linux 用户在其发行版中将有可用的本地 Web 服务器选项。
我们将通过创建一个包含用户名和密码字段的简单表单来测试它。
假设我们已经安装了 WAMP,或者有可用的网络空间,首先打开你的文本编辑器,然后添加以下代码:
<!DOCType html>
<html>
<head>
<meta charset="UTF-8">
<title>Adding watch support</title>
<link rel="stylesheet/less" href="include.less">
<script src="img/less.min.js"></script>
<script type="text/javascript">
less.env = "development";
less.watch();
</script>
</head>
<body>
<form action="demo_form.aspx">
Name: <input type="text" class="input" />
Password: <input type="password" class="input" />
<input type="submit" id="submitfrm" value="This is a button" />
</form>
</body>
</html>
注意
注意到已经添加了less.env = "development"
。这会将 Less 设置为开发模式——这是在这个模式下我们可以设置的几个选项之一。更多详情,值得阅读 Less 网站上的文档lesscss.org/usage/#using-less-in-the-browser
。
将其保存为www
文件夹中的watchr.html
,默认情况下应该是c:\wamp\www
。接下来,在另一个文件中,添加以下内容并保存为include.less
:
@color-button: #556644;
#submitfrm {
color: #fff;
background: @color-button;
border: 1px solid @color-button - #222;
padding: 5px 12px;
}
启动你的浏览器,然后在浏览器中输入适当的 URL 导航到它;如果一切顺利,你将看到如下内容:
保持浏览器窗口打开。现在,让我们对我们的 Less 代码进行更改;在 Less 文件中,将@color-button
的值更改为#334466
:
@color-button: #334466;
#submitfrm {
color: #fff;
background: @color-button;
border: 1px solid @color-button - #222;
padding: 5px 12px;
}
将更改保存到 Less 文件中。几分钟后,我们将看到我们的按钮颜色从深绿色变为深蓝色,如下截图所示:
当使用 Less 时,编译后的样式存储在浏览器的localStorage区域,并且它们将保留在那里,直到localStorage区域被清除。我们可以通过按F12,然后点击DOM,并滚动到localStorage条目来查看这一点——假设已经安装了 Firebug:
要查看任何更改,我们必须从服务器强制刷新——使用监视功能将浏览器强制进入开发模式,这会阻止浏览器缓存生成的 CSS 文件。
值得注意的是,还有其他方法可以用来监视更改,例如使用 Grunt 或 Gulp。两个很好的例子包括在github.com/kevinburke/observr
可用的 observr,或者可以从github.com/pixelass/lessc-bash
下载的 lessc-bash。我们在第二章中介绍了如何使用 Grunt 监视更改,构建 Less 开发工具包。
摘要
我们现在可以开始更详细地探索 Less 语法了。在我们这样做之前,让我们回顾一下本章学到的内容。
我们从如何下载和安装 Less 开始;我们首先介绍了如何将其作为独立库下载,然后再将其整合到我们的页面中。我们还简要地看了看如何使用 CDN 链接而不是下载代码;虽然这不建议用于开发目的,但它对于生产站点来说仍然是有价值的,如果访问者已经在一个之前的网站上访问过库,浏览器可以缓存该库。
接着,我们探讨了如何在 Node 平台上进行 Less 的服务器端安装。我们看到了使用单个命令编译 Less 文件是多么简单,并且我们可以根据需要多次执行此命令。我们讨论了如何通过观察客户端使用 Less 的风险来安装 Less,以及由于对托管服务器提出的额外要求,这实际上应该仅限于开发环境中的使用。
然后,我们改变了焦点,对 Less 语法的几个关键部分进行了快速浏览,作为在后续章节中更详细探索的先导。在切换到编译一些基本代码以查看编译过程如何工作之前,我们介绍了 Less 中变量的使用、混入、嵌套、操作和扩展。我们检查了如何使用独立的编译器或命令行执行相同的操作。我们以在 Less 中使用watch()
函数结束本章——这可以设置为监视 Less 文件中的任何更改,并强制浏览器自动刷新页面,无需手动干预。
我们现在已经介绍了如何安装 Less 以及如何在我们的代码中启动它。接下来,让我们继续前进,开始探索 Less 的功能,从混入(mixins)、函数和变量开始。
第四章:使用变量、混入(mixins)和函数
到目前为止,在这本书中,我们已经建立了将成为我们 Less 开发工具包的基础,并对 Less 作为 CSS 预处理器的一些语法和概念进行了快速浏览。我相信某个知名演员曾经在电影中说过,“是时候了....”
是的,是时候深入使用 Less 了!然而,等等;这一章说它是关于使用变量、函数等,这当然意味着我们在编写编程代码,对吧?
错了。别担心,我的朋友们;虽然我们将要看看函数,但它们与你在使用 C#或 Visual Basic 等语言开发时看到的函数完全不同。事实上,唯一的相似之处就是名称——正如我们将看到的,Less 世界中的函数更像是使用科学计算器而不是复杂的代码。
这只是我们将要涵盖的一小部分。在本章中,我们将探讨 Less 的一些构建块,包括:
-
创建和定义变量
-
开发简单和参数化混入(mixins)
-
使用 Less 函数
-
使用预构建库
感兴趣吗?让我们开始吧...
在 Less 中探索变量
就像所有美好的事物一样,我们必须从某个地方开始——现在似乎是一个合适的时机来问自己一个问题:对于那些已经熟悉编程基础的人来说,什么时候一个变量不是变量?它是常量——但是等等,这一节是关于变量的,对吧...?如果你觉得这听起来像是双关语,那么别担心,让我来解释。
Less 中的变量与大多数编程或脚本语言中的变量非常相似——它们充当值的占位符。考虑以下代码:
#somediv { width: 200px; height: 200px; }
而不是之前的代码,我们可以这样写:
@width: 200px;
@height: 200px;
#somediv { width: @width; height: @height; }
这段代码会产生相同的结果。
你可能会问自己,“为什么为了同样的结果要写双倍代码?”当然,我们可以简单地使用第一种方法,对吧?
是又否——就这个例子本身而言,它实际上并不那么有效。然而——这正是使用 Less 时的重大区别——当你使用相同的规则来为同一类型的多个项目设置样式,并产生相同效果时,它就变得非常有用。
如果我们需要在整个网站上为许多按钮设置样式,例如,那么我们通常会设置内联样式或使用类。如果我们需要更改样式,这可能会要求我们在样式表中多个不同位置更新样式;这是耗时且容易出错的!
相反,我们在 Less 样式的开头设置变量,这些变量在代码中会被使用。这意味着我们只需一击,就可以自动更新特定值的所有实例;这可以节省大量时间,尤其是如果客户不确定他们想看到什么时!
设置变量的关键是规划;通过一点小心和前瞻性,我们可以在样式表的头部设置变量,然后在我们的 Less 代码中适当使用它们。为了说明我的意思,让我们用一个简单的例子来实践。
创建宝丽来照片
在本章的第一个例子中,我们将使用 Less 创建经过验证的 宝丽来效果,这是加拿大开发者 Nick La (www.webdesignerwall.com
) 开发的,并将其应用于多个图像,如下面的截图所示:
这的好处是,我们不需要在代码中使用任何 JavaScript 或 jQuery;它将使用纯 Less,我们将将其编译为有效的 CSS。
为了本书的目的,我们假设我们将使用配置为自动将 Less 文件编译为有效 CSS 的 Sublime Text,正如我们在第二章中看到的,构建 Less 开发工具包。
注意
如果你使用不同的方式来编译 Less 代码,那么你需要相应地调整步骤。
在本书附带的代码副本中,提取 variables.html
的副本——我们将以此为基础创建我们的宝丽来图像效果。
在我们的框架建立之后,让我们添加一些样式。在一个单独的文件中,让我们开始添加 Less 样式,从定义我们颜色的变量开始:
@dark-brown: #cac09f;
@light-grayish-yellow: #fdf8e4;
@dark-grayish-yellow: #787568;
@image-width: 194px;
@caption-text: ' ';
现在我们已经创建了变量,是时候使用它们了;让我们从为每个列表项添加样式开始,使它们成为每个图像的容器:
li { width: @image-width; padding: 5px; margin: 15px 10px; border: 1px solid @dark-brown; background: @light-grayish-yellow; text-align: center; float: left; list-style: none outside none; border-radius: 4px; box-shadow: inset 0 1px rgba(255,255,255,.8), 0 1px 2px rgba(0,0,0,.2); }
我们现在可以将注意力转向为每个宝丽来图像的内容添加样式;让我们首先设置主要图像出现在每个容器内,而不是向右偏移:
figure { position: relative; margin: 0; }
接下来是添加每个花朵图像及其叠加效果:
figure:before { position: absolute; content: @caption-text; top: 0; left: 0; width: 100%; height: 100%; background: url(../img/overlay.png) no-repeat; border: none; }
最后,让我们为每个图像标题添加样式:
figcaption { font: 100%/120% Handlee, Arial, Helvetica, sans-serif; color: @dark-grayish-yellow; width: @image-width; }
将文件保存为 variables.less
。Sublime Text 将自动将其编译为有效的 CSS 文件,尽管在本演示中,我们将动态编译 Less 代码,因为它并不复杂。
留意观察的读者会发现我们为标题使用了非标准字体——这是 Handlee 字体,可在 Google Fonts 中找到。为了确保它按预期工作,请立即在 variables.html
中的 <title>
标签后添加此行:
<link href='http://fonts.googleapis.com/css?family=Handlee' rel='stylesheet' type='text/css'>
如果你在浏览器中预览结果,你会看到类似以下的内容:
在我们的例子中,我们创建了一系列变量来处理使用的颜色;而不是在我们的代码中显示难以理解的十六进制代码,我们可以使用名称,如 @dark-brown
,这些名称更容易理解:
@dark-brown: #cac09f;
@light-grayish-yellow: #fdf8e4;
@dark-grayish-yellow: #787568;
@image-width: 194px;
我们还可以使用变量来定义文本,例如:
@caption-text: ' ';
需要注意的是,虽然使用变量来定义颜色是最常见的,但这绝不是变量的唯一用途。我们还可以使用变量来定义字符串,就像我们在这里所做的那样,甚至可以将它们包含在 URL 中:
// Variables
@images: "../img";
// Usage
body { color: #444; background: url("@{images}/white-sand.png");}
这将编译为:
body { color: #444; background: url("../img/white-sand.png"); }
注意
值得阅读 Less 官方网站上的变量示例(less.github.io/features/#variables-feature
)。
在我们的例子中,我们动态编译了我们的样式;因此,Less 会自动将每个变量名在整个代码中的每个实例替换为相应的值。在这个时候,我们可以轻松地将 Less 文件替换为编译后的 CSS 文件——它会产生相同的效果。这是我们应该在生产环境中做的事情;我们还应该更进一步,最小化代码以确保带宽使用量保持在最低。
加载变量和设置作用域
在设置和使用变量时,有一个关键要素我们需要注意:在 Less 中加载变量时设置变量作用域。
Less 中的变量是延迟加载的,这意味着在使用之前不需要声明。如果我们已经声明了一个变量的实例,然后再次声明它并赋予新的值,Less 将始终使用变量的最后定义,从它被调用的点向上搜索。考虑以下:
@var: 0;
.style1 {
@var: 1;
.style {
@var: 2;
three: @var;
@var: 3;
}
one: @var;
}
在这个例子中,你可能期望看到 .style1
包含一个 one: 3
的规则。然而,它将编译为 one: 1
,因为 @var: 3
包含在 .class1
类规则中,而这个规则并不在相同的范围内。因此,在 Less 代码中正确地在正确的点上分配变量变得尤为重要,因为我们不需要在使用它们之前提前声明它们。作为一个例子,考虑以下两种编写相同代码的方法,这两种方法都会编译成同样有效的 CSS。考虑第一种方法:
lazy-eval { width: @var; }
@var: @a;
@a: 9%;
编写代码的另一种方法是:
.lazy-eval-scope { width: @var; @a: 9%; }
@var: @a;
@a: 100%;
这两种方法都会编译为:
.lazy-eval-scope { width: 9%; }
你明白我的意思吗?第一种方法更简洁——如果它产生相同的结果,就没有必要使用第二种方法!关于这一点,让我们改变方向,关注我们如何通过引入 mixins 的使用来减少 Less 代码中的重复。
探索 mixins
在编写代码时,你有多少次写出了类似但针对不同项目的代码?你是否想过,通过一点写作风格的变化,你可以转换到使用预构建的 CSS 块,你可以在需要的时候随时将其插入到项目中?
当然,你可以开始创建自己的代码库——这会非常完美。然而,它至少有一个潜在的缺点:你很可能需要手动修改任何存储的代码以适应新项目的需求。虽然这会有效,但你可能会发现自己花费更多的时间更新代码,而不是从头开始编写!
如果我说你仍然可以维护一个代码库,但不需要修改你重用的每个代码库块,这是可能的——通过使用 Less 的混入功能。
混入是代码块,正如其名所示——它们可以被混合到你的项目代码中,并在需要时调用。它们甚至可以被移动到库样式表中,你可以将其包含在你的项目中——美丽之处在于,虽然你可能有一个巨大的库样式表,但只有那些在代码中实际使用的样式会被调用并编译到最终的 CSS 样式表中。
混入的用途广泛,就像你的想象力一样——它可以是从定义一个静态代码块并在 CSS 中调用它这么简单,到将特定值作为参数传递给混入,也就是参数化混入。为了了解混入如何工作,让我们首先使用正常的 CSS 创建一个简单的网页表单。
创建网页表单
如果你花过时间查看网站——在这个技术发达的现代社会,不这么做会很困难——那么你可能会遇到或需要使用无处不在的联系表单。它们无处不在——你甚至可以采取一种愤世嫉俗的观点,认为人们使用它们作为一种避免与人接触的手段!
尽管如此,它们仍然有存在的价值。在接下来的几节中,我们将开发一个简单的联系表单,并使用 Less 混入来增强它,以展示它们如何被用来减少我们需要编写的代码量。
注意
对于这个例子,你需要准备这本书附带代码下载的副本,因为在练习中我们将使用其中的内容。
首先,打开我们之前创建的project.html
副本,然后更新<head>
部分,如下所示:
<head>
<meta charset="utf-8">
<title>Demo: Mixins</title>
<link rel="stylesheet" href="css/buttons.css">
</head>
接下来,在<body>
标签之间添加以下标记:
<body>
<form id="submitfrm" action="demo_form.asp">
<label for="fname">First name:</label>
<input type="text" name="fname"><br>
<label for="lname">Last name:</label>
<input type="text" name="lname"><br>
<input class="button red" id="submitbtn" type="submit" value="Submit">
</form>
</body>
将其保存为mixins.html
——这个文件的副本也包含在代码下载中。从代码下载中,获取位于代码文件夹css
子文件夹中的buttons.css
文件,在这个章节的代码文件夹中。由于空间限制,文件的全部 59 行无法在此全部展示,但一旦它们保存在同一文件夹中,我们就可以预览结果:
如我们从 CSS 样式中所见,确实存在相当多的重复——即使是像我们这样简单的例子!让我们通过在代码中引入混入来改变这一点。
添加基本混入
我们可以从向代码中添加两个简单的混入开始——让我们先编辑buttons.css
的副本,然后在文件开头添加以下代码:
.shadow() { box-shadow: 0 1px 2px rgba(0,0,0,.2); text-shadow: 0 1px 1px rgba(0,0,0,.3); }
.formfont { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }
接下来,我们可以从.button
样式块中移除原始代码,因为这将不再需要——它将被我们三个简单的混入名称所取代:
.button {
.shadow;
.formfont;
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
padding: .5em 2em .55em;
border-radius: .5em;
}
将其保存为mixins1.less
;然后我们可以移除代码中已经存在的buttons.css
链接。别忘了在mixins1.html
中添加我们的 Less 文件链接:
<link rel="stylesheet" type="text/less" href="css/mixins1.less">
将 HTML 文件保存为mixins1.html
——如果我们在一个浏览器中预览结果,我们不应该看到任何差异,但我们可以放心,我们知道我们的三种样式可以在代码中的任何时间重用。
在我们的例子中,我们对可以重用的块中的样式进行了简单的修改——在这种情况下,我们的三个混入可以被网站上使用的任何按钮调用,但它们需要与我们的样式相似。在每个混入中,我们将互补的样式组合在一起,例如font-family
和font-size
。关于应该组合什么和不应该组合什么没有硬性规定;一切都取决于什么有意义并有助于减少我们需要使用的代码量。
我们可以通过传递参数来进一步开发混入——这使得它们更有用,因为我们可以使用相同的代码产生不同的结果,这取决于我们的需求。然而,当使用混入时,有几个需要注意的陷阱——第一个是代码重复。
隐藏原始混入
当使用混入时,Less 会编译(并显示)混入和调用代码,这样我们最终在 CSS 样式表中会有重复的代码。这并不理想,因为它会使样式表比必要的更大,而且在出现问题时更难调试。
为了解决这个问题,我们需要对我们的现有样式进行一些小的修改——在mixin1.less
文件中,修改以下两个 Less 混入:
.shadow() {
box-shadow: 0 1px 2px rgba(0,0,0,.2);
text-shadow: 0 1px 1px rgba(0,0,0,.3);
}
.formfont() {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
按照常规保存文件——Sublime Text 将重新编译 Less 文件。我们可以通过检查 Firebug 中的代码来证明这一点——以下截图显示了在我们的混入中不使用()
的效果:
代码编译完成后,你可以清楚地看到样式已经被移除——它们仍然存在,但已经包含在 CSS 样式规则中,而不是作为单独的混入:
使用!important
关键字
当使用混入时,我们也可以指定!important
属性,就像我们可能对正常 CSS 所做的那样。我们只需要在必须优先于后续定义的同一规则的任何样式后立即添加它:
.mixin (@a: 0) { border: @a; boxer: @a; }
.unimportant { .mixin(1); }
.important { .mixin(2) !important; }
这将由 Less 按以下方式编译:
.unimportant { border: 1; boxer: 1; }
.important { border: 2 !important; boxer: 2 !important; }
由于第二个样式规则被分配了!important
属性,这将优先于第一个规则。虽然!important
覆盖应该谨慎使用——自从它在 CSS1 中引入以来,它已经获得了一些坏名声,因为它经常被误用。但是,如果谨慎使用,它可以发挥重要作用——尽管有些人可能会说,如果你需要依赖它,那么检查你的 CSS 以确保在没有它的情况下无法达到相同的结果是值得的!
注意
对于 CSS 中!important
标签的整体作用的良好解释,你可能想参考 Ian Devlin 关于如何最佳使用此属性的文章,你可以在这里找到www.iandevlin.com/blog/2013/05/css/using-important-in-your-media-queries
。
让我们继续前进,看看你如何通过传递属性使混入更强大。
开发参数化混入
到目前为止,我们已经探讨了如何使用混入创建易于在整个样式表中重用的代码块。原则上,这工作得很好。然而,如果你发现自己想要重用相同的代码块,但由于值不同而无法重用,那该怎么办呢?
好吧,这是 Less 可以做到的;我们已经介绍了如何创建可重用的代码块混入。让我们更进一步,介绍参数的使用——在这里,我们可以在主 Less 文件和单个混入之间传递值。在编译时,Less 将使用传递的适当值来生成所需的 CSS。让我们通过对我们之前在本章中创建的简单表单进行一些更改来实际看看这个效果。
打开一个新文件并添加以下混入:
.background (@bkgrd) { background: @bkgrd; }
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
.box-shadow (@x: 0; @y: 0; @blur: 1px; @color: #000) {
-webkit-box-shadow: @x @y @blur @color;
-moz-box-shadow: @x @y @blur @color;
box-shadow: @x @y @blur @color;
}
.formfont() {
font-size: 14px;
font-family: Arial, Helvetica, sans-serif;
}
将文件保存为mixinlibrary.less
。接下来,让我们修改mixins1.less
的一个副本,因为其中包含一些现在已经冗余的样式。在mixins1.less
中,对.button
混入进行以下更改,如高亮所示:
.button {
.formfont;
.border-radius(.5em);
.box-shadow(1px; 2px; rgba(0,0,0,.2));
display: inline-block;
outline: none;
cursor: pointer;
text-align: center;
text-decoration: none;
padding: .5em 2em .55em;
}
在mixins1.less
的顶部,我们需要链接我们的mixinlibrary.less
文件;否则,编译将因错误而失败——为了解决这个问题,请在mixins1.less
的顶部添加以下行:
@import "mixinlibrary.less";
我们需要做一些更多的更改;在mixins1.less
中,我们对.red
类有三个样式规则,即.red
、.red:hover
和.red:active
。在每个规则中,我们需要更改.background-color
的规则,以使用我们包含在混入库中的 Less 混入。所以,让我们进行以下更改,如高亮所示:
.red {
.background(#ed1c24);
.red:hover {
.background(#f14b52);
.red:hover {
.background(#f14b52);
将文件保存为parametric1.less
——别忘了更新parametric1.html
,为 Less 样式表添加一个新的链接!如果我们在一个浏览器中预览结果,我们可以看到我们的设计(我们预期的)没有任何变化:
然而,通过使用 DOM 检查器(如 Firebug 中的控制台部分)进行更仔细的检查,我们可以看到我们的mixinslibrary.less
中的混入已经成功导入:
在这个练习中,我们介绍了几种有用的技术——花点时间详细了解一下是值得的。
在之前的练习中,我们通过将它们定义为可以随时插入的静态代码块来使用 mixin。这很好,但是尽管代码块是静态的,但它们局限于每个块内包含的内容;如果需要,我们需要修改它们以使用不同的值,这使得它们不太有用。
相反,我们已纳入了参数,例如以下示例:
.background(#ed1c24);
这些是从调用语句传递给 mixin 的,并用于根据传递的值产生不同的结果。当使用mixinlibrary.less
中的 mixin 进行编译时,这将生成以下 CSS:
background: #ed1c24;
这使它们变得无限有用——一个 mixin 现在可以根据传递给它的不同值提供各种不同的用途。
现在,那些敏锐的眼睛中的人注意到我说我们在这里引入了几种有用的技术吗?好吧,第二个是使用@import
语句。值得很好地了解这个关键字,因为它是 Less 的关键部分。它允许你将长而复杂的 Less 文件分解成更小、更易于管理的文件。
等一下,我听到你在问:这难道不是意味着更多的 CSS 文件吗?不,这正是 Less 的美丽之处;无论你创建多少 Less 文件,你最终都会得到一个编译后的 CSS 文件。理想情况下,我们会限制其实际数量,出于实用目的(7-10 是一个很好的指导原则,以允许使用 WordPress 等)。如果你发现自己使用了超过 10 个,那么我建议你重新审视你的页面设计!我们将在本章的使用外部库部分以及第五章,Less 中的继承、覆盖和嵌套中稍后返回到导入 Less 和 CSS 文件。
让我们更进一步;我们通过使用.box-shadow
mixin 引入了多个参数的使用,但值得花时间进一步探索这些,因为我们可以对我们的页面 Less 设计做出更有用的更改。
传递多个参数
到目前为止,我们已经看到了如何向 mixin 传递单个参数,例如使用 border-radius 规则时的半径大小。这是一个很好的开始,但就像往常一样,我们可以做得更多——传递多个参数怎么样?
这为我们打开了无限的可能性,因为我们现在可以扩大传递给我们的 mixin 的范围。例如,如果我们正在创建渐变,那么我们将在我们的 mixin 中硬编码颜色值,这使它们不太灵活!相反,如果我们使用参数化 mixin,那么这允许我们将颜色作为参数传递给 mixin,从而使 mixin 更加灵活和有用。
让我们看看在实际中它是如何工作的,通过更新我们现有的linear-gradient
(和相关供应商前缀)代码,以使用 Less mixin。
在mixinlibrary.less
的一个副本中,在文件末尾添加以下 mixin:
.button (@color1, @color2, @color3) {
background: -moz-linear-gradient(top, @color1 0%, @color2 6%, @color3 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, @color1), color-stop(6%, @color2), color-stop(100%, @color3));
background: -webkit-linear-gradient(top, @color1 0%, @color2 6%, @color3 100%);
background: -o-linear-gradient(top, @color1 0%, @color2 6%, @color3 100%);
background: -ms-linear-gradient(top, @color1 0%, @color2 6%, @color3 100%);
background: linear-gradient(to bottom, @color1 0%, @color2 6%, @color3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='@middle', endColorstr='@stop', GradientType=0);
border: 1px solid #980c10;
}
现在,我们的 Less 文件中有冗余代码;因此,在 parametric1.less
的副本中,删除每个块中的六个背景语句,以及过滤器和边框语句。用以下内容替换它们,如高亮所示:
.red {
.background(#ed1c24);
.button(#ed1c24, #e93a3f, #aa1317);
}
.red:hover {
.background(#f14b52);
.button(#f14b52, #ee686c, #d8181d);
}
.red:active {
.background(#c61017);
.button(#c61017, #d8181e, #7c0e11);
}
将文件保存为 parametric2.less
——别忘了更新 parametric.html
文件,使用我们 Less 文件的新名称。
在这个练习中,我们继续使用参数化 mixin 的主题,但这次,我们在每个实例中用不同的参数调用相同的 mixin。从理论上讲,只要 Less 能够将它们与每个 mixin 中的有效输入匹配,传递多少参数都没有关系。然而,如果你最终传递了 4-5 个以上的参数,那么重新评估你的 mixin 并可能考虑是否需要重写会是一个好主意!
如果我们在浏览器中预览结果,我们不应该期望在我们的表单中看到任何可见的结果,但我们可以在 Firebug 的 HTML 选项卡中看到变化:
将条件应用于 mixin
当使用静态或参数化 mixin 时,我们应该注意的一件事是——无论情况如何,只要传递给 mixin 的任何参数可以正确匹配和处理,mixin 都会被应用。
这并不总是好事;幸运的是,我们可以通过给 mixin 添加条件来修复这个问题,这样它们只有在满足附加的条件时才会执行。这些被称为 受保护 mixin——我们将在第八章 第八章. 使用 Less 的媒体查询 中更详细地介绍这些内容,我们将看到 Less 在制作响应式网站时如何得到良好的应用。
使用特殊关键词
如果你花时间与 mixin 一起工作,那么在 Less 开发过程中,你会在某个时候遇到两个有用的变量:@arguments
和 @rest
。让我们看看它们是如何工作的,以我们上一次练习中创建的 .box-shadow
mixin 为例。
在上一个练习中,我们创建了 .box-shadow
mixin 来处理我们的 box-shadow
样式:
.box-shadow (@x: 0; @y: 0; @blur: 1px; @color: #000) {
-webkit-box-shadow: @x @y @blur @color;
-moz-box-shadow: @x @y @blur @color;
box-shadow: @x @y @blur @color;
}
我们使用以下命令引用了这个 mixin,它工作得非常完美:
.box-shadow(1px; 2px; rgba(0,0,0,.2));
然而,如果你不想处理所有单个参数(尤其是如果涉及几个参数),那么你可以将 @x @y @blur @color;
替换为 @arguments
变量:
.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
box-shadow: @arguments;
}
这将以完全相同的方式处理单个参数,并在 Less 编译时产生有效的 CSS。
如果你想改变 mixin 接受的参数数量,那么你可以使用 Less 的能力来引用命名变量。Less 将会自动将它们与 mixin 中的变量匹配,并在编译代码时产生适当的结果。例如:
.mixin(...) { // matches 0-N arguments
.mixin() { // matches exactly 0 arguments
.mixin(@x: 1) { // matches 0-1 arguments
.mixin(@x: 1; ...) { // matches 0-N arguments
.mixin(@x; ...) { // matches 1-N arguments
你也可以使用 @rest
关键字——我们首先将不同的值传递给参数列表中的任何命名变量,然后使用 @rest
来告诉 Less 使用剩余的变量,就像现在这样:
.mixin(@x; @rest...) {
// @rest is bound to arguments after @x
// @arguments is bound to all arguments
}
当你开始使用 mixin 时,这两个简单的技巧将非常有帮助——我们还没有介绍的一个技巧稍微复杂一些:将 mixin 用作函数。现在让我们解决这个问题,看看这对开发 mixin 意味着什么。
将 mixin 作为函数创建
在我们创建和开发 mixin 的旅程中,我们看到了如何将样式分组并按需更改输出,如果它被设置为接收调用语句的值。但我们还没有涵盖一个领域,那就是在 mixin 中使用函数——让我们纠正这一点,并简要看看这意味着什么。
在 mixin 内部创建的任何变量都对外部世界可见,并且可以从调用语句中引用。这意味着在 mixin 内部,我们可以调用另一个 mixin 并引用第二个 mixin 内部的任何变量:
.mixin() {
@width: 50%;
@height: 100px;
}
.caller {
.mixin();
width: @width;
height: @height;
}
之前的代码在编译后会产生:
.caller {
width: 50%;
height: 100px;
}
将此进一步扩展,我们可以在 mixin 内部定义的变量中像返回值一样使用它们——这适用于在 mixin 内部被调用的任何变量:
.average(@a, @b) {
@average: ((@a + @b) / 2);
}
div {
.average(6px, 30px); // "call" the mixin
padding: @average; // use its "return" value
}
上述代码将产生以下结果:
div { padding: 18px; }
这非常有用,因为它意味着我们不必在代码开头声明一大堆变量,而是可以将它们转换为可以存储在 mixin 库中并在未来项目中重用的 mixin。我们将在本章的“将计算移动到 mixin”部分更详细地介绍这一点。
使用外部库
到目前为止,我们已经开发了许多 mixin,并从我们的主 Less 文件或我们创建的用于存储多个 mixin 的库文件中引用它们。这都很好,但是——稍等一下——Less 的核心概念之一是 DRY(Don't Repeat Yourself)。当我们创建这些 mixin 库文件时,我们在某种程度上是在重复其他人可能已经做的事情,通过创建和发布他们自己的解决方案。
考虑到这一点,值得在网上搜索看看是否有人已经发布了他们自己的 mixin 库供使用;你可以尝试一些好的库,包括:
-
LESS Elements:可在
www.lesselements.com
找到 -
LESS Hat 2:可以从
www.lesshat.com
下载 -
3L:托管在 GitHub 上,
mateuszkocz.github.io/3l/
-
ClearLess:可在
github.com/clearleft/clearless
找到
作为 Bootstrap 的一部分提供的 Less 库也包含一些有用的 mixin——我们将在第十章“使用 Bootstrap 与 Less”中更详细地探讨这一点,第十章。
在线还有数百个可供选择——花时间查找是值得的,因为可能存在一个库能满足你的需求。
要包含库,只需将此行添加到你的 Less 文件头部即可:
@import <name of library file>
调用混入的名称,包括所需的任何参数。我们已经在本章的开发参数化混入部分中使用了这种方法,那里的原则也适用于这里,无论是调用别人制作的预构建库还是你自己的创作。
足够讨论混入(mixins)了——让我们转换话题,关注 Less 的另一个领域,那就是在代码中使用函数。
介绍函数
Less 的另一个有用特性是它能够计算出在 CSS 中应该使用的值,这是通过计算函数的答案而不是仅仅使用静态值来实现的。
如果你已经熟悉编程中的函数,你可能会认为在 Less 中使用函数将涉及编写大量的复杂公式。在你举手表示恐惧之前,不要害怕——它不必那么复杂!在本节中,我们将探讨如何使用一些简单的数学函数自动计算值,使用运算符和data-uri
函数作为 Less 中提供的许多函数的示例的基础。
注意
你可以在主网站上看到函数的完整列表,网址为lesscss.org/functions/
。
创建基于列的布局
开发者必须执行的任务之一是为网站构建大纲框架——这可能是数百种设计之一,但很可能它将以某种形式使用列。
在某些情况下,这可能会带来问题,尤其是在处理不同浏览器之间的差异时。幸运的是,Less 可以在这里提供帮助——我们可以使用它的一些数学运算符轻松构建合适的布局。为了给你一个概念,这里有一个我们下一个练习中完成的文章的截图:
在随本书附带的代码下载副本中,提取functions1.html
的副本——我们将以此为基础来设计我们的简单页面布局。
如果我们现在预览结果,设计看起来会很糟糕。让我们通过添加至关重要的样式规则来修复这个问题。在一个新文件中,添加以下 Less 样式:
@baseWidth: 800px;
@mainWidth: round(@baseWidth / 1.618);
@sidebarWidth: round(@baseWidth * 0.382);
div { padding: 5px; margin-top: 5px; margin-bottom: 5px; font-family: 'Kite One', sans-serif; }
#container { width: @baseWidth; border: 1px solid black; margin-left: auto; margin-right: auto; margin-top: 5%; margin-bottom: 5%; border-radius: 4px; box-shadow: 4px 4px 4px 0px rgba(0, 0, 0, 0.5); }
#title { color: #FFF; font-family: 'Kite One', sans-serif;
font-size: 32px; font-weight: 400; padding-left: 100px; padding-top: 30px; position: absolute; }
#header { height: 150px; font-size: 18px; background-image: url("../img/leaves.jpg"); }
#leftmargin { width: @sidebarWidth; border-right: 1px solid #ccc;
float: left; box-sizing: border-box; -moz-box-sizing:border-box;
height: 575px; }
#leftmargin li { list-style: none; }
#leftmargin a { text-decoration: none; }
#leftmargin a:hover { text-decoration: underline; }
#content { width: @mainWidth; float: left; box-sizing: -box;
-moz-box-sizing:border-box; height: 575px; padding: 10px; }
#footer { border-top: 1px solid #ccc; clear: both; font-size: 12px; }
将文件保存为functions.less
。Sublime Text 将自动将其编译为有效的 CSS 文件functions.css
。如果我们预览结果,我们应该看到一个简单但完全可接受的页面出现:
在这个例子中,我们使用了一些样式来制作一个简单的两列网页。这个技巧的关键在于以下代码:
@baseWidth: 800px;
@mainWidth: round(@baseWidth / 1.618);
@sidebarWidth: round(@baseWidth * 0.382);
在这里,我们设置了三个变量;第一个变量@basewidth
设置了内容容器的整体大小,这对于确定我们将使用的每个列的宽度至关重要。接下来,我们设置了@mainwidth
值,它从@basewidth
计算得出,除以 1.618(或大约 61%)——这给出了494px
的值。最后,我们使用相同的原则来计算列的值——这个公式的结果变为800 x 0.382
,这给出了305.6px
或大约总宽度的 39%。
使用这个计算意味着我们可以确保列将保持正确的宽度,无论我们的容器大小如何。
将计算移动到 mixin 中
在上一个例子中,我们使用了一些简单的数学来确定生成两列布局所需的大小;这构成了一个简单但有用的页面布局的基础,可以轻松地用于创建任何数量的网站。
然而,还有一个挥之不去的想法,那就是我们能否做得更好——如果我们能把我们的声明转换成一个 mixin,并像使用函数一样使用它呢?听起来疯狂吗?嗯,也许并不——我们已经在本章的“创建函数式 mixin”部分介绍了如何做到这一点的基础。让我们将一些理论应用到实践中,看看它是如何运作的。
首先,打开我们之前用于创建页面演示 Less 样式的functions.less
副本。在顶部,删除前三条变量声明。接下来,立即在其下方添加以下 mixin——这是我们替换掉刚刚注释掉的声明的替代品:
.divSize (@x) {
@baseWidth: @x;
@mainWidth: round(@baseWidth / 1.618);
@sidebarWidth: round(@baseWidth * 0.382);
}
我们需要调整三个使用此 mixin 中变量的<div>
元素;所以,请按照以下突出显示的更改进行操作:
#container {
.divSize(800px);
width: @baseWidth;
#leftmargin {
.divSize(800px);
width: @sidebarWidth;
#content {
.divSize(800px);
width: @mainWidth;
将更改保存为functions.less
。如果你在浏览器中预览结果,你应该在视觉上看不到任何变化。然而,这给了我们一个机会,如果我们一直在创建一个 mixin 库,就可以将 mixin 分离出来——一个很好的例子是我们之前在书中编写的mixinlibrary.less
文件。尽管现在这个文件可能包含许多我们在这里不需要使用的 mixin,但 Less 只会拉入它在编译过程中直接调用的那些 mixin。
使用 data-uri 函数
到目前为止,我们将完全改变方向,看看 Less 中可用的其他函数——data-uri
选项的使用。
Data-uri
是 Less 中可用的一个函数,它将资源内联到样式表中;通过直接在样式表中嵌入内容,它避免了需要链接到外部文件的需求。尽管这可能对文档大小没有帮助,但它将有助于减少从服务器发出的 HTTP 请求数量;这是影响互联网上页面加载速度的关键因素之一。我们将在本节末尾介绍更多关于这些陷阱的内容。
让我们开始编写一些代码——这个过程涉及几个步骤,为了让你了解我们将要产生的内容,这里有一张完成作品的截图:
让我们从打开 functions1.html
的副本并修改 <div>
页脚开始:
</div>
<div id="footer">
© samplesite.com 2014
<div id="social"></div>
</div>
</div>
将此文件保存为 functions2.html
。在此处,我们需要添加一些社交媒体图标——互联网上有成千上万的选择;我在我们的示例中使用的是来自 Vintage Social Media Stamps: Icon Pack 的图标,由 John Negoita 设计,可在 designinstruct.com/free-resources/icons/vintage-social-media-stamps-icon-pack/
获取。
如果你需要一些灵感,你可能想看看 www.hongkiat.com/blog/free-social-media-icon-sets-best-of/
上列出的各种包——展示了一些令人惊叹的例子!
在这个例子中,我们使用了三个图标:RSS、Facebook 和 Twitter 图标,尽管你可能更喜欢根据你的需求使用包中的不同图标。
接下来,为了使图标的定位更容易,我们将它们转换成图像精灵。对于初学者来说,图像精灵是一种非常有用的方法,可以减少从服务器请求资源的数量。如果你网站上有很多小图像,如箭头或图标,这尤其有用;一旦下载了初始图像,它将在网站上其他地方缓存以供进一步使用。
注意
如果你想要了解更多关于使用 CSS 图像精灵的信息,请访问 css-tricks.com/css-sprites/
。
创建图像精灵有多种方法;最简单的方法是使用在线服务,例如 spritepad.wearekiss.com/
上的服务,我们将在示例中使用它。
浏览到网站,然后将每个图像拖放到网格上。调整它们的位置,直到每个图像周围都有均匀的间隙——目标是在每个图像之间留下 3-5 像素。当你对布局满意时,点击 下载 以获取网站生成的转换后的精灵和相关的 CSS 样式。
从我们刚刚下载的压缩存档中,将图像提取到 lessjs
项目文件夹中;将其存储在 img
子文件夹中。切换到你的文本编辑器中的新文档,然后添加以下内容,假设你已经使用了前面概述的相同图标:
#social {
background-image: data-uri('../img/sprites.png');
width: 175px;
height: 60px;
float: right;
}
将文件保存为 social.less
——别忘了在 functions2.html
的 <head>
部分添加对 social.less
的链接:
<link rel="stylesheet" href="css/social.less">
Sublime Text 会将代码编译成有效的 CSS——虽然使用这种方法的好处可能不会立即显现,但当你查看生成的 social.css
文件时(该文件包含在本书的代码下载中),你将看到效果。为了给你一个大致的概念,这是从我们的编译 social.css
文件中提取的内容:
#social{background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAA...
如果你将文件保存并在浏览器中预览结果,你将看到图标出现在页脚,类似于这个截图:
在我们的例子中,我们取了三张图像并将它们转换成一张单独的图像精灵。然后我们使用 data-uri
函数从我们的 Less 样式表中引用它,并使用标准的 CSS 属性来确定其高度和宽度(这对于背景图像规则的正确工作是必要的)。
使用 data-uri 函数——一些注意事项
虽然确保页面大小保持在最小是开发者的最佳利益,但在使用 data-uris
时,我们仍需注意一些潜在的问题:
-
将使用
data-uri
渲染图像的网站更新可能会使其维护变得更加困难——最好在图标或图像频繁重复的地方使用data-uri
。 -
在 CSS 样式表中设置一个较长的过期时间是一个好习惯,这样可以使样式表尽可能多地被缓存,尤其是对于经常重复出现的图像。
-
一些浏览器会对可使用的
data-uri
的大小设置严格的限制。例如,IE8 的最大限制是 32KB;这将限制可以使用的图像大小。 -
你会发现嵌入式代码意味着更大的文件大小——只要文档被缓存,这通常不是问题;如果需要,你可以通过使用 gzip 压缩来帮助减少这一点。
这不应该让你对使用 data-uri
挫折——它只是意味着你需要小心地在你的页面上使用它!只要谨慎选择要使用的内容,Data-uri
是一种非常实用的方法,可以减少对服务器的请求次数。一个很好的例子是小的信用卡图像——这些图像在电子商务网站上频繁重复,因此它们可以很容易地内联在 CSS 样式表中。
摘要
呼吁!我们在本章中涵盖了大量的内容!让我们回顾一下我们学到了什么。
我们首先探讨了如何在 Less 中创建变量,并且谨慎地使用它们来有效地创建一系列图像上的经典宝丽来效果。我们看到了这种方法如何真正节省时间,通过减少对代码的修改次数,同时注意到变量的作用域可以变化,以及这如何影响我们的代码。
我们接着转向查看混入(mixins)——包括静态和参数化两种类型。在这里,我们通过一点预先思考,发现可以创建可重用的代码块,这些代码块可以轻松地插入到我们的主 Less 文件或代码库文件中。我们使用这种技术迭代地改变构建一个非常简单的网页表单所需的代码,以证明所做的改进不会影响整体结果。
接下来,我们介绍了使用函数的方法,我们看到通过使用一些简单的运算符或数学函数,我们可以用很少的输入产生一些有用的结果。我们看到了如何使用一个小混入轻松创建一个简单的两列页面布局,并且如果需要,这可以进一步发展以包含更多的列。
最后,但同样重要的是,我们探讨了使用 Less 的另一个功能,即data-uri
运算符。我们看到了将图像转换为可以在代码中内联渲染的格式是多么容易,这有助于减少从服务器渲染内容所需的请求数量,并提高访问我们页面的速度。
在下一章中,我们将继续前进并改变方向,通过查看 Less 中的继承、覆盖和嵌套来覆盖 Less 的另一个关键领域。
第五章. Less 中的继承、覆盖和嵌套
到目前为止,在我们的 Less 之旅中,我们已经看到了如何开始减少需要编写的代码;现在是时候提升一个层次,开始探讨 Less 中的一些更高级的概念。
让我先问你一个问题:关于编写样式时必须多次重复相同选择器的事情,有什么让你感到烦恼?比如在设计使用无序列表元素的菜单系统时?希望答案是重复的样式。在本章中,我们将探讨如何分组样式以避免在代码中重复选择器。我们还将介绍如何继承样式,这可以显著减少重复;我还会提供一些使用这些技术和其他技术的提示和技巧,以帮助减少代码膨胀。
足够聊天了,让我们看看本章我们将涵盖哪些内容:
-
在 Less 中嵌套样式
-
继承样式
-
Less 中的命名空间
-
Less 中样式的范围
-
避免代码膨胀的建议和技巧
-
在 Less 中导入样式表
好奇吗?你在等什么?让我们开始吧...
在 Less 中嵌套样式
如果你花时间编写样式,我敢肯定你经常会编写一些在其他地方相同样式表中已经存在的重复样式;如果你正在为网站的元素创建样式,例如使用 <ul>
或 <li>
的菜单系统,这种情况尤其如此。
它可能会因为重复的样式而增加大量的额外代码膨胀。幸运的是,我们可以通过使用 Less 嵌套样式的功能来减少这一点。让我们通过创建在线名片来查看这个原则是如何工作的。
对于这个练习,我们需要一些东西。首先,我们需要在卡片上放置一张图片;在这个例子中,我们将使用头像,因为这个名片将在网站上显示。为此目的有数千个图标可用;我将假设你已经选择了一个合适的图标并将其保存为 avatar.png
。我使用了来自 www.iconarchive.com/show/vista-people-icons-by-icons-land/Office-Client-Male-Light-icon.html
的 Office Client Male Light 图标。
接下来是电话、电子邮件和象征性图标;这些图标来自 www.fontsquirrel.com/fonts/modern-pictograms
上的 Modern Pictograms 字体家族。您需要将其转换为可以嵌入网页的格式;这可以通过 www.convertfonts.com
上的免费服务来完成。
最后,在我们开始创建我们的卡片之前,我们需要一些社交媒体图标。我选择了 Chris Spooner 的手绘图标,可以从blog.spoongraphics.co.uk/freebies/hand-drawn-sketchy-icons-of-your-favorite-social-sites
下载;如果你决定使用其他图标,请相应地更改代码。
创建名片
首先,打开这本书附带的代码包中的nesting.html
副本。这包含我们创建基本 vCard 所需的标记。
接下来,我们需要添加一些样式使其看起来更美观。涉及几种样式,所以请获取这本书附带的代码下载文件的副本,并从存档中提取nesting.less
的副本。
将文件保存为nesting.html
。如果你在浏览器中预览结果,你会看到以下截图类似的内容:
详细检查过程
如果我们查看nesting.less
,你会注意到许多使用类似格式的样式。这些例子都是嵌套主题的变体,其中我们不是添加单个子选择器(从而重复代码),而是可以将相似的子选择器组合在一起并实现一个父选择器。
我们的第一个例子使用了标准的a
选择器,我们将:focus
、:hover
和:active
的样式规则组合在一起:
a {
&:focus { outline: thin dotted; }
&:hover { outline: 0 none; }
&:active { outline: 0 none; }
}
编译后会产生以下代码:
a:focus { outline: thin dotted; }
a:hover { outline: 0 none; }
a:active { outline: 0 none; }
注意
在这个例子中,我们只使用了a
来展示这个过程是如何工作的——实际上,这是一个你不会从如此简短的选择器名称中获得任何好处的例子;好处只有在使用较长的名称时才会显现。
我们的第二个例子稍微复杂一些——在这里,我们包括了一些标准的 CSS 样式,并混合了针对两个更深层次的额外子选择器的样式规则:
.social {
background-color: #e6e6e6; padding: 10px; width: 100%;
ul { text-align: right; }
ul li { display: inline-block; height: 48px; width: 48px; }
ul li a { display: inline-block; height: 100%; overflow: hidden; text-decoration: none; text-indent: 100%; white-space: nowrap; width: 100%; }
}
嵌套的关键在于仔细检查任何类或选择器,如果有重复;让我们看看在浏览器中将要显示的 CSS 样式,针对我们刚刚讨论的.social
代码块:
.social { background-color: #e6e6e6; padding: 10px; width: 100%; }
.social ul { text-align: right; }
.social ul li { display: inline-block; height: 48px; width: 48px; }
.social ul li a { display: inline-block; height: 100%; overflow: hidden; text-decoration: none; text-indent: 100%; white-space: nowrap; width: 100%; }
为了确定一个样式是否可以转换为使用嵌套,我们可以查看类似的选择器;嵌套只有在选择器使用公共 ID 时才会起作用。在这个例子中,.social
是公共选择器,因此它在我们的 Less 示例中被使用。
一个需要注意的关键点——乍一看,似乎可以使用.social ul
代替。这会起作用,但只能针对两个额外的子选择器(.social ul li
和.social ul li a
)。如果我们从这个级别开始,父.social
类将不能被包含,因为我们只能自上而下考虑哪些样式要嵌套,而不能自下而上。
注意
有一个一般规则是,用作分组 ID 的选择器或类不应超过两级深度;任何更多都被认为是坏习惯,并且应该真正重新审视!
让我们改变焦点,看看 Less 的另一个功能,即使用extend
选项继承和覆盖样式。
使用extend
继承和覆盖样式
到目前为止,我们使用 mixin 来帮助减少编写额外代码的需求,因为我们可以从我们的 Less 语句中轻松调用这些代码块,以产生期望的效果。
不幸的是,这仍然有其自身的缺点。假设我们创建了两个规则,这两个规则都调用相同的 mixin,并产生相同的结果(除了规则名称),那么 Less 将它们解释为两个不同的代码块,尽管它们都对两个不同的对象执行相同的样式。如果我们能合并这两个规则,使得只有一个代码块,但可以由任一规则调用,那会怎样呢?
嗯,我们可以使用 Less 中的extend
函数来实现。这是一个真正强大的函数,为了这个目的而引入的。让我们看看这个概念,看看它是如何工作的。
假设你有一个 mixin,比如这个简单的:
.stuff { color: red; }
.foo { .stuff; }
.bar { .stuff; }
如果我们使用类似 Crunch!的工具来编译它,那么它将显示如下:
.stuff { color: red; }
.foo { color: red; }
.bar { color: red; }
这工作得非常完美,但显示了上述的重复样式。为了消除这种重复,我们可以使用extend
关键字并重新编写代码如下:
.foo { color: red; }
.bar { &:extend(.foo); }
你可以立即看到输出的差异。我们不再像以前那样将每个规则拆分成两行,而是将规则合并到一个块中,但可以由任一类调用:
.foo, .bar { color: red; }
注意
值得阅读 Less 主站上关于extend
主题的文档——在使用代码中的函数时,你需要注意一些有趣的功能。你可以在lesscss.org/features/#extend-feature
查看文档。
选择是否使用extend
或 mixin 的规则是选择需要最少最终输出(或最适合你的)的技术。
使用extend
创建信息提示
为了了解extend
在实际中的工作方式,让我们来看一个小练习,创建一些包含消息以提醒用户操作结果的想象中的对话框。
在我们开始我们的示例之前,我们首先需要下载一些适合用于对话框的图标。我选择使用 Andy Gongea 创建的免费图标;为了练习的目的,我们将假设你正在使用这些图标。访问www.graphicrating.com/2012/06/14/koloria-free-icons-set/
下载图标。你需要提取info.png
、error.png
、warning.png
、help.png
和valid.png
图像,并将它们放入项目文件夹根目录下的img
文件夹中。
让我们开始编写代码!打开我们在第三章中创建的project.html
副本,即使用 Less 入门,然后修改以下代码中的<head>
部分:
<title>Demo: Extending</title>
<link rel="stylesheet/less" href="css/extend.less">
<script src="img/less.min.js"></script>
接下来,移除<body>
标签中的现有标记,并用以下内容替换:
<div class="info">Info message</div>
<div class="success">Successful operation message</div>
<div class="warning">Warning message</div>
<div class="error">Error message</div>
<div class="validation">
<li>First name is a required field</li>
<li>Last name is a required field</li>
<li>Email address has been typed incorrectly</li>
<li>Preferred language has not been selected</li>
</div>
将其保存为extend.html
。仅就其本身而言,如果我们现在预览它,它不会赢得任何风格奖项,所以让我们通过添加一些来修复它!在一个新文件中,添加以下样式:
body{ font-family: Arial, Helvetica, sans-serif; font-size: 13px; }
.demo { font-style: italic; }
.box { border: 1px solid #000; margin: 10px 0px; padding:15px 10px 15px 50px; background-repeat: no-repeat;
background-position: 10px center; width: 300px; padding-top: 15px; }
.info:extend(.box) { color: #00529B; background-color: #BDE5F8; background-image: url('../img/info.png'); }
.success:extend(.box) { color: #4F8A10; background-color: #DFF2BF; background-image:url('../img/valid.png'); }
.warning:extend(.box) { color: #9F6000; background-color: #FEEFB3; background-image: url('../img/warning.png'); }
.error:extend(.box) { color: #D8000C; background-color: #FFBABA; background-image: url('../img/error.png'); }
.validation:extend(.box) { width: 280px; padding-left: 70px; color: #D63301; background-color: #FFCCBA; background-image: url('../img/error.png'); }
将文件保存为css
子文件夹中的extend.less
;如果你已经配置了 Sublime Text 在保存时编译 Less 文件,那么它也会生成编译后的 CSS 等价文件。我们可以使用这个文件来比较文件中显示的结果和浏览器中显示的结果,当我们使用 DOM Inspector 如 Firebug 时。如果我们现在在浏览器中预览文件,我们应该看到以下截图:
虽然这是一个相对简单的例子,但花点时间研究代码,看看extend
函数是如何工作的,是值得的。
如果你使用 mixin,你经常会发现你必须在 mixin 中包含一个基类(在我们之前的例子中是.stuff
),这个基类包含你需要在调用类中继承的样式(在这个例子中是.foo
和.bar
)。
这将完美地工作,但会像我们之前看到的那样重复代码;相反,我们使用了extend
函数将现有的.box
类应用到我们用于对话框的每个类中,即.info
、.success
、.warning
、.error
和.validation
。
由于extend
是一个 Less 伪类,extend
函数的所有痕迹都将被删除,留下的将是编译后的样式。使用此函数的实际好处可以在使用 Firebug 时看到;我们不会看到很多重复的样式,而会看到样式整洁地合并在一起,它们执行相同的功能,剩余的样式则保留在适当的位置操作剩余的元素。
使用all
关键字进行扩展
一旦你开始在 Less 代码中使用extend
关键字,你可能会发现你想扩展嵌套的样式。
不幸的是,extend
只能根据extend
请求中给出的内容匹配选择器;它并不总是能够匹配父选择器下的子选择器,除非指定了子选择器。让我们通过一个例子来看看这意味着什么。
想象一下,你有一段嵌套的 Less 代码如下:
.module {
padding: 10px;
h3 { color: red; }
}
使用extend
将产生以下结果:
.news { &:extend(.module); }
h3
样式将不会被扩展,而将被编译为单独的样式:
.module, .news { padding: }
.module h3 { color: red; }
为了解决这个问题,我们可以使用下面的代码行中的all
关键字:
.news { &:extend(.module all); }
all
关键字将扩展所有内容以产生所需的效果:
.module, .news { padding: 10px; }
.module h3, .news h3 { color: red; }
其关键在于将其视为对原始选择器执行非破坏性的搜索和替换操作,以产生一个新的选择器。让我们通过修改之前的 extend
示例来使用 all
关键字来实际看看它。
首先,打开我们之前练习中创建的 extend.html
的副本,然后使用 <h3>
标签包围每个对话框文本消息,如高亮所示:
<div class="info"><h3>Info message</h3></div>
<div class="success"><h3>Successful operation message</h3></div>
<div class="warning"><h3>Warning message</h3></div>
<div class="error"><h3>Error message</h3></div>
<div class="validation">
<h3>
<li>First name is a required field</li>
<li>Last name is a required field</li>
<li>Email address has been typed incorrectly</li>
<li>Preferred language has not been selected</li>
</h3>
An example using <span class="demo">extend:(...all):</span>
<div class="rebase"><h3>Info message</h3></div>
将其保存为 extendall.html
。在 extend.less
的副本中,我们需要将 font-size
规则从 body
移动到 <h3>
,这样我们就可以稍后在代码中将其包含为一个嵌套规则。修改 body
的样式规则,然后立即在此规则下方添加一个新的 <h3>
规则,如下面的代码所示:
body { font-family: Arial, Helvetica, sans-serif; }
h3 { font-size: 12px; }
在验证代码块中,添加三条高亮显示的行;这将为我们之前添加到 HTML 代码中的 <h3>
标签设置样式:
.validation:extend(.box) { width: 280px; padding-left: 70px;
color: #D63301; background-color: #FFCCBA; background-image: url('../img/error.png');
h3 { font-size: 14px; }
}
我们现在可以利用 all
关键字;在 .validation
样式块下方立即添加以下代码:
.rebase:extend(.validation all) {}
.rebase {
color: #fff;
background-color: #9a0074;
background-image: url('../img/help.png');
}
将文件保存为 extendall.less
。如果我们在一个浏览器中预览结果,我们会看到新增的对话框出现在最后一个对话框下方,如下面的截图所示:
现在我们已经看到了它的实际应用,让我们花一点时间来考察它是如何工作的。
如我们所见,使用 all
属性与 extend
非常简单,但这确实意味着需要复制的样式应该尽可能接近期望的结果,以便使 extend
的使用变得有价值。
这并不意味着你不能添加额外的,或者实际上覆盖现有的样式,就像我们在这里所做的那样,但我们已经将它们保持在最小范围内。在这里,我们使用了 extend all
来复制 .validation
类并将其重命名为 .rebase
;这包括对 <h3>
标签的额外样式,如果没有使用 all
标签,这些样式将不会被包含。然后我们简单地覆盖了三种样式来更改使用的图片、background-color
和文本 color
,使其更加独特。
我们只是刚刚触及了使用 extend
可以做到的事情的表面——在我们改变焦点并转向查看命名空间之前,让我们花一点时间看看使用 extend
关键字的一些其他亮点:
-
extend
可以与伪类选择器一起使用,例如:hover
或:active
;可以使用多个extend
,并使用空格分隔。然而,如果只使用一个extend
,那么它必须是语句的最后一部分。 -
你可以在规则集中使用
&:extend
;这是一个将extend
添加到规则集中每个选择器的快捷方式。 -
extend
可以与嵌套选择器一起使用;只要调用的extend
可以与一个有效的 Less 规则匹配,它就会被扩展以使用新的类或选择器 ID。 -
默认情况下,
extend
将寻找精确匹配,例如,*.class
和.class
,这两个是等价的,但在使用extend
时不会被 Less 视为精确匹配。 -
如果你想要使用类型标识符(如
[title="identifier"]
)进行匹配,那么是否使用引号无关紧要;这些实际上是被忽略的。
extend
关键字是 Less 文章中的一个非常有用的工具,但如果使用不当可能会引起问题。非常值得阅读 Less 网站上的主要文档lesscss.org/features/#extend-feature
,以了解使用该函数的一些怪癖。
Less 中的命名空间
随着时间的推移和你的 CSS 样式表变得越来越大,你可能会发现自己会问自己一个问题:我能否将相似的样式分组,以便更容易找到?
当然,你总是可以剪切和粘贴相似的风格,但这是一个手动过程,对吧?如果两周后你需要添加一个新的样式,而这个样式与 1500 行左右的样式相似,会发生什么?当然,必须有一种更好的方法来做这件事——确实有。欢迎来到 Less 中的命名空间!
Less 中的命名空间将你分组相似样式的需求颠倒过来;它将你样式的所有构成块组合在一起,然后允许你在为网站上的新元素添加样式时选择和选择要使用的样式。当然,如果我们需要,我们可以创建多个命名空间——我们唯一的实际指南是每个命名空间应包含具有共同元素的样式;一个很好的例子是按钮,你将在我们即将进行的练习中看到。
让我们从打开project.html
的副本并修改如下代码所示的<head>
标签开始创建这些按钮:
<title>Demo: Namespaces</title>
<link rel="stylesheet/less" href="css/namespace.less">
<script src="img/less.min.js"></script>
接下来,移除<body>
标签中现有的标记,并用以下代码替换:
<input type="button" name="buy" value="Buy" class="redbutton">
<input type="button" name="clear" value="Pay by PayPal" class="purplebutton">
<input type="button" name="checkout" value="Pay by credit card" class="bluebutton">
将其保存为项目文件夹根目录下的namespace.html
。我们需要应用一些样式,所以请继续添加以下 Less 样式到一个新文件;我们将将其分解为几个部分,一点一点地讲解,因为有几个重要的概念需要考虑:
.background (@color1, @color2) {
background: -webkit-gradient( linear, left top, left bottom, color-stop(0.05, @color1), color-stop(1, @color2) );
background: -moz-linear-gradient( center top, @color1 5%, @color2 100% );
background-color: @color1;
border: 1px solid @color1;
}
我们在第四章中看到了类似的例子,使用变量、混合和函数;希望你能认出这是一个参数化混合。在这个例子中,我们使用它为每个按钮构建渐变;我们向它提供两个值,这两个值代表了渐变渐变过程中使用的颜色,如下面的代码所示:
#button() {
.base { border-radius: 6px; color: #fff; font-family: Arial;
font-size: 15px; font-weight: bold; font-style: normal; height: 32px; text-align: center; text-shadow: 1px 1px 0px #000; margin-left: 5px;
&:active { position: relative; top: 1px; }
}
注意
注意,这里使用的命名空间(如#button()
)可以由类或选择器 ID 创建;有关已识别行为的更多详细信息,请参阅github.com/less/less.js/issues/1205
。
接下来是我们 Less 样式中最重要的部分:命名空间样式的开头声明。它显示了我们将以哪个名称来分组我们的样式。我们使用了()
,因为我们不希望 Less 在编译我们的代码时输出混合以及编译后的 CSS:
.red {
.background(#cc1c28, #a01620);
box-shadow: inset 0px 1px 0px 0px #b61924;
&:hover { .background(#a01620, #cc1c28) }
}
.purple {
.background(#800080, #9a009a);
box-shadow: inset 0px 1px 0px 0px #670067;
&:hover { .background(#9a009a, #800080) }
}
.blue {
.background(#004771, #00578a);
box-shadow: inset 0px 1px 0px 0px #0067a4;
&:hover { .background(#00578a, #004771) }
}
}
这三段代码将调用.background(...)
mixin 来设置适当的渐变,具体取决于特定按钮当前设置的状态:
.redbutton { #button > .base; #button > .red; }
.purplebutton { #button > .base; #button > .purple; }
.bluebutton { #button > .base; #button > .blue; }
这才是真正的魔法所在。在这里,我们为三个按钮设置了要使用的样式,即红色、紫色和蓝色。在每个按钮样式中,我们选择调用#button
命名空间中的元素;如果创建了多个类似的命名空间,我们可以轻松地从每个命名空间中选择我们的样式,因为我们不仅限于使用一个命名空间。需要注意的是,当调用命名空间样式时,你必须使用我们示例中给出的格式。
好吧,理论就到这里。如果我们预览浏览器中的结果,我们应该期望看到类似以下内容:
一个简单易懂的例子,对吧?希望这能帮助你了解如何从样式分组中选择和选择你的样式,尤其是在项目使用大量类似元素和样式且可以从命名空间中受益时。
Less 中变量的懒加载
到目前为止,我们已经介绍了一些创建和控制样式应用的技术。然而,贯穿所有这些的一个关键主题是你需要注意的:作用域。
是的,那个丑陋的词,作用域!无论我们多么努力避免它,在使用 Less 时,我们都必须允许它;否则,它可能会在最意想不到的时刻回来咬我们。让我解释一下我的意思:正如我们将在即将到来的练习中看到的那样,我们可以在整个 Less 代码中重复使用我们的 mixin 或变量。
然而,Less 必须有一种方式来知道哪个实例是最新的;因此,它总是取我们代码中包含的任何变量或 mixin 的最后一个实例。如果你不小心,这可能会导致一些奇怪的效果。让我们通过一个快速练习来看看这在实际中意味着什么。
首先,打开我们之前在第三章中创建的project.html
副本,即使用 Less 入门,然后,按照以下代码修改<head>
标签:
<meta charset="utf-8">
<title>Demo: Scoping</title>
<link href='http://fonts.googleapis.com/css?family=Over+the+Rainbow' rel='stylesheet' type='text/css'>
<link rel="stylesheet/less" href="css/scope1.less">
接下来,删除现有的标记并替换为以下代码:
<div id ="container">
<div id="box1">This is box 1</div>
<div id="box2">This is box 2</div>
<div id="box3">This is box 3</div>
</div>
将其保存为scope.html
。最后,尽管这只是一个简单的例子,我们仍然需要添加一些样式;请将以下内容添加到一个新文件中,并将其保存为scope1.less
:
@boxcolor: green;
html { font-family: 'Over the Rainbow', cursive; font-weight: bold; font-size: 20px; }
div { width: 200px; height: 100px; padding: 3px; border-radius: 3px; float: left; position: absolute; }
#box1 { margin-left: 0; }
#box2 { margin-left: 225px; }
#box3 { margin-left: 450px; }
#container {
@boxcolor: red;
#box1 { background-color: @boxcolor; }
#box2 { background-color: @boxcolor; }
@boxcolor: orange;
#box3 { background-color: @boxcolor; }
}
在我们在浏览器中预览结果之前,问问自己这个问题:你期望在每个框中看到什么颜色?
不,我没有发疯;请跟我一起看这个!如果你期望在框1和2中看到红色,在框3中看到橙色,那么我很抱歉让你失望:
等等——它们三个都是橙色!这是真的;这与 Less 中的作用域概念有关。
如果你曾经花过时间编程,那么你可能会知道,如果一个变量在语句之前刚刚被设置,那么它的值将如何被该语句使用。Less 以类似的方式使用变量,但有一个重要的区别:它使用该变量赋值的最后一个已知实例,以确定要显示的值。
注意
Less 中的变量被合并到代码中——这相当于懒加载,因为变量的最后一个定义实例是使用的,覆盖了该变量的任何先前实例。
如果我们查看代码,我们可以清楚地看到在 box3
之前,@boxcolor
的最后一个实例被设置为颜色值。由于颜色设置为橙色,这就是我们代码中将使用的值。我们可以从 Crunch! 中编译后的样式截图的摘录中清楚地看到这一点,其中 #ffa500
是橙色:
值得注意的是,当我们使用变量时设置的范围,就像我们在这里做的那样。很容易因为使用一个(错误地)分配的变量而陷入困境,这会产生意外的结果!
确保使用正确值的唯一安全方法是分配单独的变量。如果我们修改之前示例中的 Less 样式,我们可以看到这个结果:
@boxcolor1: lightgreen;
html { font-family: 'Over the Rainbow', cursive; font-weight: bold; font-size: 20px; }
div { width: 200px; height: 100px; padding: 3px; border-radius: 3px; float: left; position: absolute; }
#box1 { margin-left: 0; }
#box2 { margin-left: 225px; }
#box3 { margin-left: 450px; }
#container {
@boxcolor2: red;
#box1 { background-color: @boxcolor1; }
#box2 { background-color: @boxcolor2; }
@boxcolor3: orange;
#box3 { background-color: @boxcolor3; }
}
将 Less 文件重新保存为 scope2.less
;别忘了更改 scope.html
中的标记!如果我们预览浏览器中的结果,我们可以清楚地看到它所带来的差异,其中使用了单独的变量:
注意
在整个演示过程中,我们使用了 box1
、box2
和 box3
作为选择器 ID——值得注意的是,这些不是语义名称;因此,它们不应该在生产环境中使用。由于我们只在演示环境中工作,以说明一个概念,因此使用这些名称的问题较小。
现在我们已经看到了使用单独变量的结果,我们也可以通过查看 Crunch! 的这个截图中的编译后的 CSS 来看到差异:
你注意到了差异吗?希望你能看到在使用变量时多么关键地需要小心,因为它们的使用范围如果不小心使用可能会产生一些奇怪的效果!让我们继续前进,因为我们需要查看一些我们已经使用但尚未深入研究的功能,即导入 Less 中的样式表。
小贴士
过度使用变量
要为网站中使用的颜色等值添加大量变量是非常容易的。这并不总是明智的做法;你应该考虑设置一个核心数量的变量,然后使用函数来计算应该使用的值。
将样式表导入 Less
呼吁!我们几乎完成了。我们确实在本章中涵盖了大量的内容!在我们结束本章并给出一些避免代码膨胀的提示之前,我们应该花点时间考虑一个有用的功能,我们虽然使用了它,但并没有详细探讨——这就是使用导入来管理我们的 Less 样式表。
在 Less 中导入是一个简单但有用的技巧,尤其是在管理大型样式表时。我们可以开始构建代码库,然后直接将其导入到任何未来的项目中。
这使得管理较小的文件变得容易得多,因为我们可以构建一个主文件,将每个子文件导入到一个主文件中;Less 只会编译直接从我们的主代码中引用的样式。例如,如果你的代码库文件超过 2,500 行,但只有 10 行的 mixin 被使用,那么 Less 只会将这 10 行包含在最终的编译结果中。
使用导入选项非常简单;你只需要在你的 Less 代码中添加以下语句即可:
@import (XXXXXXX) "foo.less";
这里 XXXXXXX
是以下任何一种选项之一:
选项: | 允许我们: |
---|---|
reference |
这使用 Less 文件,但不会输出它,除非在代码中引用。 |
inline |
这会将源文件包含在输出中,但不会对其进行处理,如果你需要导入不兼容 Less 的文件,但仍然需要将它们包含在编译的 CSS 文件中,这很有用。 |
less |
这会将文件视为 Less 文件,无论文件扩展名是什么。如果你需要所有 Less 文件都具有 .css 扩展名,但应该被视为 Less 文件而不是纯 CSS,那么这是理想的。 |
css |
这会将文件视为 CSS 文件,无论文件扩展名是什么。 |
once |
这只会包含该文件一次(这是默认行为);对于该文件的任何后续导入请求都将被忽略。 |
multiple |
这会将相同的 Less 文件多次包含。这与 Less 的默认行为相反。 |
你可以从 Less 主站点了解更多关于各种选项的信息,网址是 lesscss.org/features/#import-options
。
好的,让我们通过查看一些避免代码膨胀的重要提示和技巧来结束这一章。你所看到的一些内容来自于我们在本章中探索的功能,但花点时间总结一下到目前为止我们在书中涵盖的一些关键点是有用的。
避免代码膨胀
在设计网站时,每个设计师都应该非常重视的一个关键目标是确保他们尽可能避免代码膨胀,以便他们的最终作品能够良好运行并吸引观众。
为了帮助做到这一点,我们可以使用一些技巧来帮助减少代码膨胀。到目前为止,我们已经在本书中使用了一些,但现在似乎是一个回顾和巩固它们到一个有用的列表的好时机,你可以将其用于未来的项目:
-
旨在使用嵌套来创建更清晰的结构——这意味着你可以避免重新输入重复的选择器(例如在列表或菜单中使用
<ul>
),并且可以将代码组织得井井有条,因为相关项目被分组在一起。 -
创建变量以实现更快的维护——这些变量在其他编程语言(如 C#)中工作方式非常相似。我们可以在代码开始时设置一个变量的一个实例,然后在我们的整个代码中引用它;Less 会自动为你更新每个实例。但是要注意你创建了多少个变量,因为每个都需要宝贵的资源;更好的做法是创建一个核心组,并使用运算符动态计算出新的值。这样做的好处是,即使原始变量随后被更改,这些新值仍然可以继续工作。
-
使用 mixin 来创建我们可以在我们整个代码中引用的整个类。在大型网站上,这可以显著减少需要编写的代码量。如果你已经在使用 mixin,那么检查你的代码,看看它们是否不能被参数化;这增加了它们的灵活性,并允许你删除冗余的 mixin,因为它们可以通过调整其他 mixin 来提供。
-
采用迭代方法来开发你的 CSS,尤其是在使用 mixin 时。如果你使用与外部 Less 库中引入的 mixin 相似的 mixin,那么尝试设计出差异,这样你就可以移除自己的...
-
使用命名空间来选择和选择 mixin。这有助于将适用于类似元素(如按钮)的常见样式规则分组在一起;然后你可以选择和选择要使用的元素。尽量将每个命名空间中使用的选择器元素数量保持在最低限度;没有硬性规定,但一个好的经验法则是以下代码:
.redbutton { #base > .button #base > .redcolor }
如果你的代码在每个命名空间中使用多个选择器元素,那么你的代码可能不像它应该的那样高效...!
-
如果你正在使用命名空间,那么要注意你的 CSS 特定性,否则冲突的结果可能是嵌套太深或过度使用
!important
属性的征兆。如果你发现这种情况发生,那么你可能需要将你的命名空间分解成更小的组,这会使用更少的嵌套级别。 -
考虑使用类继承而不是选择器继承。如果你正在创建一个 mixin,稍后你会在你的选择器类中引用它,你可能发现你可以在 HTML 中简单地使用类继承。所以,作为一个例子,而不是在你的 Less 文件中使用以下内容:
.gradientBlack { ... } h3 { .gradientBlack; ... } .darkBox { .gradientBlack; ... } td.dark { .gradientBlack; ... }
我们可以通过在样式表中只定义一次
.gradientBlack
来消除其重复使用,然后在代码中直接引用它:<h3 class="gradientBlack"></h3> <div class="darkBox gradientBlack></div> <td class="dark gradientBlack"></td>
-
使用
extend
而不是 mixin 来减少代码膨胀;extend
足够聪明,可以合并使用相同规则的样式,正如我们在本章前面所看到的,而不是简单地为每个类似样式复制代码块。 -
如果您必须继续使用 mixin,那么请使用括号来隐藏 mixin 代码,这样只有调用代码会被编译,而额外的 mixin 则不会。
-
如果您有许多需要供应商前缀的 mixin,您可以使用此 mixin 通过简单地传递需要添加前缀的属性以及相应的值来处理它们,如下面的代码所示:
.vendorize(@property, @value) { -webkit-@{property}: @value; -moz-@{property}: @value; -ms-@{property}: @value; -o-@{property}: @value; @{property}: @value; }
注意,这并不是所有需要供应商前缀的属性所必需的;如果 CSS3 属性只需要一个或两个供应商前缀,您可能会发现创建一个简单的 mixin 来单独处理这些前缀更容易。
注意
值得注意的是,一些供应商前缀使用与我们所用的示例完全不同的格式——这里的 mixin 不适用于所有属性值,例如渐变,因此需要单独的 mixin。
希望其中有一些有用的技巧,您可以在项目中使用。所有这一切的关键是使用正确的函数组合,例如使用extends
而不是 mixin(或两者的混合),这有助于将您的代码保持最小并消除膨胀。
摘要
在本章中,我们介绍了一些概念,这些概念可以帮助进一步减少您需要编写的代码量——在进入下一章中 Less 的更多实际应用领域之前,让我们花点时间回顾一下。
我们从查看如何在 Less 中分组或嵌套样式开始;我们看到了这如何有助于视觉上排列样式,使其更容易管理,同时消除在引用子选择器(如构建菜单系统时使用的选择器)时重复样式的需要。
然后,我们转向 extend 函数,用于继承或覆盖现有样式,并介绍了它如何以与 mixin 类似的方式工作,同时合并相同的样式,以消除为相同样式编写单独代码块的需要。我们还探讨了使用all
关键字来帮助继承所有样式,尤其是那些单独使用 extend 无法访问的样式。
然后,我们介绍了如何使用命名空间来分组样式和引用一个或多个元素;这允许我们将常见元素视觉上分组,同时挑选和选择要使用的样式。一旦选择,我们就看到了 Less 如何将它们编译成有效的 CSS。
最后但同样重要的是,我们快速浏览了在 Less 中设置正确的作用域,以确保我们的变量具有正确的值。我们从示例中看到了如何容易地出错以及正确使用代码中的作用域的重要性。然后,我们结束了关于将 Less 文件导入 CSS 的查看,并基于我们在书中迄今为止看到的 Less 的一些关键区域提供了一些关于消除代码膨胀的提示和技巧。
在下一章中,我们将从理论转向,探讨将基于 CSS 的网站迁移到使用 Less 的一些实际方面。
第六章. 将您的网站迁移到 Less
因此,到现在为止,你希望已经花了一些时间使用 Less,并且认为这对你未来的项目可能非常有用,对吧?
问题在于你可能也会想到现有的项目,它们通过使用 Less 可以轻易受益,但你不确定如何将它们转换为使用 Less。没问题;在本章中,我将带你了解如何进行这种过渡到使用 Less 的一些技巧和窍门,而不会冒任何风险。
我们首先将审视我们需要问自己的问题类型,然后继续创建我们将用于开始转换的基本框架,通过一个将迷你网站转换为使用 Less 的详细示例。
转换的关键是记住,Less 毕竟只是 CSS 的超集——大部分工作都是关于识别那些可以轻松更改的部分以及可能需要更多工作的部分。在本章中,我们将涵盖以下主题:
-
低垂的果实——Less 转换的明显候选者
-
识别 CSS 中的模式
-
构建混入库
-
将预构建库作为转换过程的一部分使用
-
将 Less 与普通 CSS 混合
-
通过实际示例进行操作
你准备好开始转换你的 CSS 了吗?好的,让我们开始吧...
准备初次跳跃
因此,你已经阅读了有关使用 Less 的所有内容,并且渴望开始在您的一些较旧的项目中使用它。你已经开始在您的新网站上使用它,并且非常喜欢它使编写 CSS 变得多么容易...但是,你可能正在想:我如何将其纳入一个较旧的网站?
好吧,你来了对地方——只要记住这些提示,在较旧的网站上做出改变并不需要那么困难:
-
确保你已经安装了带有 Less 支持的 Firebug,如第二章中所述,构建 Less 开发工具包。相信我,这将使调试你的工作变得容易得多!
-
将你的现有 CSS 通过一个网站,如 W3C CSS 验证器(
jigsaw.w3.org/css-validator/validator
)进行验证。如果你还没有这样做,这将有助于发现任何错误,并在开始将其转换为 Less 之前确保你的代码正确验证。 -
尝试养成将 Less 转换分块进行,并且应该是一个迭代过程的心态——这减少了错过机会或在你代码中犯错误的风险;这在转换大型文件,如 WordPress 样式表时尤其重要!
-
不要忘记 Less 是 CSS 的超集——只要我们以逻辑方式完成转换过程。Less 仍然会编译尚未转换为 Less 等价的普通 CSS 代码。这意味着我们可以在转换过程中混合代码,直到所有样式都得到了适当的转换。
-
养成使用诸如
less2css.org
或lesstester.com
等网站的习惯。这些网站非常适合实验 Less 代码,以查看它将如何编译为有效的 CSS。
让我们将一些这些技巧付诸实践,并查看应该构成任何初始转换过程基础的初步步骤。
创建初始框架
一旦您决定转换为使用 Less,我们就可以采取一些步骤,这些步骤有助于初始转换过程,在我们开始编写 Less 代码之前。
让我们看看我们如何使这个过程更容易。为了本例的目的,我将假设您只有一个样式表,称为styles.css
,并且您正在开发环境中工作,在基于 HTML 的简单网站上工作,以便熟悉转换过程。
-
首先,将
sitestyles.css
文件重命名为.less
扩展名的sitestyles.less
。 -
在您的文本编辑器中的新文件中,添加以下内容:
@import "sitestyles.less";
-
将其保存为
styles.less
。在您的 HTML 代码中,将现有的链接sitestyles.css
更改为指向sitestyles.less
,使用以下链接:<link rel="stylesheet/less" href="css/styles.less"> <script src="img/less.min.js"></script>
使用 Crunch!或 Sublime Text(取决于您在第三章中设置的内容,使用 Less 入门)来编译新的styles.less
文件,以确认它是否生成有效的styles.css
文件。
注意
我们在我们的代码中直接引用了 Less 文件——这仅用于开发目的,不建议用于生产使用。
在这一点上,您可能会认为在styles.less
文件中只有一个语句听起来可能有些过度;这是有原因的:与 Less 一起工作的关键是建立 Less 文件的初始框架,以便我们首先证明它可以编译为有效的 CSS。一旦证明这一点,就只需为每个您想要包含的部分文件添加更多的@import
语句。在我们下次重新编译styles.less
时,Less 会将所有这些合并到一个文件中,正如我们将在下一节中看到的。
将 Less 与纯 CSS 混合
如果我们将 Less 与 CSS 混合以创建导入单个部分文件的框架,我们将获得一个额外的好处:我们不必一次性转换所有 Less 文件!相反,我们可以简单地将现有的 CSS 文件拆分成更小的部分,然后将它们导入到主 CSS 文件(此处为styles.less
)中——这使得转换过程更容易管理。
注意
部分是包含 Less 代码的单独文件——它们是帮助简化 Less 代码管理的手段,因为多个文件可以作为编译过程的一部分在一个样式表中导入。
然后,我们只需为每个需要导入的 Less 文件添加一个@import
语句,例如以下示例所示:
@import "sitestyles.less";
@import "fonts.css";
@import "css3.less";
@import "menu.less";
记住,无论 Less 文件有多大或正在导入多少部分,Less 在最终编译的 CSS 文件中只会导入被代码引用的样式。当我们还在开发 Less 文件时,我们可以轻松地在浏览器中动态编译它;一旦最终版本准备就绪,它就可以预先编译,生成的 CSS 文件可以导入我们的生产环境中。
寻找低垂的果实
现在我们已经建立了基本框架,是时候去“摘水果”了——不,我并不是字面意义上的摘水果,而是寻找那些可以轻松转换且几乎不需要努力的 CSS 语句。
每个项目的大小和范围都会有所不同,但总会有一些简单的转换我们可以进行,这些转换适用于任何项目:
-
可以进行的一个简单更改是引入颜色变量——一旦转换,我们可以使用运算符来计算新的值,例如将特定颜色亮度提高 25%。作为开始,我们可以创建一些变量,例如以下这些:
@color-light-orange: #ffa500; @color-gray-cyan: #6a7172; @color-gray-dark: #313131; @color-grayish-orange: #d7cec3;
我们可以在我们的样式中使用变量,而不是十六进制代码;它们将如下所示:
body {background: @color-gray-cyan; color: @color-gray-dark; } a { color: @color-light-orange; } h1, h2, h3, h4, h5, h6 { color: @color-gray-dark; }
注意
理想情况下,这里使用的名称应该反映它们被使用的上下文,例如
body-textcolor
或heading-textcolor
;我们在这里使用名称来展示它们如何替换现有的颜色,并且至少使颜色名称可读! -
在转换过程中,你可能想要考虑将转换后的代码移动到一个单独的 Less 部分,并使用我们之前介绍的过程导入它。虽然这允许你在 Less 和 CSS 样式之间保持区分,但也意味着如果我们正在转换现有的 CSS 样式,而转换后的 Less 代码没有在屏幕上显示,我们可能会错过机会。
-
如果我们使用包含供应商前缀的 CSS3 样式,我们可以将我们的代码转换为从外部预构建库导入混入(mixins),例如 LESS Hat 或 LESS Elements。这将减少我们需要编写的代码量——毕竟,如果有人已经构建了一个我们可以使用的合适的混入,为什么还要重新发明轮子呢?
-
我们可以做出的一个更进阶的更改是关于嵌套的使用——这将使我们的代码更容易阅读,因为更清楚子样式将如何影响其父元素。一个完美的例子是嵌入到页面头部
DIV
中的菜单系统:header .nav { margin-top: 100px; } header .nav li { margin-left: 10px; } header .nav li a { height: 30px; line-height: 10px; }
我们可以手动转换或使用网站,例如css2less.cc
;虽然这个网站并不完美,但它会在转换过程中给你一个良好的起点:
小贴士
在线 CSS 到 Less 转换器并不完美——例如,如果您的 CSS 文件包含大量随机选择器,它们可能难以生成高质量的代码;Less 在编译过程中也会重新组合 CSS 语句,这可能会破坏您的代码。这些网站应该被视为开发的一个起点;假设在初始转换后,手动花费时间对代码进行微调。
毫无疑问,我们还可以做出其他一些简单的改变——这完全取决于将要转换为使用 Less 的网站的大小和范围。再次强调,这里的关键点是转换应该是一个迭代的过程,如果你试图一次性完成网站的转换,那么你并不会给自己带来任何好处!
让我们稍微改变一下焦点,继续到过程的下一阶段——一旦你处理了简单的转换,就是时候问自己一系列问题,所有这些问题都属于在 CSS 中识别模式这一范畴。
在你的 CSS 中识别模式
在你的 CSS 中识别模式,就是问自己一个问题:我如何减少代码?
有许多种方法可以做到这一点;具体的过程将取决于要转换的网站的性质。尽管如此,你可以问自己一些一般性的问题,以帮助转换过程:
-
你的网站使用了任何 CSS3 样式吗?如果使用了,考虑使用预构建的 Less 库,我们可以在我们的 Less 样式表中导入它。
-
你的 CSS 代码中是否包含任何语句,例如链接到图像元素?如果包含,您可能希望考虑使用字符串变量和插值来更好地管理链接,尤其是如果它们需要在未来进行更新。
-
你的网站使用了多少变量?如果其中任何变量将用于定义颜色,那么考虑使用一些 Less 内置的函数或运算符来动态生成颜色,例如将颜色变亮 20%或向现有颜色添加值以创建一个新的颜色。
-
你在代码中看到相同的(或非常相似的)代码块有多频繁?只要稍加注意,是否可以将其修改为与其他代码相同?如果是这样,这将是一个非常适合转换为混入的候选者。我们能够改变多少代码实例,同时仍然保持相同的效果,我们就能够从使用混入中获得更多的价值。
虽然你可能会有更多的问题要问,因为每个网站都是不同的,但并非每个问题都适用。其中一个关键问题将涉及到创建混入(mixins)以及我们是否可以将它们分离到我们自己的库中以便将来使用。
使用预构建的混入库
如果我们创建了许多混入,我们可以将这些混入变成一个库。然而,这并不总是必要的;相反,我们总是可以寻找方法来重用从互联网上可下载的库中的混入。
为什么我们应该使用它们?这样做有两个很好的理由:
-
我们可以避免重造轮子的需要
-
我们不需要担心库的支持或更新——这将由作者处理,通常还会得到整个开源社区的协助
可用的库有很多——它们都可以使用我们之前已经看到的相同的@import
语句导入。我们将在本章末尾的实践示例中更详细地介绍如何使用此类库,但在此期间,以下是一些可用的库示例:
-
Animate.css (
github.com/daneden/animate.cs
) -
ClearLess (
github.com/clearleft/clearless
) -
CSS Effects (
adodson.com/css-effects/
) -
Cssowl (
cssowl.owl-stars.com/
) -
LESS Elements (
lesselements.com/
) -
LESS Hat (
lesshat.com/
) -
Oban (
oban.io/
) -
Preboot (
getpreboot.com/
)
在线将有更多可用资源;您可以在互联网上搜索以查看可用资源,您可能会找到更适合您需求的资源。我们将在本章后面的实践演示中使用 LESS Hat 库。
构建混入库
作为识别我们 CSS 中模式的一部分,我们可以识别出可以转换为混入的代码,我们可能会发现使用预构建的库,如 LESS Elements 或 LESS Hat,并不总是满足我们的需求。
这可能不是问题;可能是因为库的作者没有按照我们的期望创建混入,因为他试图满足另一个需求。如果现有的混入不可用,我们始终可以考虑创建自己的混入库作为部分,以便在未来的项目中使用。我们甚至可以考虑在 GitHub (www.github.com
)上托管混入,就像其他人所做的那样:
提示
有几个流行的代码共享平台可供选择,您可以尝试——两个很好的例子是 Google Code (code.google.com/
)和 Bitbucket (bitbucket.org/
)。
在为库创建混入时,技巧是提前几步考虑,并找出您如何转换相似的代码块,以便它们可以用一个或多个混入来替换。
如果你发现代码可以转换为 mixin,那么思考这些 mixin 应该如何编写是值得的。Less 的一个关键原则是 DRY(不要重复自己)——你可能会发现自己编写了许多可以重用的 mixin。如果仔细考虑任何可以进行的调整,这些 mixin 的实用性将会增加,这样其他 CSS 代码块就可以通过 Less 调用你创建的 mixin 来替换。
一旦你的库创建完成,你就可以在 GitHub 上托管它——这样做有几个很好的理由:
-
在社区中有一个现成的群体,他们可以帮助解决问题或支持这个库
-
这是一种向他人表示感谢的好方法,因为你可能已经使用了他们的工作
-
任何使用你的 mixin 库的人都可以帮助你提出对 mixin 的改进建议
创建自己的库并将其在线上发布,将给你带来巨大的满足感,因为你能够为开源运动做出贡献——毕竟,我们今天所达到的成就,离不开那些花费数小时创建库(如 Less)的人们的努力!
现在,让我们将注意力转向使用我们刚刚提到的这些预构建库之一——我们将通过实际例子来看看如何使用 LESS Hat。
通过实际例子进行操作
到目前为止,我们已经查看了一系列你可以用来将网站转换为使用 Less 的技巧和窍门——虽然有一些有用的技巧,但我认为你也会同意,看到转换过程在实际中发生要更好!考虑到这一点,让我们看看一个简单的例子,以我们在第四章中创建的 CSS 样式为例,使用变量、mixin 和函数,这是一个单页网站。
在我们开始做出更改之前,让我们看看为该页面创建的编译后的 CSS,以及页面的截图:
介绍 CSS
现在我们已经看到了将要改造以使用 Less 的页面的截图,让我们来看看我们需要转换的 CSS 代码。使用 Crunch!生成的编译后的 CSS 如下——这本书附带的代码下载中包含了这个副本,作为conversion.css
。我们还将包括对social.css
中样式的一点点修改,并将其包含在conversion.css
中。这将产生相同的结果,但修改它的原因将在下一节中变得明显:
#social { width: 175px; height: 60px; background-image: url('../img/sprites.png'); float: right;}
初看,这应该看起来像一张普通的样式表,希望它使用了一些在任何一个网站项目中都可能用到的相当常见的样式属性:
你可能正在想,这样一个简单的例子,我们在这里能做些什么,对吧?
确定需要做出的更改
错误!将转换到使用 Less 不应该总是关于你的样式表的大小,而应该是进入使用 Less 将使代码管理更容易的心态。将转换到使用 Less 应该是一个迭代的过程,只有当所有原始 CSS 都已转换并且 Less 正在你的网站上使用时,这个过程才会停止。
为了证明这一点,让我们看一下代码,并突出显示一些可以转换的区域。样式表是一个简单的例子,但它足以说明你可以用来将 CSS 文件转换为 Less 等价物的过程。
-
你注意到使用
#leftmargin
的三个样式规则了吗?这是一个使用嵌套的完美机会——我们可以避免重复规则名称,并且可以以更合理的方式分组样式。 -
我们使用了
#content
的box-sizing
属性,但没有包含所有供应商前缀。这是一个很好的理由去查看网上可用的许多 mixin 库,看看其中是否包含一个合适的 mixin 我们可以使用。这避免了重新发明轮子的需要——如果合适,我们可以简单地链接到 mixin 并传递给它值。导入预构建的 mixin 也会处理操作所需的任何供应商前缀。 -
与使用难以转换为有意义的十六进制值的颜色值相比,我们可以创建变量并将值分配给它们。名称可以设置为描述所设置的颜色的值。如果需要更新,那么只需要一个更新,因为 Less 会自动处理所有其他实例的更改。
-
在
div
和#title
中,我们包含了font-family
属性——虽然这在正常 CSS 中可以完美工作,但我们可以使用相同的变量过程并为每个font-family
属性创建有意义的名称。这使得它们在将来需要更改时更容易更新。 -
在
#leftmargin
和#content
中,你可能已经注意到了这里的一个机会——我们重复使用相同的代码(尽管值略有不同)来创建我们的列。然而,有一个问题:注意#content
在样式规则中额外有padding: 10px
?在这种情况下,这不是问题——我们可以在#leftmargin
中添加这个样式,而不会产生明显的负面影响。记住,关键在于先进行初始更改,然后查看我们可以更改什么,这样我们就可以向 mixin 添加更多内容,使其更有用。 -
我们可以做出的更高级的更改是,将使用
data-uri
来导入我们的 CSS 中的社交网络图片,以节省服务器请求和带宽使用。我们在第四章的原始示例中使用了它,使用变量、混入和函数——它对于小图像(如我们的示例)将完美工作,但对于较大的图像或那些在网站上未重复使用的图像则不太有用。
注意
关于什么可以定义为“小”图像并没有硬性规定——我在这个示例中使用的图像重量为 9 KB。这会稍微取决于浏览器中的任何data-uri
限制;例如,IE8 的限制为 32 KB。这完全关乎仔细选择——如信用卡标志这样的小图像将完美无缺,但一张大图片显然就不合适了!
这些只是我们可以用来将此样式表转换为使用 Less 的一些概念。转换过程的关键不在于大小,而在于重新设计代码以使其更容易维护,并移除其他人已经创建且你可以导入到自己的项目中的代码的重复部分。一旦你开始转换代码,你将看到其他转换的机会——这完全是一个熟能生巧的例子!
进行更改
既然我们已经看到了可以做出的更改,让我们开始实施一些这些更改,从创建我们的 Less 框架文件开始。首先,将conversion.css
文件重命名为conversion.less
。接下来,在你的文本编辑器中的新文件中添加以下行:
@import "conversion.less";
将文件保存为styles.less
——这设置了我们的框架,以便我们可以转换我们的代码。如果你使用了 Sublime Text 或 Crunch!,那么你将发现已创建了一个styles.css
文件——它包含从conversion.less
编译的代码副本。以这种方式设置框架意味着我们可以在未来添加更多的@import
语句;这些导入文件的 内容将在styles.less
文件重新编译时自动包含到最终文章中。
使用 CSS3 混入
接下来,让我们看看我们使用的 CSS3 样式——我们可以将其转换为使用预构建的混入库。为了这个练习的目的,我们将使用可从lesshat.madebysource.com/
获取的 LESS Hat 库。点击下载 LESS Hat按钮——在撰写本书时,最新版本是 2.0.15。
我们需要提取lesshat.less
文件,该文件位于build
子文件夹中——将其复制到项目文件夹中的css
子文件夹。切换回文本编辑器中的conversion.less
文件,然后在开头添加以下行:
@import "lesshat.less";
现在,这将导入我们需要从 LESS Hat 库中使用的任何混入(mixins)。
注意
我们不能在styles.less
文件中包含@import
语句用于 LESS Hat——这将在conversion.less
中导致编译错误,因为它在编译代码时找不到它需要使用的源混入。
现在我们已经添加了 LESS Hat 库,我们可以开始调整我们的代码以使用这个库中的混入;有几个地方我们更改了代码以使用混入,如下所示:
#leftmargin { .box-sizing(padding-box); border-right: 1px solid #CCCCCC; float: left; height: 575px; width: 306px; }
#content { .box-sizing(padding-box); float: left; height: 575px; padding: 10px; width: 494px; }
#container { border: 1px solid #000000; .border-radius(4px);
.box-shadow(4px 4px 0 rgba(0, 0, 0, 0.5)); margin: 5% auto; width: 800px; }
在这个例子中,我们只能在三个地方使用 LESS Hat。尽管这个数量有限,但我们不应该忘记,这更多不是关于我们可以使用外部混入库的实例数量,而是关于不重复造轮子,以及使用外部库意味着我们做更少的工作,前提是有一个合适的库可供使用。
为字体创建变量
让我们改变我们的焦点,看看在将代码转换为使用 Less 时我们可以使用另一个概念:使用变量来帮助维护值,例如字体。
在我们的代码中,有几个地方使用了字体。在正常的 CSS 中更新这些可能会很麻烦,所以让我们创建一些变量,我们可以使用这些变量来自动更新我们的 Less 代码。创建变量意味着我们只需要在代码的开始处更新一个值。Less 将自动处理这些变量其他实例的更新。
在conversion.less
的一个副本中,在@import
语句下面立即添加以下行:
@import "lesshat.less";
@KiteOne: ~"'Kite One', arial, sans-serif";
仔细观察的你们会注意到,我们增加了一个变量——与本书前面提到的变量相比,唯一的区别是这个变量是封装的。我们使用波浪号符号来告诉 Less 在编译我们的代码时,要精确地按照显示的样式来复制这个变量。这意味着我们不再需要使用长句,现在我们可以简单地使用@KiteOne
作为值:
div { font-family: @KiteOne; margin-bottom: 5px; margin-top: 5px; padding: 5px; }
在这种情况下,我们只需要更改一条规则。在一个更大的样式表中,这种做法的好处将更加明显,因为它消除了在更新样式时手动更改每个实例的需求。
注意
我们将在第七章中详细介绍如何使用 Less 来操作字体,使用 Less 操作字体。
为颜色创建变量
我们还在代码中使用了几个颜色——其中一个应该是白色(#fff
),但另一个则不太容易识别为浅灰色。让我们使用相同的过程为这些颜色创建两个新变量,并为黑色创建一个变量:
@KiteOne: "'Kite One', arial, sans-serif";
@lightgray: #ccc;
@white: #fff;
@black: #000;
我们现在可以像下面这样修改我们的 Less 代码以使用这些变量,这将使代码更易于阅读:
#container { border: 1px solid @black; .border-radius(4px); }
#title { color: @white; font-family: @KiteOne; font-size: 32px; font-weight: 400; padding-left: 100px; padding-top: 30px; position: absolute; }
#leftmargin { .box-sizing(padding-box); border-right: 1px solid @lightgray; float: left; height: 575px; width: 306px; }
#footer { border-top: 1px solid @lightgray; clear: both; font-size: 12px; height: 65px; }
这将使代码更容易阅读,但也意味着如果我们需要更改值,我们只需要在开始时更改一次——Less 将自动处理所有其他实例的更新。
转换为使用嵌套
我们接下来的更改更为显著;它涉及到代码中#leftmargin
样式规则的四个实例。我们不需要手动编写每个规则,可以通过使用 Less 的嵌套功能将它们组合在一起;这使得它们更容易阅读,因为它们遵循更合理的结构。
在conversion.less
的副本中,删除四个#leftmargin
行,并用以下内容替换:
#leftmargin {
.box-sizing(padding-box);
border-right: 1px solid @lightgray;
float: left; height: 575px; width: 306px;
li { list-style: none outside none; }
a {
text-decoration: none;
&:hover { text-decoration: underline; }
}
}
这将使我们的代码更容易阅读,并避免在编写规则时重复元素名称的需要。注意我们如何使用&符号为:hover
——&符号告诉 Less 将:hover
视为伪选择器,Less 将编译为#leftmargin a:hover
。
小贴士
如示例所示,使用&符号(ampersands)不仅限于伪选择器;它可以用来表示代码中使用的父选择器或类——有关更多详细信息,请参阅lesscss.org/features/#parent-selectors-feature
。
引入我们自己的混合
我们最后的更改与列大小有关——如果你仔细阅读代码,你将注意到至少有两个地方我们有几乎相同的代码:#leftmargin
和#content
。我们可以将四个样式属性移动到一个单独的参数化混合中,如所示——将此内容添加到本章前面创建的变量下面:
.columnsize( @height, @width) { float: left; height: @height;
width: @width; padding: 10px; }
完成后,我们可以相应地更改我们的样式规则:
#leftmargin { .box-sizing(padding-box); border-right: 1px solid @lightgray; .columnsize(575px, 306px); ...}
#content { .box-sizing(padding-box); .columnsize(575px, 494px); }
这是一个简单的例子,说明我们可以通过一点细心,创建自己的混合来减少代码中的重复。虽然它可能不会减少我们代码中的行数,但它将帮助使代码更易于阅读,并在需要更改通过混合传递的值时更容易修改。
在这个阶段,我们已经将原始代码转换为使用 Less。如果一切顺利,我们应该得到可以编译成有效 CSS 的代码;如果你查看本书附带的代码下载,可以看到conversion.less
的副本,并比较你的版本。
我们可以通过更改第四章中产生的 HTML 代码副本来测试转换过程的成功,使用变量、混合和函数。打开functions2.html
的副本,然后寻找以下突出显示的行:
<title>Demo: Functions</title>
<link href='http://fonts.googleapis.com/css?family=Kite+One' rel='stylesheet' type='text/css'>
<link rel="stylesheet/less" href="css/functions.less">
<link rel="stylesheet" type="text/less" href="css/social.less">
<script src="img/less.min.js"></script>
</head>
按照所示进行更改;然后,将文件保存为conversion.html
:
<link href='http://fonts.googleapis.com/css?family=Kite+One' rel='stylesheet' type='text/css'>
<link rel="stylesheet/less" href="css/styles.less">
<script src="img/less.min.js"></script>
如果你在一个浏览器中预览结果,不要期望看到任何对整体页面的真正变化,除了添加的一小部分额外填充,这使左侧导航略微下移。希望这能表明,通过一些细心和思考,我们可以产生相同的结果,同时更好地管理我们的代码!
将图像导入样式表——一个额外的好处
在我们完成更改之前,我想加入一个小奖励;如果我们回顾一下我们可以做出的更改列表,我们注意到一个可以做出的微小更改,这与我们页面页脚中使用的社交媒体图像有关。
这个 CSS 由我们 Less 文件中的以下行控制:
#social { width: 175px; height: 60px; background-image: url('../img/sprites.png'); float: right; }
这将作为单独的文件引入图像,这意味着对服务器的额外请求。在一个小型网站上,这不会成为问题,但在一个大型网站上,这可能会使网站带宽需求增加,这将成为一个问题。
相反,我们可以使用 Less 的一个函数,data-uri
,这在第四章中有所介绍,即 使用变量、混合和函数,当我们创建我们页面的原始版本时。这对于小图像来说非常理想,尤其是那些在整个网站上重复出现的图像;这将它们转换为可以包含在我们的 CSS 中的 base64 语句,从而消除了需要从服务器请求图像的需要。
在 conversion.less
中,查找以下这一行:
#social { width: 175px; height: 60px; background-image: url('../img/sprites.png'); float: right; }
如果我们想使用 data-uri
,我们将像下面这样更改 background-image
属性:
#social { width: 175px; height: 60px; background-image: data-uri('../img/sprites.png'); float: right; }
这意味着虽然我们可能在 CSS 中有几百行代码,但我们已经减少了从服务器请求图像的需求。虽然这个过程应该谨慎使用——它只应该用于小图像,这些图像可能在整个网站上重复出现。这是一个有用的技巧,可以节省对服务器的请求,只要谨慎使用!
查看完成的文章
现在我们已经更改了转换后的 CSS 文件,让我们看看最终结果。为了比较,打开书中附带的代码下载中的 conversion.less
的副本,看看你在做出更改方面做得如何:
希望你能看到我们所做的部分更改——请注意,我们并不一定减少了所写的行数,但我们已经使代码在未来需要更改时更容易更新。诚然,在这个小型 Less 文件中,我们可能看不到使用 Less 的全部好处;但在一个较大的文件中,当从 CSS 转换为使用 Less 时,好处将变得明显。
摘要
在 Less 中,最难理解的概念之一是如何将现有网站转换为使用 Less。虽然有一些简单(或者可能更复杂,取决于你的看法)的问题我们可以回答,但转换一个网站可能需要一定程度的技能,以确保我们在转换过程中充分利用 Less。
在本章中,我们看到了一些问题和技巧,我们可以使用它们来开始转换过程。我们首先查看如何为转换过程的初步跳跃做准备,然后是任何人在考虑如何转换他们的 CSS 代码之前应该采取的初步步骤。我们看到了如何轻松地将代码拆分为单独的部分,这些部分可以导入到一个 Less 将编译为有效 CSS 的主文件中。
我们将 Less 代码转换为 CSS 代码的初步步骤,始于寻找低垂的果实,即快速且容易的改变。我们看到了如何使用诸如css2less.cc
之类的网站,我们可以轻松地开始转换代码;指出这些网站并不完美,但可以作为转换代码的良好基础。接下来,我们探讨了如何识别我们的 CSS 代码中的模式——我们检查了在过程中应该提出的一些问题。指出每个网站都会有所不同;因此,需要提出不同的问题。尽管如此,仍有一些基本问题适用于任何网站。
我们首先了解了如何在转换过程中使用预构建的 mixin 库,并介绍了一些可以在我们的项目中使用的示例——这是一种将他人创建的 mixin 引入的好方法,这将有助于减少创建我们样式表所需的工作量。然后,我们讨论了在现有的在线 mixin 库不能满足我们的需求时,可能需要创建我们自己的 mixin 库。
我们以一个详细的实际例子结束了这一章,展示了如何将现有的网站转换为使用 Less——我们使用了在第四章中创建的单个网页,使用变量、混入和函数,作为证明无论网站有多大,大多数网站都将从转换为使用 Less 中受益的例子。我们探讨了如何通过仔细检查代码的基本原则,一次检查一个代码块,并使用本章前面概述的技术,轻松地应用一些简单的转换。其中之一是我们对所使用的字体进行的一个简单更改——我们将在下一章进一步探讨这一点。
第七章。使用 Less 操作字体
我们探讨了如何使用 Less 的各种元素,创建了一个基本的页面来使用 Less,并介绍了如何将网站迁移到使用 Less……那么接下来是什么?
嗯,是的,处理文本或更具体地说,字体!
在任何网站上,内容都是王——实现正确影响的一部分是仔细选择应在您的网站上使用的字体。如果我们正在设计一个新闻网站,我们不会使用基于脚本的字体,因为文本应该是清晰易读的。然而,对于代表裁缝店出售的连衣裙的流动线条,脚本字体将是完美的。
这一切都关乎选择正确的样式;Less 完美地帮助我们管理页面中决定使用的任何字体的样式、颜色和大小。在本章中,您将看到如何使用一些简单的原则,让 Less 轻松管理字体。我们将涵盖以下主题:
-
创建字体混合
-
使用变量动态确定大小
-
使用预构建库
-
支持 Less 中的
@media
和@font-face
你准备好享受字体带来的乐趣了吗?让我们开始吧!
创建简单的字体混合
处理字体的关键是先从简单开始,然后逐步构建——没有比创建一个简单的混合来管理如字体名称这样的属性更好的起点了。让我们创建一个简单的例子,看看它是如何发挥作用的;以下是我们的混合将生成的内容:
好吧,让我们开始创建我们的混合;我们将从为我们的演示准备标记开始:
-
打开我们在第三章中创建的
project.html
文件副本,然后按照以下方式修改它:<title>Demo: Creating simple font mixins</title> <link href='http://fonts.googleapis.com/css?family=Kite+One' rel='stylesheet' type='text/css'> <link rel="stylesheet/less" href="css/basicfonts.less"> <script src="img/less.min.js"></script>
-
接下来,将以下标记添加到
<body>
部分:<h1>H1 - The cat sat on the mat</h1> <h2>H2 - The cat sat on the mat</h2> <h3>H3 - The cat sat on the mat</h3> <h4>H4 - The cat sat on the mat</h4> <h5>H5 - The cat sat on the mat</h5> <h6>H6 - The cat sat on the mat</h6>
-
将文件保存为
basicfonts.html
。在另一个文件中,添加以下 Less 样式:.fontfamily() { font-family: 'Kite One', Arial, sans-serif; } h1 { .fontfamily; color: #808080; } h2 { .fontfamily; color: #ff0000; } h3 { .fontfamily; color: #008000; } h4 { .fontfamily; color: #ffa500; } h5 { .fontfamily; color: #800080; } h6 { .fontfamily; color: #000000; }
-
将其保存为
basicfonts.less
。如果您在浏览器中预览结果,您将看到六个语句以递减的字体大小出现。
那么,让我们花点时间考虑一下这里发生了什么:我们创建了一个简单的混合,将.fontfamily
替换为'Kite One', Arial, sans-serif;
作为页面语句的字体族。一旦 Less 文件被编译,每个H
样式都将使用 Kite One 作为基本字体(以各种大小),如果 Kite One 不可用,则回退到使用 Arial 或 sans-serif。
扩展混合
在前面的例子中,我们可以在这里停止——毕竟,我们创建的混合工作得很好。然而,这并不是我们能做的最好的;如果我们在整个代码中创建类似的混合,那么如果字体名称需要更改,确保所有混合都更新将很快变得非常困难。
相反,我们可以进行一个简单的更改并使用变量名称。为了了解这意味着什么,打开basicfonts.less
并在开头添加这两行:
@font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif;
.fontfamily() { font-family: @font-family-sans-serif }
h1 { .fontfamily; color: #808080; }
你可能会问,为什么要进行这种改动?答案很简单:这减少了代码需要更新的实例数量。如果你更改了作为@font-family-sans-serif
变量一部分引用的字体,那么 Less 会自动处理代码的更新——这意味着又少了一项工作要做!在这里,我们只需要更改一个实例;如果我们的代码中有许多实例,那么在编译我们的代码时,Less 会自动更新它们。
让我们继续前进,把注意力转向更改我们使用的字体大小——毕竟,如果所有东西都是同一大小,那就太无聊了,对吧?
使用 Less 中的@font-face
在网页中使用字体的一个缺点是,它们必须存在于你的最终用户个人电脑或笔记本电脑上。自然地,随着市场上现在可用的 PC、笔记本电脑和移动设备的混合,几乎不可能保证字体存在!
我说不可能;我们可以在 PC 或笔记本电脑上使用一些字体,例如 Arial、Times New Roman 或 Verdana;它们不是坏字体,但它们被过度使用,并不特别。当然,我们可以使用外部服务,例如 Google Fonts——就像我们在本章早些时候的创建简单的字体混合部分所做的那样。
然而,我们可以通过使用@font-face
将任何字体嵌入到我们的页面中做得更好。我说的是任何字体,但该字体的许可证必须允许在页面中嵌入。幸运的是,如果我们使用像 Font Squirrel(我们将在下一个练习中使用)这样的网站,我们可以在选择字体时轻松检查并消除任何不符合这一标准的字体。
谈话到此为止;让我们把注意力转向使用@font-face
,这样我们就可以看到它是如何工作的。我们将在一个非常简单的演示中使用它;虽然它可能不会展示很多,但它完美地说明了如何使用 Less 与@font-face
一起使用。
下载字体文件
在我们开始编写代码之前,我们需要下载一个合适的字体——毕竟,使用 Arial 或 Times New Roman 这样的字体无法使演示公正!请执行以下步骤:
-
对于这个演示,我们将从 Font Squirrel 网站(
www.fontsquirrel.com
)使用一个字体。让我们首先浏览到 Font Squirrel 网站,下载 PT Sans 字体,我们将在我们的演示中使用它。我们可以从www.fontsquirrel.com/fonts/PT-Sans
下载它。在这里,我们还可以检查许可证的详细信息,并查看屏幕上显示的字体的样本。 -
点击Webfont Kit标签,然后点击Download @Font-Face Kit按钮下载字体;将压缩归档保存到项目文件夹中,命名为
PT-Sans-fontfacekit.zip
。 -
现在,打开
ptsans_regular_macroman
文件夹,从中提取四个 Webfont 文件,并将它们放置在我们项目文件夹中的fonts
子文件夹中。
我们将在本章后面的处理不同权重部分重新访问这个字体。
将字体嵌入到我们的演示中
好的,现在我们已经有了字体文件,让我们开始编写代码:
-
打开你选择的编辑器——我假设这个练习的目的使用的是 Sublime Text。
-
打开我们在本书开头创建的
projects.html
副本,然后按以下方式修改它:<meta charset="utf-8"> <title>Demo: Using @font-face</title> <link rel="stylesheet/less" href="css/fontface.less"> <script src="img/less.min.js"></script>
-
在
<body>
部分添加以下标记:<h1>H1 - The cat sat on the mat</h1> <h2>H2 - The cat sat on the mat</h2> <h3>H3 - The cat sat on the mat</h3> <h4>H4 - The cat sat on the mat</h4> <h5>H5 - The cat sat on the mat</h5> <h6>H6 - The cat sat on the mat</h6>
-
将其保存为
fontface.html
。正如我们清楚地看到的,这是一个非常简单的演示——足以展示如何使用@font-face
——它从未打算变得复杂!没有所有重要的样式,它就不完整;所以,请继续添加以下内容到一个新文件,并将其保存为fontface.less
:.font-face(@family, @filename: @family) { font-family: "@{family}"; @font-face { font-family: "@{family}"; @file: "../fonts/@{filename}"; src: url("@{file}.eot"); src: url("@{file}.eot?#iefix") format("eot"), url("@{file}.woff") format("woff"), url("@{file}.ttf") format("truetype"), url("@{file}.svg#webfont") format("svg"); } } @name: PTS55F-webfont; @family: "PT Sans"; h1 { .font-face(@family, @name); color: #808080; } h2 { .font-face(@family, @name); color: #ff0000; } h3 { .font-face(@family, @name); color: #008000; } h4 { .font-face(@family, @name); color: #ffa500; } h5 { .font-face(@family, @name); color: #800080; } h6 { .font-face(@family, @name); color: #000000; }
-
如果你在浏览器中预览结果,你可以期待看到类似以下截图的内容:
这是一种简单的方法来展示如何使用 Less 中的@font-face
;在这里,我们使用 PT Sans 字体显示了一个简单的句子,并为每个字体大小使用了不同的颜色。在每次调用.font-face
混合时,我们传递字体名称和要使用的颜色;混合根据所使用的浏览器选择最合适的字体格式:
字体格式 | 支持该格式的浏览器 |
---|---|
TTF |
这在大多数浏览器中工作,除了 IE 和 iPhone |
EOT |
这是一种仅适用于 IE 的专有字体格式——目前不是 W3C 推荐的标准 |
WOFF |
这是一个压缩的、新兴的标准——目前除 Opera Mini 外,大多数浏览器都支持 |
SVG |
仅适用于 iPhone/iPad |
如果你只能访问一种格式,那么 WOFF 是最好的选择;否则,尽可能包含所有四种格式的字体。
使用预构建库处理字体
在上一个示例中,我们使用了@font-face
将自定义字体嵌入到我们的页面中;这消除了对我们可以使用字体的任何限制,因为我们可以下载并使用适合的授权字体。这很好,但我们还能做得更好——Less 的一个原则是 DRY(Don't Repeat Yourself),我们在本书中较早地介绍了这个原则;这是一个完美的机会来实践我们所宣扬的!
我们不需要创建新的混合来处理@font-face
,我们可以使用预构建库来为我们处理@font-face
混合。这意味着我们可以删除大量代码,因为我们将从预构建库中使用混合——让我们看看它是如何工作的:
-
打开
fontface.html
的副本,并按以下方式更改到 Less 文件的链接:<title>Demo: Using @font-face</title> <link rel="stylesheet/less" href="css/fontface-ml.less"> <script src="img/less.min.js"></script> </head>
-
将其保存为
fontface-ml.html
。在新的文件中,添加以下代码:@import "lesshat.less"; @my-font-name: 'pt_sansregular'; @fontfile: '../fonts/PTS55F-webfont'; @font-face { .font-face(@my-font-name, @fontfile); } .myfont() { font-family: @my-font-name, arial; } h1 { .myfont; color: #808080; } h2 { .myfont; color: #ff0000; } h3 { .myfont; color: #008000; } h4 { .myfont; color: #ffa500; } h5 { .myfont; color: #800080; } h6 { .myfont; color: #000000; }
-
这将是我们的 Less 样式表——请将其保存为
fontface-ml.less
。
如果你在浏览器中预览结果,与上一个练习的结果相比,你应该看到几乎或没有差异。那么,有什么不同呢?我听到你问:为什么使用预构建库?
答案很简单:你忘记了其中一个关键原则——当使用 Less 时,不管库有多大,Less 只会包含在编译过程中直接引用在代码中的样式。
如果你浏览一下库,你会在大约第 1362
行看到 @font-face
混合器:
.font-face(@fontname, @fontfile, @fontweight: normal, @fontstyle: normal) {
font-family: "@{fontname}";
src: url("@{fontfile}.eot");
src: url("@{fontfile}.eot?#iefix") format("embedded-opentype"),
url("@{fontfile}.woff") format("woff"),
url("@{fontfile}.ttf") format("truetype"),
url("@{fontfile}.svg#@{fontname}") format("svg");
font-weight: @fontweight;
font-style: @fontstyle;
}
在这个例子中,我们只使用了这些内容——我们可以使用 DOM 检查器,例如 Firebug,来查看编译后的 CSS 样式,如本截图所示:
在我们这样的小例子中,好处可能并不立即明显——一旦扩展到更大的网站,这将显著减少你需要编写的代码量。在这种情况下使用预构建库的关键在于选择正确的库——我们能够从预构建库中使用的越多,就越好!
好的,我们现在已经放置了正确的字体;我们需要确保它们可以在我们的页面上适当地调整大小。幸运的是,Less 包含一些有用的功能,可以帮助我们轻松地设置字体大小——让我们看看我们如何使用库来帮助我们设置页面上的字体大小。
使用变量计算尺寸
现在我们已经选择了想要使用的字体,我们需要确保我们能够为特定场合设置正确的尺寸;幸运的是,Less 有许多我们可以使用的技巧来创建我们的 CSS 样式。
最简单的方法是将字体大小分配给一个集合变量,然后在你的代码中引用这个变量:
@font-size-base: 14px;
一旦设置了初始变量,我们就可以通过将基本值乘以一系列递增的数字来自动创建一系列字体大小:
@font-size-large: @font-size-base * 1.25;
@font-size-small: @font-size-base * 0.85;
@font-size-mini: @font-size-base * 0.75;
当使用预编译器编译时,Less 会将这些转换为有效的 CSS 字体大小,如本截图所示:
这是一种定义字体大小的非常简单的方法;如果我们需要更改字体大小,我们只需要更改 @font-size-base
的值,Less 将自动更新其他值。
顺应时代潮流
使用像素来定义字体大小是一种一致、可靠的方法——如果你为一个元素指定了 14px
的值,那么该元素的大小将是 14px
。然而,对于使用 IE 的用户,当使用缩放功能时,大小不会很好地级联。
相反,我们可以使用 rem
单位——这会保持其值相对于根(HTML)元素,而不是其父元素。你可能注意到我跳过了将 em
作为选项的使用。em
值是相对于父元素设置的,这意味着如果您的访客决定在 IE 中使用缩放功能,元素将不会很好地调整大小!
注意
关于使用rem
、em
和px
作为字体大小格式的优缺点的好讨论,请参阅 Jonathan Snook 的文章——尽管它已经几年了,但它仍然包含一些有用的细节——在snook.ca/archives/html_and_css/font-size-with-rem
。
在现代浏览器中,对rem
的支持很好,所以我们只需要为版本低于 8 的任何 IE 版本提供回退支持。
考虑到这一点,我们可以创建一个如下所示的 mixin 来处理使用rem
值的大小值,但对于仍然需要使用 IE8 或以下版本的人来说,有一个像素回退:
.font-size(@sizeValue){
@remValue: @sizeValue/10;
@pxValue: @sizeValue;
font-size: unit(@pxValue,px);
font-size: unit(@remValue,rem);
}
p { .font-size(13); }
编译后,这将生成以下 CSS:
html { font-size: 62.5%; }
p { font-size: 13px; font-size: 1.3rem; }
大多数现代浏览器将无问题支持使用rem
元素,或者在适当的情况下回退到使用像素等效值。太好了!我们现在已经正确设置了字体大小;我们可以出发了,对吧?或者,我们是…?
处理不同的权重
嗯,也许不是;如果我们正在使用特定字体的多个变体呢?在使用 Less 时这不是问题——我们可以以常规方式引用我们的字体,并使用 Less 命名空间功能来选择和决定为每个 HTML 元素使用哪种字体样式。让我们看看这在实践中意味着什么。
让我们从下载本书附带的代码副本开始;从代码下载中,提取包含我们基本文本和 HTML 标记的weights.html
文件。在项目文件夹内保存该文件的副本。
接下来,将以下内容添加到一个新文档中,并将其保存为weights.less
:
@Alegreya-Sans: "Alegreya Sans",sans-serif;
#SansFont() {
&.light { font-family: @Alegreya-Sans; font-weight: 300; }
&.bold { font-family: @Alegreya-Sans; font-weight: 500; }
&.extrabold { font-family: @Alegreya-Sans; font-weight: 800; }
}
.para1 { #SansFont > .light; }
.para2 { #SansFont > .bold; }
h1 { #SansFont > .extrabold; }
section {
background-color: #ffc; border-radius: 5px;padding: 5px;
border: 1px solid black; width: 400px;
box-shadow: 3px 3px 5px 0px rgba(50, 50, 50, 0.75);
h1 { background-color: #c00; margin-top: 0px; color: #fff; border-top-left-radius: 4px; border-top-right-radius: 4px; padding: 3px; }
}
如果你在一个浏览器中预览结果,你会看到类似于以下截图的内容:
使用 Less 命名空间功能是处理字体的好方法。在这个例子中,我们又触及了我们之前在第五章中介绍的技术,即Less 中的继承、覆盖和嵌套,在那里我们可以选择和决定 Less 编译成有效 CSS 的样式。
在这种情况下,我们正在引入 Google 的 Web 字体之一,在调用.para1
、.para2
和h1
之前,创建三个样式作为嵌套块。这是一个帮助将常见样式组合在一起的好技术——使用它的真正好处是帮助更好地组织你的 Less 样式;Less 将调用样式(即.para1
、.para2
和h1
)转换为有效的 CSS。
小贴士
不要忘记在你的命名空间块中包含()
,以防止 Less 将其编译为有效的 CSS 块。
现在我们已经介绍了使用 Less 帮助管理字体的基础知识,让我们继续看看使用 Less 处理字体的更多示例,从创建响应式设计的@media
查询开始。
在 Less 中使用@media
在使用移动设备和响应式设计的时代,构建网站的一个关键要素是允许它们在移动设备上使用,例如 iPad 或智能手机。
响应式设计的关键是 @media
规则——我们可以使用它来定义特定断点或屏幕状态大小的样式,以适应不同的设备。为了说明使用 Less 时它是如何工作的,我们将使用 Eric Rasch 创建的简化示例作为示例网页的基础:
注意
Eric 的原始示例可在 codepen.io/ericrasch/HzoEx
找到。
对于这个演示,我们将打破常规,使用本书附带的代码下载中可用的 media.html
和 media.less
文件的副本。我建议你在安装了 DOM 检查器的浏览器中运行这个演示,这样你就可以在我们调整浏览器大小时看到不同的样式。
media.html
文件包含一些使用 Lorem Ipsum 生成器在 www.lipsum.com
生成的简单文本;这是为了表示一个标准网页。
由于空间原因,我们将处理 media.less
文件中的重要元素——此文件中的其余 Less 标记纯粹是为了使页面看起来吸引人。
创建一个基本的媒体查询
在我们详细查看 Less 文件之前,让我们先提醒自己一个基本的 @media
查询看起来是什么样子:
@media all and (max-width: 699px) and (min-width: 520px) {
body { background: #ccc; }
}
这意味着当屏幕尺寸在 520 px 和 699 px 之间时,将背景颜色设置为 #ccc
(浅灰色)。
检查 Less 文件
这是一个简单的媒体查询,对吧?让我们将其应用到我们的 Less 文件中。
在 media.less
中,我们可以看到几个部分——第一个部分声明了多个变量;这些包括我们将使用的每个断点,以及我们将应用于页面文本中的字体大小:
@mobile: ~"only screen and (max-width: 529px)";
@tablet: ~"only screen and (min-width: 530px) and (max-width: 949px)";
@desktop: ~"only screen and (min-width: 950px) and (max-width: 1128px)";
@desktop-xl: ~"only screen and (min-width: 1129px)";
@font-size-base: 14px;
@font-size-large: @font-size-base * 1.25;
@font-size-small: @font-size-base * 0.85;
@font-size-mini: @font-size-base * 0.75;
你注意到 @tablet
变量以及它与我们的示例有多相似吗?诚然,我们的不会用于像这个平板电脑这么大的设备,但格式保持不变,无论定义的尺寸大小如何。
接下来是应用样式到每个 @media
规则的 mixin。body:after
语句将屏幕左上角的标签更改为显示特定屏幕尺寸正在使用的断点。部分规则确定用于 <section>
块的宽度和字体大小:
.mediaMixin(@background, @content, @width, @fontsize) {
body:after { background: @background; content: @content; }
section { width: @width; font-size: @fontsize; }
}
我们以最重要的部分结束——这将我们定义的所有 mixin 和变量结合起来,以到达我们编译样式表中将要有的 @media
CSS 规则:
@media @mobile { .mediaMixin( orange; "mobile"; 85%; @font-size-mini ); }
@media @tablet { .mediaMixin( purple; "tablet"; 37%; @font-size-small ); }
@media @desktop { .mediaMixin( green; "desktop"; 40%; @font-size-base ); }
@media @desktop-xl { .mediaMixin( blue; "desktop xl"; 45%; @font-size-large );
如果我们运行代码下载中的示例,并将屏幕调整到最大尺寸(即,对于此示例,大于 1129px
),我们可以看到正在使用的断点为 桌面 xl:
我们的例子是如何工作的?很简单;我们使用变量和混合器的组合来重现每个 @media
查询所需的代码。虽然我们可以更改每个断点以匹配我们想要支持的设备,但这里使用的范围应该覆盖大多数设备。
在每个语句中,我们调用 .mediaMixin
混合器,并将其传递所需的背景、内容(描述我们正在使用的断点)、包含内容的 <section>
的宽度和字体大小。Less 将每个实例编译成有效的 CSS 规则,然后浏览器将其解释为适当的规则。我们将在第八章 Media Queries with Less 中更深入地探讨使用 @media
。
小贴士
如果您已安装 Firefox,尝试在查看此演示时按 Ctrl + Shift + M 激活响应式设计模式——它将演示效果展示得非常出色!
我们几乎完成了使用 Less 处理字体的旅程;在我们继续之前,让我们稍微放松一下,看看使用 Less 可以创建的一些效果。
使用 Less 创建特殊效果
Less 的美妙之处在于,如果您创建了有效的 Less 代码,它将编译成有效的 CSS——这意味着我们可以用它产生一些有趣的效果,尤其是在处理字体时。
如果您在互联网上花点时间搜索 CSS3 类型的效果,您无疑会遇到一些很好的例子——为了说明我的意思,让我们花点时间尝试使用 Less 重新制作两个效果:letterpress 和 emboss。为此演示,我们将使用本章前面创建的 weights.html
页面的副本,并将标题修改得更有强调性。
让我们从打开之前演示中使用的 weights.html
副本并再次将其保存为 sfx.html
开始。
接下来,打开 weights.less
的副本,并添加如下高亮显示的混合器:
@Alegreya-Sans: "Alegreya Sans",sans-serif;
.letterpress() { text-shadow: 0px 1px 0px rgba(0, 0, 0, 0.5); }
.emboss() { box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5); }
混合器只有在从我们的 Less 语句中调用它们时才会被使用;所以,请按照如下所示修改 h1
块:
h1 {
.emboss;
.letterpress;
background-color: #c00;
将文件保存为 sfx.less
。如果您在浏览器中预览结果,应该会看到标题的强调性更强,如截图所示:
Less 的好处之一是我们可以轻松地将类似的效果应用到任何文本上——这只需要一点小心和计划。
在这个例子中,我们使用了 text-shadow
和 box-shadow
,并传递了正确的值组合来产生标题中使用的 letterpress 和 emboss 效果。值得运行这个示例的演示来看到全色的效果——在打印中并不能完全体现其效果!
不应该将其用作在网站上添加大量不同文本效果的借口——这很可能会让您的访客感到厌烦。只要稍加注意,像我们这里使用的两种效果这样的文本效果就可以在我们的页面上添加真正的强调,而不需要使用图像。
进一步探索效果
等等——我们肯定不需要做更多的事情,除了计划我们将要使用的效果,对吧?错了,这就是规划介入的地方:如果我们仔细选择我们使用的任何外部混入函数库,我们可以为自己节省更多的工作。
例如,我们在这里使用了 text-shadow
来产生压印示例;这至少在一个外部混入函数库中可用,即 LESS Elements(我们在第六章迁移您的网站到 Less 中介绍过),可在 www.lesselements.com
获取。
假设您已经在项目中使用了 LESS Elements,我们所需做的只是包含我们的调用语句——混入函数已经成为了 LESS Elements 库的一部分。是的,虽然这意味着我们不一定能减少项目中的整体代码量,但它确实意味着我们需要编写的代码更少,这肯定是一件好事!
摘要
哇,真是一次旅行!我们涵盖了在使用 Less 处理字体时的大量内容;让我们花点时间回顾一下本章我们学到了什么。
我们开始学习如何创建一个简单的混入函数,帮助设置要使用的字体家族和颜色;然后我们看到了如何扩展混入函数以将我们的字体选择存储为变量。接下来,我们探讨了在使用 Less 时如何使用 @font-face
,以及这消除了我们在页面中可以使用字体的任何限制。
我们还看到了我们如何在我们的代码中使用预构建的库,这有助于节省编写混入函数的时间,因为它们可以从像 LESS Hat 这样的库中引用。然后我们转向查看管理字体大小可用的各种方法,包括使用 rem
以及为什么使用 ems
并不一定像它看起来那样好。
然后,我们转向使用 Less 创建 @media
查询作为响应式设计的一部分,并在本章结束时简要地查看了一些在使用 Less 时可以创建的特殊字体效果。
在下一章中,我们将更详细地探讨在为多个设备构建网站时的一项关键技术——即,如何在使用 Less 时使用 @media
规则。
第八章。使用 Less 的媒体查询
现在我们已经看到如何使用 Less 来管理我们内容的显示,那么确保它适合页面呢?啊,是的——这不是媒体查询发挥作用的地方吗……?
在智能手机出现之前,大多数网站都会以固定宽度构建——足够小,可以适应笔记本电脑或 PC,这样大多数最终用户都会有一个一致的经验。
然而,现在越来越多的人使用移动设备,设计可以在每个设备上无缝查看的内容的需求增加了。那些需要具备外科医生技能才能查看内容、操作移动设备的时代已经过去了——人们越来越习惯于在移动设备上查看内容。
我们如何解决这个问题?简单——欢迎来到媒体查询的世界!响应式网页设计的一个基本组成部分,我们可以使用媒体查询来构建一个可以在多个平台上无缝查看的网站。
我想你可能在想——Less 如何在这里帮助?没问题。在本章中,我们将看到 Less 如何使创建媒体查询变得轻而易举;我们将涵盖以下主题:
-
媒体查询的工作原理
-
CSS 有什么问题?
-
设置客户端标准
-
使用 Less 构建媒体查询
准备好享受创建媒体查询的乐趣了吗?让我们开始吧!
介绍媒体查询
如果你曾经花时间为网站创建内容,尤其是为移动平台显示的内容,那么你可能已经遇到过媒体查询。
对于那些刚开始接触这个概念的人来说,媒体查询是一种在视口调整到更小尺寸时定制屏幕上显示内容的方法。从历史上看,网站总是以静态尺寸构建——随着越来越多的人使用智能手机和平板电脑查看内容,这意味着查看它们变得更加困难,因为滚动页面可能是一个令人疲惫的过程!
幸运的是,随着媒体查询的出现,这个问题变得不那么严重了——它们帮助我们确定在特定设备上查看内容时应该显示或不应显示的内容。在本章中,我们将简要地看看它们是什么,它们是如何工作的,并更多地关注如何使用 Less 来创建它们。
几乎所有现代浏览器都提供对媒体查询的原生支持——唯一的例外是 IE 版本 8 或以下,其中它不支持原生:
媒体查询始终以@media
开头,并包含两部分:
第一部分,only screen
,确定规则应该应用的媒体类型——在这种情况下,只有在我们查看屏幕上的内容时才会显示该规则;打印时查看的内容可以很容易地不同。
第二部分,或媒体特性,(min-width: 530px) and (max-width: 949px)
,意味着规则将只应用于最小为530px
和最大为949px
的屏幕尺寸。这将排除任何智能手机,并将适用于更大的平板电脑、笔记本电脑或 PC。
注意
实际上,有数十种媒体查询的组合来满足各种需求——为了找到一些好的例子,请访问cssmediaqueries.com/overview.html
,在那里你可以看到一个详尽的列表,以及是否在你通常使用的浏览器中受支持。
媒体查询非常适合动态调整你的网站以在多个浏览器中工作——实际上,它们是响应式网页设计的一个基本组成部分。虽然浏览器支持媒体查询,但有一些限制我们需要考虑;让我们现在看看这些限制。
CSS 的限制
如果我们花时间与媒体查询一起工作,有一些限制我们需要考虑;这些限制同样适用于我们使用 Less 或纯 CSS 编写时:
-
并非每个浏览器都均匀支持媒体特性;为了看到差异,请使用不同的浏览器访问
cssmediaqueries.com/overview.html
。 -
当前的观点是必须提供一系列断点;这可能导致大量重复,并且需要不断与众多不同的屏幕尺寸保持同步!
-
@media
关键字在 IE8 或更低版本中不受支持;你需要使用 JavaScript 或 jQuery 来实现相同的结果,或者使用像 Modernizr 这样的库来提供一个优雅的回退选项。 -
编写媒体查询将使你的设计绑定到特定的显示尺寸;这增加了重复的风险,因为你可能希望相同的元素在多个 断点 中出现,但必须编写单独的规则来覆盖每个断点。
注意
断点是设计在调整大小超过特定尺寸时将断裂的点。
传统的思维是,我们必须在样式表中为不同的断点提供不同的样式规则。虽然这是有效的,但讽刺的是,这正是我们不应该遵循的!原因在于,你可能需要添加大量的断点规则,只是为了管理一个网站。
通过谨慎的计划和基于设计的断点思维,我们通常可以减少规则的数量。正如你将在本章末尾的示例中看到的那样,只有一个断点被给出,但它可以在一系列尺寸中工作,而无需更多的断点。这个过程的关键是从小开始,然后增加显示的大小。一旦它破坏了你的设计(这就是你的第一个断点),就添加一个查询来修复它,然后,继续这样做,直到你达到最大尺寸。
好的,我们已经看到了媒体查询是什么;让我们改变方向,看看在与客户合作时需要考虑什么,然后再着手编写代码中的查询。
设置客户标准
与媒体查询一起工作的最难的部分不在于代码的设计,而在于与客户就应支持哪些设备达成一致!
一些客户可能希望在他们的网站上获得一致的经验,无论使用什么设备或平台来查看内容。当互联网仍然在正常尺寸的屏幕上查看时,这可能有效。现在情况已经不再是这样了;越来越多的人正在移动或其他类似设备上查看内容。移动设备的使用如此之多,以至于其数量正在迅速增加,很快就会超过仍然使用台式电脑查看内容的人。
“期望是所有心痛的根源”(出自匿名来源,但常被误引为莎士比亚所说),这句话特别恰当——它在决定每个断点应该包含什么内容以及不应该包含什么内容时是关键;如果不这样做,你更有可能在与客户的交流中遇到麻烦!
在构建客户网站的过程中创建媒体查询时,有一些关键点需要记住,这些将成为与客户交谈的基础:
-
在开始时,向客户清楚地解释响应式设计的概念——使内容适应特定的屏幕尺寸。让他们明白,网站在移动设备上不显示所有内容是完全可接受的实践。
-
如果希望在所有设备上都有相同的体验,那么这自然会增加大量的代码并需要额外的资源——这是绝对必要的吗?与客户合作创建可以在同一网站上工作但不是每个设备都会显示的内容,这要好得多。
-
向客户明确说明在每个断点应该包含什么内容以及不应该包含什么内容——他们可能希望显示诸如条款和条件等内容,但如果内容过长,可能会让移动用户对查看网站感到厌烦。
-
如果客户难以理解响应式设计的整体概念,那么让他们在移动设备上查看他们的网站——他们应该看到它看起来很糟糕。移动设备更适合内容而不是交互或搜索——媒体查询可以在屏幕上隐藏这些元素。
-
一种更激进的方案是限制在移动设备上可以执行的操作——这对于航空公司网站来说效果完美,因为它们可能只想让客户预订机票或检查他们的预订。这需要前期做更多工作来默认隐藏更多元素,但为了制作一个干净、快速且在移动设备上运行良好的网站,这些努力是值得的。
-
从技术角度来看,确定在特定断点上哪些元素可以缩放、移动、省略或甚至折叠在屏幕上至关重要。还应考虑在移动环境中使用时其他元素,例如使用的交互形式、字体大小调整和图像裁剪。
需要与客户达成一致的一个关键问题是——网站应该适用于多种设备,还是仅在屏幕大小调整且元素在特定点断裂时才工作?有一种新兴的观点认为,我们无法支持所有设备,我们只需尝试调整屏幕大小,然后在调整过程中修复在特定点断裂的任何元素。当然,我们可以使用 Chrome 或 Opera 中可用的仿真功能——即使这样做,我们仍然无法为所有设备提供支持!
好的,让我们继续,并将注意力转向创建媒体查询;在我们编写代码之前,我们将快速回顾一下创建查询时可用选项。
探索媒体查询
当创建媒体查询时,我们已经看到了它们分为两部分——第一部分由一个媒体类型组成,它定义了媒体查询应该应用的环境(即屏幕或打印)。需要注意的是,这些都不是 Less 特有的——它们都是我们可以使用 Less 创建媒体查询的有效 CSS 媒体类型。
定义媒体类型
虽然我们可能只需要在创建 Less 代码时使用打印或屏幕,但还有其他选项可用;以下是一个完整的元素列表,这些元素可能或可能不被所有浏览器支持:
特性 | 适用于 |
---|---|
all |
大多数设备;这是默认值,除非有其他指定 |
braille |
在盲文触觉设备中使用 |
embossed |
分页式盲文打印机 |
handheld |
手持设备,屏幕尺寸小且带宽有限 |
print |
在打印预览模式下查看的内容 |
projection |
使用投影仪等设备时的投影演示 |
screen |
彩色计算机屏幕 |
speech |
与语音合成器一起使用 |
tty |
使用固定间距字符网格的媒体,例如终端或电传打字机 |
tv |
与电视设备一起使用,具有低分辨率、彩色、有限的滚动和声音 |
探索媒体特性
一旦设置了媒体类型,我们还需要设置应该测试的媒体特性;如果媒体查询可以匹配媒体显示的设备类型和正在测试的特性,它将返回 true。
媒体特性分为三个类别——视觉和触觉媒体、位图媒体和电视。让我们看看视觉和触觉媒体可用的完整选项列表:
特性 | 值 | Min/max 前缀 | 描述 |
---|---|---|---|
width |
Length |
Yes | 这给出了显示区域的宽度 |
height |
Length |
Yes | 这给出了显示区域的高度 |
device-width |
Length |
Yes | 这给出了设备区域的宽度 |
device-height |
Length |
Yes | 这给出了设备区域的高度 |
color |
整数 |
是 | 这是每个颜色组件的位数(如果不是彩色,则值为 0 ) |
color-index |
整数 |
是 | 这是输出设备颜色查找表中的条目数 |
monochrome |
整数 |
是 | 这是单色帧缓冲区每像素的位数(如果不是单色,则值为 0 ) |
grid |
0 或 1 |
否 | 如果设置为 1 ,则设备基于网格,例如电传终端或只有一种固定字体的电话显示屏(所有其他设备为 0 ) |
第二个类别是位图媒体类型;以下是完整的列表:
特性 | 值 | 最小/最大前缀 | 描述 |
---|---|---|---|
orientation |
纵向 或 横向 |
否 | 这给出了设备的方向 |
aspect-ratio |
比例 (w/h) |
是 | 这给出了宽度和高度的比例,以两个整数表示,并用斜杠分隔(例如,16/ 9 ) |
device-aspect-ratio |
比例 (w/h) |
是 | 这是设备宽度与设备高度的比例 |
resolution |
分辨率 |
是 | 这给出了输出设备的像素密度,以整数后跟 dpi (每英寸点数)或 dpc m (每厘米点数)表示 |
第三和最后一个类别只有一个媒体类型——这是 scan
,用于电视设备:
特性 | 值 | 最小/最大前缀 | 描述 |
---|---|---|---|
scan |
渐进式 或 交错式 |
否 | 电视设备使用的扫描过程 |
在大多数情况下,在创建媒体查询时指定单个媒体类型和特性就足够了——会有一些情况我们需要在一个查询中检查多个特性或类型。
幸运的是,Less 可以通过使用逻辑运算符轻松处理这个问题——让我们花一点时间回顾一下创建媒体查询时可用选项:
使用逻辑运算符
当我们开始构建更复杂的查询时,会有一些情况需要在一个媒体查询中对多个标准进行检查。Less 可以轻松处理这个问题。在我们查看如何将所学知识付诸实践之前,让我们花一点时间回顾一下可用的运算符:
运算符 | 用于 |
---|
| and
| 将多个媒体特性组合在一起,或将媒体特性与其他媒体类型组合。例如:
@media tv and (min-width: 700px) and (orientation: landscape) { ... }
|
| comma
| 如果逗号分隔的查询列表中的任何一个返回 true
,则应用一组样式:
@media (min-width: 700px), handheld and (orientation: landscape) { ... }
|
not |
如果媒体查询原本会返回 false ,则返回 true ,例如,@media not all and (monochrome) { ... } 会返回 @media not (all and (monochrome)) { ... } |
---|---|
only |
阻止不支持媒体查询的浏览器应用样式(假设尚未实现回退支持) |
好的,我们已经涵盖了媒体查询的理论;让我们把注意力转向构建一些查询!
设计媒体查询
到目前为止,我们已经了解了媒体查询是什么,可用的选项,以及帮助我们确定需要支持哪些设备的客户。在这个过程中,我们需要确定如何将这些需求转化为实际的代码。
为了帮助做到这一点,让我们通过一个简单的示例来操作。在这个例子中,我们需要创建一个简单的文本块,将编辑器列表显示在文本的左侧。当然,这有点牵强,但它完美地展示了我们如何在不同的设备上变化内容。
创建一个简单示例
要了解媒体查询是如何工作的,最好的方式是通过一个简单的演示。在这个例子中,我们有一组简单的需求,关于在每个尺寸下应该显示什么:
-
我们需要为四种不同大小的内容提供支持
-
小版本必须以纯文本电子邮件链接的形式显示给作者,没有任何装饰
-
对于中等尺寸的屏幕,我们将在链接前添加一个图标
-
在大屏幕上,我们将在电子邮件链接后添加电子邮件地址
-
在超大屏幕上,我们将结合中等和大型断点,因此将显示图标和电子邮件地址
在所有情况下,我们都会有一个简单的容器,其中将包含一些占位文本和编辑器列表。我们创建的媒体查询将控制编辑器列表的显示外观,这取决于用于显示内容的浏览器窗口大小。
让我们从下载并解压书籍附带的代码下载中的simple.html
副本开始。这包含我们将用于创建页面的标记。
接下来,将以下代码添加到一个新文档中。我们将逐节进行讲解,从为媒体查询创建的变量开始:
@small: ~"(max-width: 699px) and (min-width: 520px)";
@medium: ~"(max-width: 1000px) and (min-width: 700px)";
@large: ~"(min-width: 1001px)";
@xlarge: ~"(min-width: 1151px)";
接下来是一些基本的样式,用于定义边距、字体大小和样式:
* { margin: 0; padding: 0; }
body { font: 14px Georgia, serif; }
h3 { margin: 0 0 8px 0; }
p { margin: 0 25px }
我们需要为演示中的每个区域设置大小,所以请添加以下样式:
#fluid-wrap { width: 70%; margin: 60px auto; padding: 20px; background: #eee; overflow: hidden; }
#main-content { width: 65%; float: right; }
#sidebar {
width: 35%; float: left;
ul { list-style: none; }
ul li a { color: #900; text-decoration: none; padding: 3px 0; display: block; }
}
现在基本样式已经设置好了,我们可以添加我们的媒体查询——从为小屏幕服务的查询开始,我们只需显示一个电子邮件标志:
@media @small {
#sidebar ul li a { padding-left: 21px; background: url(../img/email.png) left center no-repeat; }
}
中等查询接下来;在这里,我们在电子邮件地址前添加单词Email
:
@media @medium {
#sidebar ul li a:before { content: "Email: "; font-style: italic; color: #666; }
}
在大媒体查询中,我们改为首先显示名称,然后是电子邮件(后者从data-email
属性中提取):
@media @large {
#sidebar ul li a:after { content: " (" attr(data-email) ")"; font-size: 11px; font-style: italic; color: #666; }
}
我们以超大查询结束,在这里我们使用大媒体查询中显示的电子邮件地址格式,但向其中添加一个电子邮件标志:
@media @xlarge {
#sidebar ul li a { padding-left: 21px; background: url(../img/email.png) left center no-repeat; }
}
将文件保存为simple.less
。现在我们的文件已经准备好了,让我们在浏览器中预览结果。为此,我建议您在 Firefox 中使用响应式设计视图(通过按Ctrl + Shift + M激活)。一旦激活,调整视图大小为 416 x 735;在这里我们可以看到只有名称被显示为电子邮件链接:
将大小增加到 544 x 735 会添加一个电子邮件标志,同时仍然保持之前相同的名称/电子邮件格式:
如果我们进一步增加到 716 x 735,电子邮件标志将变为单词Email,如下面的截图所示:
让我们进一步将大小增加到 735 x 1029;格式再次改变,变为名称/电子邮件链接,后面跟着括号中的电子邮件地址:
在我们的最终更改中,将大小增加到 735 x 1182。在这里,我们可以看到之前使用的样式,但增加了电子邮件标志:
这些截图完美地说明了您如何调整屏幕大小,同时仍然为每个您决定支持的设备保持合适的布局;让我们花点时间考虑代码是如何工作的。
对于开发者来说,通常接受的实践是“从移动开始”,或者创建最小的视图使其完美,然后增加屏幕大小并调整内容,直到达到最大尺寸。这对于新网站来说效果很好,但如果要将移动视图添加到现有网站,则可能需要反转这个原则。
在我们的例子中,我们首先为全尺寸屏幕生成了内容。从 Less 的角度来看,这里没有什么新东西——我们使用了#sidebar
div 的嵌套,但除此之外,这部分代码的其余部分都是标准的 CSS。
奇迹发生在两个部分——立即在文件顶部,我们设置了一系列 Less 变量,这些变量封装了我们查询中使用的媒体定义字符串。在这里,我们创建了四个定义,从@small
(适用于520px
到699px
之间的设备),一直到@xlarge
(宽度为1151px
或更多)。
然后,我们将每个变量用于每个查询中适当的位置,例如,@small
查询设置如下所示:
@media @small {
#sidebar ul li a { padding-left: 21px; background: url(../img/email.png) left center no-repeat; }
}
在前面的代码中,我们有标准的 CSS 样式规则来在名称/电子邮件链接之前显示电子邮件标志。其他每个查询都遵循完全相同的原则;它们在通过 Less 运行时将编译为有效的 CSS 规则。
现在我们已经看到了如何使用 Less 构建媒体查询,值得花点时间来探索如何最好地查看我们的演示。虽然可以争辩说简单地调整浏览器窗口大小可能就足够了,但我们还可以更进一步,利用一系列工具来帮助这个过程。
使用工具调整屏幕大小
在上一节中,我们查看了一个创建媒体查询的简单示例,用于在调整编辑器列表大小时显示或隐藏元素。我们使用了 Firefox 的响应式设计视图选项来调整屏幕大小;这是我们用来干净地调整屏幕以供移动查看的一个选项;它是处理媒体查询的一个关键工具。
您可以使用特殊工具来完成此目的,但大多数现代浏览器已经内置了用于此目的的完全足够的工具。让我们依次看看几个。
对于 Firefox 用户,按下 Ctrl + Shift + M 来激活响应式设计视图,如下面的截图所示:
然而,如果你的首选是谷歌 Chrome,那么同样的功能也是可用的——它是开发者工具集的一部分,可以通过按下 Ctrl + Shift + I 来激活:
如果你是一名 Opera 用户,那么有一个专门的 Opera 移动模拟器,可在www.opera.com/developer/mobile-emulator
找到,支持 Windows、Mac 和 Linux 平台:
如果你需要使用 IE 以响应式格式显示你的网站,那么很遗憾,你的选择相当有限——至少是 IE10。IE 有一个调整大小选项(如下面的截图所示),但它调整的是整个窗口,而不是在正常大小的窗口内显示视图:
这不是完美的选择,但最佳实践是在更符合标准的浏览器(如谷歌 Chrome 或 Firefox)中进行开发。然后我们可以对 IE 进行任何调整,以便稍后进行。
小贴士
值得注意的是,如果使用 IE11,则可以设置为以类似于谷歌 Chrome 的方式工作。我们可以设置模拟模式以在大型/完整大小的浏览器窗口中显示一个小窗口。
如果你不想使用内置的浏览器工具,那么还有其他工具可供选择。两个值得注意的工具是 Brad Frost 的 ish,可在bradfrostweb.com/demo/ish/
找到,以及 Malte Wassermann 的 Viewport Resizer,可在lab.maltewassermann.com/viewport-resizer/
找到。
让我们现在改变焦点,将注意力转向构建更深入的东西,我们可以使用 Less 在更真实的例子中。
构建响应式页面
向任何网站添加媒体查询都是可能的;关键是决定你想要支持哪些断点以及在每个断点应该显示哪些元素。这可以少到只有一个断点,也可以很多。这完全取决于元素在调整大小时会发生什么,以及你是否需要修改代码以在特定断点改善它们的显示效果。
现在我们已经看到了基本媒体查询的实际应用,我们将创建一个更复杂的东西,形式为一个基本的欢迎页面,这样的页面在作品集中也不会显得突兀。我们将从基本的完整页面开始,其外观可能类似于以下截图:
这是一个非常简单的页面,仿佛它是作品集网站的一部分。这是一个完美的机会来探索我们如何使用一些简单的媒体查询来调整页面以适应移动平台。
构建基本页面
让我们从提取本书附带的代码下载中的 responsive.html
文件副本开始。这个文件包含一个简单的演示页面,设置为看起来可以成为个人作品集网站的前页。将此文件保存到你的项目文件夹中。
我们还需要 reset.less
文件的副本,它也在相同的代码下载中;请将其提取到项目文件夹中。这提供了一些基本的样式重置,以模拟在创建用于在网站上显示的页面时可能发生的情况。
注意
为了本演示的目的,我将假设你正在使用 Sublime Text,它预先配置为在保存内容时将 Less 文件编译成有效的 CSS。
接下来,打开你选择的文本编辑器并添加以下代码;我们将逐节详细讲解。我们首先设置一些基本样式,以定义页面内的每个区域:
#wrapper { width: 96%; max-width: 45rem; margin: auto; padding: 2%; }
#main { width: 60%; margin-right: 5%; float: left; }
aside { width: 35%; float: right; }
a { text-decoration: none; text-transform: uppercase; }
a, img { border: medium none; color: #000000; font-weight: bold;
outline: medium none;}
接下来,我们需要为我们的页眉定义一些样式。这是我们将在调整页面到较小屏幕时被替换的元素之一:
header {
font-family: 'Droid Sans', sans-serif;
h1 { height: 70px; float: left; display: block; font-weight: 700; font-size: 2.0rem;}
nav {
float: right; margin-top: 40px; height: 22px; border-radius: 4px;
li { display: inline; margin-left: 15px; }
ul { font-weight: 400; font-size: 1.1rem; }
a {
padding: 5px 5px 5px 5px;
&:hover { background-color: #27a7bd; color: #ffffff; border-radius: 4px; }
}
}
}
剩下的两个基本样式涵盖了屏幕调整大小时出现的跳转到主要内容链接以及屏幕上的主图像:
#skipTo {
display: none;
li { background: #197a8a; }
a { color: #ffffff; font-size: 0.8rem; }
}
#banner {
float: left; margin-bottom: 15px; width: 100%;
img { width: 100%; }
}
将文件保存为 responsive.less
。如果我们浏览器的结果,我们将看到类似于本例开头所示截图的内容。
然而,如果我们使用像 Firefox 中的响应式设计视图这样的工具调整浏览器窗口大小,它将开始破坏设计——工具栏丢失标签,页眉有一个很大的间隙,图像的右侧已经被裁剪,如下面的截图所示:
我们可以通过添加一个媒体查询来解决这个问题,以管理屏幕调整大小时发生的情况。让我们看看这个在实际操作中是如何工作的。
添加响应式查询
我们已经为我们的作品集页面设置了基本样式,并且可以清楚地看到,当页面调整大小时,元素开始断裂。让我们通过添加媒体查询来修复这个问题,重新定义屏幕调整大小时发生的情况。
首先,在 responsive.less
文件的头部添加以下内容:
@mobile: ~"screen and (max-width: 30rem)";
接下来,我们需要添加在移动平台上使用时将激活的替换样式。在 responsive.less
中的 Less 样式下方,请添加以下代码,从控制页面顶部出现跳转到主要内容按钮的样式开始:
@media @mobile {
#skipTo {
display: block;
a {
display: block; padding: 10px; text-align: center; height: 20px;
&:hover { background-color: #27a7bd; border-radius: 0px; height: 20px; }
}
}
接下来是调整主内容区域、侧边栏和页眉所需的样式:
#main, aside { float: left; clear: left; margin: 0 0 10px; width: 100%; }
#banner { margin-top: 150px; }
header h1 { margin-top: 20px; }
最后,我们需要修改用于重新定义导航选项的样式,当页面调整大小时,这些选项现在会显示为按钮堆叠列表:
header nav{
float: left; clear: left;margin: 0 0 10px; width: 100%;
li { margin: 0; background: #efefef; display: block; margin-bottom: 3px; height: 40px; }
a {
display: block; padding: 10px; text-align: center;
&:hover { background-color: #27a7bd; border-radius: 0px; padding: 10px; height: 20px; }
}
}
}
将文件重新保存为 responsive.less
。如果你使用 Sublime Text 作为编辑器,它将将其转换为编译后的 CSS 文件。现在让我们在浏览器中预览结果:
在全尺寸时,不会有任何变化(这是预期的),但当页面大小调整时,我们已经在页面上看到了改进。标题已经被重新定位,以减少其下方的间隙,工具栏已经被重置以显示为按钮,图片已经被调整大小以更好地适应页面,内容已经被重新定位为垂直格式。我们还可以看到添加了一个按钮,允许我们跳转到页面上的主要内容。
极好,我们的页面现在在移动设备上的外观和功能正如我们所期望的那样!如果我们增加或减小浏览器窗口的大小,我们可以看到内容根据我们在responsive.less
中创建的媒体查询重新流动以适应可用空间。
那么,是什么魔法让这一切都工作得如此顺利?从我们使用的代码来看,如果你认为这部分的全部代码都是关键,你可能会被原谅。这是一个完全有效的陈述。毕竟,所有这些样式都是必需的,以确保在移动环境中使用时内容被正确放置。
然而,实际上我们只使用了两个关键语句:@mobile: ~"screen and (max-width: 30rem)"
;和@media @mobile {…}
。
(好吧,我稍微作弊了一下,但只多了一个字符!)
第一个语句是一个 Less 变量,我们将其设置为我们的媒体类型和我们将要测试的功能。第二个语句调用该变量作为测试。介于两者之间的所有内容都是标准的 CSS 样式,并且在使用于在移动设备上显示内容时被用来重新设计页面布局。
在这个例子中,我们使用了一张大图片,其宽度被设置为width: 100%
。虽然当页面大小减小或增加时,它将完美地调整大小,但这仍然意味着我们可能在小型设备上加载了一个大图片——这不是一个好主意!我们可以通过要求浏览器根据应用的媒体查询加载不同版本的图片来改进这一点。让我们看看 Less 如何帮助减轻管理此过程的一些负担。
添加响应式图片
如果你拥有一台移动设备,比如平板电脑或智能手机,请举手?如果你有,那么你可能会看到当页面没有针对移动使用进行缩放时,页面加载需要多长时间。
在我们刚刚工作的例子中,我们将#banner img
的宽度设置为 100%;在大多数情况下,这将完美地工作;这也意味着我们正在加载一张大照片,这在移动设备上并不理想!相反,我们可以简单修改我们的媒体规则,在屏幕尺寸减小时加载一个较小的图片。
注意
对于这个演示,我将摘要图片的一个副本调整到较小的 461px x 346px 版本,并保存为abstract_small.jpg
。这个尺寸足够小,当屏幕适当地调整到更小的尺寸时,我们可以看到变化的效果。
让我们从下载并提取本书代码下载中的responsive.html
和responsive.less
的副本开始,然后分别保存为responsive_img.html
和responsive_img.less
。
打开responsive_img.html
,然后修改如所示行:
<link href="css/reset.less" type="text/less" rel="stylesheet">
<link rel="stylesheet/less" href="css/responsive_img.less">
接下来,按照指示将高亮行添加到媒体查询中:
#banner {
margin-top: 150px;
img { content:url("../img/abstract_small.jpg"); }
}
保存两个文件。如果我们然后在浏览器中预览结果,您应该看不到任何可见的变化(这是我们预期的)。然而,如果我们打开浏览器中的开发者工具并缩小屏幕尺寸,我们会看到图像的 URL 有所变化:
这种方法的优点是我们可以节省几 KB,这使得在移动设备上查看网站更快,因为浏览器需要下载的内容更少。然而,我们可以通过用高分辨率版本替换图像来走完全极端,但前提是设备支持它!感兴趣吗?让我们看看这是如何工作的,使用可从imulus.github.io/retinajs/
获取的retina.js
Less 混合器。
集成图像视网膜支持
在上一个示例中,我们看到了如何轻松调整我们的 Less 代码,以便在屏幕尺寸调整以模拟移动设备时加载较小的图像。
然而,你们中的许多人将拥有具有视网膜支持或能够显示高分辨率图像的设备(如 iPad 或 iPhone),这些图像在其他情况下在普通 PC 上显示效果不佳。我们可以利用 Less 来利用这一点。实际上,已经创建了一个 Less 混合器,我们可以从raw.githubusercontent.com/imulus/retinajs/master/src/retina.less
获取它。将此保存为项目文件夹中的retina.less
。
接下来,我们需要保存我们一直在使用的abstract.jpg
文件的副本,作为abstract@2x.jpg
——这将成为我们的高分辨率版本。将原始的abstract.jpg
文件复制一份,并使用 JPG 压缩器(如来自www.jpeg-optimizer.com
的在线服务)进行压缩。将压缩版本保存为abstract.jpg
。
现在我们已经准备好了图像,打开responsive.html
并修改如所示行:
<link href="css/reset.less" type="text/less" rel="stylesheet">
<link href="css/responsive_hd.less" rel="stylesheet/less">
<script src="img/less.min.js"></script>
将此保存为responsive_hd.html
。接下来,打开responsive.less
并在文件开头添加此行:
@import "retina.less";
然后,在文件末尾添加以下行:
#banner img { .at2x('/images/abstract.png', 200px, 100px); }
注意
在生产环境中,这更有可能是在媒体查询中——为了演示目的,将其添加到末尾就足够了。
将此保存为responsive_hd.less
。然后我们可以在浏览器中预览结果。为了获得最佳效果,我建议以下操作:
-
使用本地 Web 服务器或在线 Web 空间预览结果——一个值得尝试的本地 Web 服务器是 WAMP (
www.wampserver.de
for Windows) 或 MAMP (www.mamp.info
for MAC)。 -
如果可能,如果你无法通过视网膜屏设备在线查看结果,尝试在 Google Chrome 中查看结果。Google Chrome 具有模拟不同设备的能力;如果我们启用此功能并将其设置为显示 iPhone 5,例如:
我们可以清楚地看到已经进行了更改:
虽然网页布局不应该有实质性的变化,但使用这个技巧意味着当设备支持时可以使用更高分辨率的图像,或者在不支持视网膜屏的设备上替换为标准分辨率图像。
要测试设备是否支持这里使用的device-pixel-ratio测试,请浏览到www.quirksmode.org/css/mediaqueries/devicepixelratio.html
。例如,当使用 iPad 进行测试时,我们可以确认webkit-device-pixel-ratio
是支持的:
让我们继续这个主题,通过查看使用 Less 处理媒体查询时可用哪些外部库来继续使用外部库。
使用预构建的库
到目前为止,我们已经介绍了使用 Less 创建媒体查询的基础——这时你可能正在想,“当然,我们可以使用预构建的库来帮助我们,对吧……?”
嗯,在这种情况下,很遗憾我们没有可用的预构建库;我们必须手动构建每个查询!这并不是坏事,因为如果不小心,媒体查询可能会被视为一种折衷方案,这可能导致代码膨胀。要为所有断点提供支持将非常困难,甚至几乎是不可能的。每个项目都需要支持特定的断点集,而这些断点对于每个网站来说可能并不相同。
此外,媒体查询在所有现代浏览器中都是原生支持的;唯一的例外是 IE,其中版本 8 或以下不支持。为了解决这个问题,有三个选项:
-
我们可以使用 Mike Morici 创建的回退库 media-query-to-type,我们可以从
github.com/himedlooff/media-query-to-type
下载它。这个库将媒体查询转换为媒体类型,这些类型支持回退到 IE6。 -
或者,我们可以使用 Modernizr(来自
www.modernizr.com
)来检测媒体查询的使用情况。 -
另一个可以使用的库是 Respond.js,由 Scott Jehl 创建,可在
github.com/scottjehl/Respond
获取。这是一个有效的即插即用库,可以将大多数媒体查询转换为 IE8 或以下版本可以理解的格式。
尽管本章是关于使用 Less 创建媒体查询的,但考虑应该支持哪些浏览器以及你愿意走多远以使媒体查询在旧浏览器(如 IE6 到 8)中工作仍然很重要。
注意
为了保持清晰,我们可以使用条件技巧,仅在检测到 IE9 或以下版本已被使用时才加载 media-query-to-type 或 Respond.js 库:
#<!--[if lt IE 9]>….<![endif]-->
虽然在某些方面我们可能觉得有义务在所有情况下(包括旧 IE)提供相同的环境,但这并不一定是一项值得做的练习;对少量浏览器提供良好的支持比大量浏览器的平均支持要好!
摘要
媒体查询迅速成为响应式网页设计的既定事实。在本章中,我们看到了如何使用 Less 使代码中的管理过程更加容易。
我们通过一个简要介绍开始了对媒体查询的旅程,随后回顾了一些我们必须解决的限制以及在与客户合作时需要考虑的注意事项。
接下来,我们对在 Less 中使用时可以使用的媒体类型和功能进行了简要探索;我们查看了一些逻辑运算符,这些运算符也可以用来创建测试多个类型或功能的查询。然后,我们介绍了如何创建一个简单的媒体查询,快速浏览了如何在浏览器中最佳地显示响应式视图,在继续讨论一个演示作品集中单页的更实际示例之前。我们看到了如何首先创建我们的基本页面,然后添加必要的代码将其转换为响应式页面。
然后,我们简要地探讨了如何通过首先使其更具响应性,然后在支持并启用视网膜的情况下切换到显示高分辨率图像来改进页面上的图像。然后,我们通过查看在处理 Less 时可以使用的预构建库来结束本章。
在下一章中,我们将转向一些 Less 的更实际用途,探讨在 CMS(如 WordPress)中使用 Less。
第九章。在 CMS 中使用 Less
在 CMS 中工作……啊,选择,选择……!
问题:以下哪些有共同之处——Facebook、Beyoncé、Sony、达拉斯小牛 NBA 篮球队和《时代》?
解决了这个问题吗?嗯,这是我们学习 Less 旅程中下一章的主题。他们都有使用 WordPress 创建的博客或网站!WordPress 创建于 2003 年,已成为世界上知名的内容管理系统平台之一,用于数十种场景,从简单的博客到完整的电子商务系统。
在接下来的几页中,我们将学习如何将我们最喜欢的 CSS 预处理器集成到 WordPress 中,以及我们可以使用的技巧来帮助简化样式表的创建。最好的部分——大多数都是我们在本书中已经介绍过的技巧;我们只是将它们应用到我们使用的地方。
在本章中,我们将涵盖以下主题:
-
WP 主题结构的概述
-
将 Less 集成到页面中
-
将代码转换为使用 Less 的一些示例
-
使用 Less 为 WP 预构建的主题
-
可用于与 WordPress 一起使用 Less 的插件
-
使用 Grunt 帮助在 WP 中开发 Less
好奇吗?让我们开始吧...!
注意
本章将假设您对 WordPress 主题设计有一定程度的熟悉;如果您是 WordPress 的新手,您可能想浏览一下 Packt Publishing 出版的关于 WordPress 主题设计的几本书。
介绍 WP 主题结构
如果您花过时间与 CMS 系统一起工作,那么您可能已经遇到了使用主题来定制您的网站和根据需要添加或删除功能的概念。
WordPress 也不例外;它使用一套主题来定制其外观;在本章中,我们将遵循这一原则,看看我们如何使用 Less 来帮助简化这个过程。在我们开始编写代码之前,花一点时间来检查 WordPress 主题的结构是值得的。
首先,我们需要下载 WordPress 源文件,这些文件可在wordpress.org/latest.zip
找到;在撰写本文时,最新版本是 3.9.1。当我们打开 WordPress 存档时,导航到wp-content | themes | twentyfourteen。我们会看到类似以下的内容:
所有这些文件都是操作随本版 WordPress 提供的 Twenty Fourteen 主题所必需的;我们将以此主题为基础,在本章的练习中使用。
我们最感兴趣的是style.css
文件——这是任何主题的主要样式表。此文件包含在 WordPress 主题选择区域显示的主题信息,我们可以看到诸如主题名称、作者、支持 URL 等详细信息。我们还将使用functions.php
文件来添加对 Less 的支持,但这将是一个一次性过程,在我们真正开始定制主题之前发生。
准备我们的环境
现在我们已经下载了 WordPress,我们需要确保有一个可用的环境来使用 Less。
每个人的环境可能都不同,但要最大限度地利用接下来的练习,您至少需要确保以下内容:
-
一个可以定制的 WordPress 工作副本——理想情况下,这将是在使用类似 WAMP(适用于 Windows,可在
www.wampserver.com
获取)或 MAMP(适用于 Mac,可在www.mamp.info
获取)的 Web 服务器本地托管。或者,您可能有一些在线 Web 空间可供使用——这同样有效,尽管您可能会发现本章末尾的自动化练习难以完成。 -
为了本书的目的,我将假设 WampServer 已安装;如果您的服务器不同,请相应地进行更改。
-
安装 Node.js 和 Grunt 的副本;我们已经在 第二章 构建 Less 开发工具包 中介绍了如何安装它们。
-
选择您喜欢的文本编辑器——有数百种可供选择;我个人的偏好是 Sublime Text 2,我将假设您已经安装了它。
如果您尚未安装 WordPress,您可以在 codex.wordpress.org/Installing_WordPress
找到完整的安装说明。
好的,假设我们已经安装了所需的软件组件,让我们继续并查看如何为使用 Less 准备我们的主题。
创建基本子主题
等一下,准备我们的主题?
是的,您读得正确——准备我们的主题。虽然 WordPress 默认附带三个主题可供使用,但直接修改源文件并不是一个好习惯。
修改源文件意味着如果为该主题发布更新,则您的主题将会损坏(是的,WordPress 确实会对其主题发布更新)。我们可以通过创建一个子主题来解决这个问题,该子主题位于同一主题文件夹中,但设置为继承其父主题的基本文件。
这意味着我们可以保留父主题的原始系统文件,但使用在子主题中创建的新样式来覆盖现有样式。我们将在本章后面开始编写新的 Less 代码时充分利用这一原则。
现在,让我们快速浏览创建我们的新子主题:
-
导航到 wp-content | themes;在这里,您将看到一个名为
twentyfourteen
的文件夹: -
创建此文件夹的副本,并将其重命名为
twentyfourteen-child
。在主题文件夹列表中识别此类主题时,在主题名称末尾附加child
是一个好习惯。 -
在
twentyfourteen-child
文件夹内,打开style.css
的副本,然后删除关闭*/
下的所有内容,并按照以下所示进行替换:This theme, like WordPress, is licensed under the GPL. Use it to make something cool, have fun, and share what you've learned with others. */ @import url("../twentyfourteen/style.css"); /* =Theme customization starts here -------------------------------------------------------------- */
这就是我们需要做的全部。如果我们浏览到 WordPress 安装中的 中央管理 区域,我们将在 外观 | 主题 区域看到子主题。剩下的只是以通常的方式激活它。
注意
注意,从现在开始,假设所有更改都将直接在子主题中进行,除非另有说明。
在 WordPress 中添加 Less 支持
在 WordPress 安装并运行后,是时候将我们的注意力转向添加 Less 支持。
在 WordPress 的旧版本中,通常直接将其添加到 header.php
文件中。虽然它工作得很好,但这意味着我们无法在 HTML 内容和表现性标记之间保持清晰的分离。幸运的是,在更近的版本中,WordPress 团队转向使用存储在 functions.php
文件中的函数来添加样式表。让我们看看现在如何实现这一点:
-
打开您选择的文本编辑器,然后浏览到
twentyfourteen
主题文件夹,并查找functions.php
。在文件底部添加以下代码:/* * Adds support for the Less preprocessor to your theme. * * @since Twenty Fourteen 1.0 * @param string $current_user Determines the currently logged in user */ if ( ! function_exists( 'less_enqueue_scripts' ) ) { function less_enqueue_scripts() { $current_user = wp_get_current_user(); if ( $current_user->ID == '1' ) { wp_enqueue_script( 'lesscss', get_stylesheet_directory_uri() . '/js/less.min.js' ); } } add_action( 'wp_enqueue_scripts', 'less_enqueue_scripts' ); }
-
保存更改。如果我们刷新屏幕并在浏览器中预览结果,我们不会看到任何视觉上的变化。然而,如果我们使用 Firebug 等 DOM 检查器预览编译的源代码,我们可以清楚地看到 Less 的添加:
到目前为止,我们已经有一个版本的工作良好的 WordPress,它支持 Less——我们可以继续创建一个名为 style.less
的 Less 文件,并将其作为 style.css
的替代品放入,对吧…?
向特定用户显示更少的样式表
别急。我们告诉了 WordPress 如何调用 Less,但还没有告诉它如何检索正确的 Less 样式集!为了做到这一点,我们需要在 functions.php
文件中添加另一个函数;这个函数不仅将包含一个基于 Less 的替换样式表,而且只向管理员显示,并为常规使用显示编译版本。请耐心等待,一切很快就会变得清晰:
-
打开我们在上一项练习中工作过的
functions.php
文件副本。这次,在文件底部添加以下内容:if ( ! function_exists( 'less_filter_stylesheet_uri' ) ) { function less_filter_stylesheet_uri( $stylesheet_uri, $stylesheet_dir_uri ) { $current_user = wp_get_current_user(); if ( $current_user->ID == '1' ) { $style_src = $stylesheet_dir_uri . '/style.less'; } else { $style_src = $stylesheet_dir_uri . '/style.min.css'; return $style_src; } add_filter( 'stylesheet_uri', 'less_filter_stylesheet_uri', 10, 2 ); }
-
保存文件副本,然后刷新当前显示 WordPress 的浏览器窗口。如果我们像之前一样打开我们的 DOM 检查器,我们现在可以看到正在使用的替换样式表:
如果我们退出 WordPress 并以其他用户身份登录,将显示样式表的编译 CSS 版本。
使用插件添加 Less 支持
手动添加代码工作得很好,但过了一段时间就会变得乏味。我们当然可以使用插件使事情变得更简单,对吧?
绝对可以,我们可以使用插件添加对 Less 的支持;有几种方法可以实现这一点,但我的最爱必须是 Justin Kopepasah 创建的插件,可在 WordPress 插件目录wordpress.org/plugins/less-theme-support/
下载。让我们看看如何使用它;安装它真的很简单:
-
首先导航到
wordpress.org/plugins/less-theme-support/
,然后点击下载版本 1.0.2。当被提示时,将其保存到 WordPress 安装的plugins
文件夹中。 -
在 WordPress 的 admin 中浏览到插件区域,然后点击上传并选择less-theme-support.1.0.2.zip。
-
点击立即安装,然后当被提示时,点击激活插件。
到目前为止,插件现在是激活的,我们需要告诉我们的 WordPress 主题如何使用它:
-
如果我们还没有在之前的练习中这样做,将主题根目录下的
style.css
文件重命名为style.less
。 -
启动您最喜欢的文本编辑器并打开位于我们
theme
文件夹根目录的functions.php
文件的副本。 -
查找
twentyfourteen_setup()
函数(在第 58 行或附近)并在函数末尾添加以下内容,如图所示:add_filter( 'use_default_gallery_style', '__return_false' ); // Add support for Less preprocessor add_theme_support( 'less', array('enable' => true ) ); } endif; // twentyfourteen_setup
保存文件。如果我们回到我们的 WordPress 网站并刷新屏幕,我们应该看不到任何视觉上的变化。真正的变化会在我们查看 DOM 检查器中的代码时显示:
值得注意的是,Less 主题支持附带了一些配置选项,我们可以使用它们来更改其工作方式。如果我们从开发网站切换到生产环境,这非常完美。可以设置的值是布尔值,默认为 false:
-
Enable
:这启用了 Less 并在前端排队less.min.js
-
Develop
:这启用了 Less 的开发环境并在前端排队less-develop.js
-
Watch
:这启用了 Less 的监视模式并排队less-watch.js
-
Minify
:这启用了在前端对所有其他访客使用压缩样式表(style.min.css
)(最好使用lessc -x style.less > style.min.css
生成)
如果使用得当,它们可以非常灵活;例如,我们可能希望配置我们的主题在开发时动态使用 Less,但在生产时不使用:
add_theme_support('less', array(
'enable' => true,
'develop' => true,
'watch' => true
));
如果我们切换到生产使用,那么我们可能会使用minify
选项:
add_theme_support( 'less', array(
'minify' => true
));
正如我们所见,这是一个易于配置的插件。如果你在多个网站上使用 Less,通常使用插件来安装 Less 会更好,这样我们就不必深入研究源文件并对其进行编辑。这个练习的关键部分是使用 WordPress 的add_theme_support
关键字,它允许主题或插件在我们的主题内注册对某些功能的支持。
注意
如果你想要了解更多关于 add_theme_support
的信息,值得浏览 WordPress Codex 页面 codex.wordpress.org/Function_Reference/add_theme_support
。
这允许我们告诉主题使用 Less。我们总是可以手动这样做(正如我们所看到的),但在可能的情况下,使用插件会更好,除非情况要求需要另一种方法。
在 WordPress 中使用 Less 主题
现在我们已经设置了 Less 的支持,让我们继续看看在主题中使用 Less 样式可用的选项,无论是在我们自己的创作中,还是作为可在网上销售或下载的预构建主题的一部分。
将主题转换为使用 Less
现在我们有了 Less 样式表的基线,我们可以开始添加我们转换的样式。等等,我听到你问,“如果我们正在转换一个像 TwentyFourteen
这样的主题,我们应该从哪里开始?”
这是一个非常好的问题。在这个主题当前样式表的 4200 多行中,很容易感到困惑!然而,如果我们遵循两个简单的原则,所有的问题都将开始变得清晰:
-
Less 允许我们将样式表分解成多个文件,这些文件由 Less 编译成一个。利用这一点;这将非常有帮助,因为较小的文件更容易转换!
-
不要试图一次性转换所有内容;一点一点地做。Less 是 CSS 的超集,这意味着它实际上包含了所有的 CSS;Less 会愉快地将未更改的 CSS 样式编译为
.less
文件。
在这些原则的指导下,让我们开始转换我们的主题:
-
首先打开
TwentyFourteen
父主题中的style.css
文件副本,并查找第四部分,它从第 831 行或第 926 行开始。 -
将此部分复制到子主题中的
style.less
文件;在此行下方粘贴:/* =Theme customization starts here -------------------------------------------------------------- */
-
我们将从将搜索框的正常绿色颜色转换为变量开始,然后使用它来计算悬停时使用的浅绿色颜色。在
style.less
中的@import
语句下方立即添加以下内容,如图所示:@import url("../twentyfourteen/style.css"); /* Define colors */ @search-box-color: #24890d; @search-box-hover-color: @search-box-color + #333;
-
我们接下来要做的更改将是
.site-title
样式。我们将将其转换为 Less 的嵌套格式,因此请删除这两个样式:.site-title { float: left; font-size: 18px; font-weight: 700; line-height: 48px; margin: 0; } .site-title a, .site-title a:hover { color: #fff; }
用以下内容替换之前的两个样式:
.site-title { float: left; font-size: 18px; font-weight: 700; line-height: 48px; margin: 0; a { color: #fff; &:hover { color: #fff; } } }
-
我们还有机会整合一个 mixin。这次,它将是一个用于
.search-box-wrapper
类中使用的box-sizing
样式的替代品。在style.less
文件中查找此类,并按所示修改:.search-box-wrapper { .box-sizing(border-box); position: absolute; top: 48px; right: 0; width: 100%; z-index: 2; }
-
在一个单独的文件中,添加以下代码并将其保存为
mixins.less
在less
文件夹中:.box-sizing(@sizing: border-box) { -ms-box-sizing: @sizing; -moz-box-sizing: @sizing; -webkit-box-sizing: @sizing; box-sizing: @sizing; }
-
我们需要将此导入我们的 Less 文件中,所以请继续添加以下行,如指示:
@import url("../twentyfourteen/style.css"); @import "less/mixins.less";
-
最后一步是将子主题中的
style.css
文件重命名为style.less
;尽管这还不是完全转换,但 Less 仍然会将其编译为有效的 CSS。
在这个阶段,我们现在可以保存我们的工作,然后刷新浏览器窗口,它将显示我们的 WordPress 网站。如果一切顺利,你将看不到任何视觉上的差异。你唯一会看到的不同之处在于通过 DOM 检查器查看编译后的代码,例如 Firebug:
中间那些敏锐的人可能已经注意到了——为什么我们要重复代码,你可能会问?重复代码有一个很好的理由,至少暂时是这样——虽然我们通常不想这样做,但这里的讽刺之处在于我们可以利用这种意外的重复来产生良好的效果,以帮助确认我们的新样式是否正确。
我们从原始父主题的 CSS 文件中复制了第四部分
并将其复制到我们的子主题中。默认情况下,子主题中的样式会附加到父主题的样式表中。在这种情况下,我们的主题已经附加了重复的样式,正如我们所期望的那样。现在的问题是:我们需要将重复的样式重新工作成 Less 等价物(就像这里所做的那样)。然后我们可以与原始主题进行对比,原始主题由第 917 行的style.css
指示,以查看我们的 Less 版本是否正确。
如果它是正确的,我们就可以从原始主题中删除它,或者我们可以删除@import
语句;这打破了与父主题的依赖关系,并将子主题转变为一个独立的主题。
现在我们已经涵盖了转换主题的基础知识,让我们花点时间考虑一些有用的提示,这将帮助我们创建自己的主题。
创建我们自己的主题
到目前为止,我们已经花费时间将 WordPress 主题中现有的 CSS 样式转换为使用 Less。虽然这样做效果不错,但完成它需要时间,因为 WordPress 核心主题,例如TwentyTwelve
或TwentyFourteen
,有数千行代码!
更合理的方法是创建自己的主题。与其从头开始编写,不如将其创建为子主题,这样就可以覆盖父主题中现有的样式。
小贴士
尽管我们在这里使用了一个例子,但详细说明的原则可以用于任何需要创建新主题的实例。
“为什么使用子主题?”你可能会问?这样做有几个很好的理由:
-
你对父主题所做的任何更改,如果 WordPress 团队发布更新,很可能会被破坏。
-
这可以节省你重新定义大量样式的麻烦;你可以集中精力进行关键更改。准备好后,你可以将父主题的样式合并到自己的主题中,并将子主题转换为可以独立使用的主题。
现在我们来看看如何使用 Less 创建一个主题。为了充分利用这个练习,我们需要确保以下几点已经到位:
-
你的 WordPress 安装中安装并激活了
TwentyTwelve
。TwentyTwelve
的 CSS 样式表比当前的TwentyFourteen
版本简单;这将使理解过程更容易,并可能鼓励你开始使用较新的主题! -
TwentyTwelve
主题的副本已被保存并重新配置为子主题;如果您不确定如何操作,请参阅本章的创建基本子主题部分。 -
Crunch!的副本已安装并配置好,可在您的系统上使用。
-
Firefox 的副本已安装。这个主题是使用 Firefox 开发的,以便在本练习中保持简单。
我们将从创建整个编译过程关键的基本样式表开始:
-
首先,将子主题文件夹中现有的
style.css
文件重命名。我们将在练习结束时用编译版本替换它。 -
从附带下载中提取并保存
learningless
文件夹中的less文件夹的副本到子主题文件夹的根目录。 -
打开您的文本编辑器,然后将其添加到其中,将其保存为子主题文件夹根目录下的
style.less
:/* Theme Name: Learning Less Description: Child theme for the Twenty Twelve theme Author: Alex Libby Author URI: http://www.not42.net Template: twentytwelve Version: 0.1 */ // Import parent theme styles @import url("../../twentytwelve/style.css"); @import "variables.less"; @import "mixins.less"; @import "misc.less"; @import "navigation.less"; @import "header.less"; @import "posts.less"; @import "pages.less"; @import "sidebar.less"; @import "widgets.less"; @import "footer.less";
-
接下来,我们需要编译
style.less
以生成我们的 WordPress 样式表。目前,我们将使用 Crunch!来编译文件,所以请继续在 Crunch!安装中打开style.less
。 -
点击Crunch File,然后在提示时,输入
style.css
作为保存编译结果的文件名。它看起来类似于以下截图: -
将编译好的
style.css
文件复制到子主题文件夹的根目录。 -
启动您的 Firefox 副本并浏览到您的 WordPress 安装。如果一切顺利,您应该会看到类似于以下截图的内容:
好的,它不会赢得任何风格奖项!然而,它有助于说明一些关键点;让我们休息一下,更详细地看看这些。
注意
在learningless
文件夹中有style.less
和style.css
文件的完成版本;导航到 less 文件夹,然后将style-finished.css
重命名为 style 并复制到子文件夹的根目录。如果您在 less 代码上遇到困难,那么style-finished.less
包含了这个主题的代码的完成副本。
整个过程的精髓是style.less
文件。注意我们如何在其中创建了许多@import
语句?这是使用 Less 为 WordPress 开发主题时的一个重要部分;Less 允许我们将可能很长的样式表拆分成更小、更易于管理的文件。
到目前为止,你可能想知道,“我如何知道将代码拆分成多少个文件?”这是一个好问题,简短的答案是:没有唯一的正确答案!让我来解释。
这一切都取决于您的样式表有多大。一个好的提示是考虑您的样式表中有哪些元素,并相应地分组。然后,您可以使用一个或多个 Less 文件;Less 会愉快地将它们编译成一个单一的样式表。在我们的例子中,我们有多个合适的组,如帖子、侧边栏、导航等;我们已将主样式表设置为为每个这些组导入单个 Less 文件。
在所有的 Less 文件中,我们已经充分利用了 Less 的嵌套功能;这是在用 Less 构建 WordPress 主题时需要掌握的关键技能之一。嵌套在开发 WordPress 主题时是非常有用的;我们可以将所有相关的样式组合在一起,这使得阅读和管理变得更加容易。
接下来;有人注意到两个关键文件的存在,即 mixins.less
和 variables.less
?这些是作为开发 WordPress 主题的一部分创建的 Less 文件的完美示例。
我们可以将所有变量存储在一个文件中,并在需要时引用它们。一个完美的例子是首先为我们的每种颜色创建变量:
// Colors
@white: #fff;
@vivid-orange: #f95812;
@desaturated-cyan: #335c64;
@gray: #666;
…
然后,我们可以在二级变量中引用颜色。如果需要更改,那么只需要更新这个文件:
// Posts
@entry-title-color: @white;
@entry-title-link: @vivid-orange;
@entry-title-link-hover: @desaturated-cyan;
@border-color: @gray;
如果我们打开 posts.less
的一个副本,我们可以看到正在使用的变量,如下面的代码所示:
.entry-header {
.entry-title {
.links(@entry-title-link, @entry-title-link-hover);
}
}
.entry-header, .entry-meta {
.links(@entry-title-link, @entry-title-link-hover);
}
.entry-header .entry-title {
.links(@entry-title-color, @entry-title-link-hover);
}
同样,我们可以将所有我们的混入(mixins)存储在一个文件中,即 mixins.less
;如果这些混入有任何更改,只需要更新一个文件,而不是多个!
进一步构建
到目前为止,你可能正在想,“太好了,我有一个可以使用的主题…” 对吗?嗯,是的,但也不完全是这样。(你肯定没料到这个…)
如果你阅读了我们新主题中的每个 Less 文件,请举手。很好。现在,如果你们真的仔细阅读了这些文件,请举手…啊!没有多少人…
这是有充分理由的——代码工作得非常完美;作为一个起点,它将满足需求。然而,有些地方可以改进;毕竟,它从未打算成为毕加索的作品!我想我应该给你留下这个小挑战:你能找到可以改进的地方吗?一个提示…变量似乎不够多…你接受挑战吗?
好吧,这里有一个更复杂的挑战:记得我提到我们会使用 Crunch! 来编译我们的代码吗?嗯,我们可以做得更好。我们在本书的其他地方使用了 Grunt,所以这里又有一个用途:我们可以用它来自动化我们的编译。
关键在于只编译 style.less
文件。虽然你可以尝试编译其他文件,但它们无疑会抛出错误,因为大多数文件都不会看到作为依赖的变量文件。
下一步是配置 gruntfile.js
,这将告诉 Grunt 只编译这个文件。然后我们可以在后台运行 Grunt watch 以允许它自动编译。我们将在本章的后面更详细地介绍整个过程。
小贴士
如果遇到困难,可以在谷歌上查找,因为那里有多个示例;jonathanmh.com/make-grunt-watch-for-lesscss-changes/
包含了 Jonathan Hethey 的一篇有用的示例博客文章。它包含了一些额外的步骤,但应该足以让你了解如何使用 Grunt 和 watch 来编译 Less 主题文件。
足够的开发了;是时候改变方向,休息一下了。让我们深入了解如何使用预构建的 Less 主题与 WordPress 一起使用。
使用预构建的 Less 主题
如果你还没有准备好从头开始构建主题,那么你可以始终使用预构建的主题。网上有数十种可供选择,要么免费,要么价格低廉。在 Google 上查找一些示例,然后尝试它们并决定它们是否符合你的要求是值得的。以下是一些帮助你开始的示例:
-
Less:这是一个来自 Jared Erickson 的简约主题,可在
jarederickson.com/less-a-free-super-minimal-wordpress-theme/
找到。 -
入门者:这个由 Roots 开发的主题支持 Less,可在 http://roots.io/starter-theme/找到。
-
白板:这是一个使用 Less 4 Framework 的主题,可从
whiteboardframework.com/whiteboard-documentation/
下载。 -
备用:这是一个付费主题,可在 Theme Forest 上找到,地址为
themeforest.net/item/spare-ultimate-multipurpose-less-theme/7520253
。
有很多主题可供使用,花些时间在 Google 上查看可用的选项并尝试它们是值得的。希望你能找到接近或符合你要求的东西。如果有幸,你可能能够通过阅读这本书获得的一些技能稍作调整!
自动化 WordPress 开发
如果你花时间开发主题,你无疑会知道这是一个手动过程,需要时间。主题通常需要仔细调整和重新测试;重新编译 Less 文件时尤其令人厌烦!
幸运的是,在开发 WordPress 主题时,有一些解决方案可以缓解一些单调乏味的体验;最受欢迎的选项是使用我们在第二章中首次遇到的包,即构建 Less 开发工具包。现在是时候重新审视使用 Grunt 了!
注意
对于经验更丰富的人来说,在网上寻找lessphp
是值得的,这是 Less 到 PHP 的移植。有代码可以直接在 WordPress 中编译,这与我们将在这项练习中涵盖的方式非常相似。
在 WordPress 开发中使用 Grunt
记得在第二章中,我们第一次遇到 Grunt 吗?
好吧,我们将再次遇到它,因为它是帮助编译 Less 文件作为 WordPress 开发一部分的完美工具。在这里使用它是完全合理的,因为毕竟我们是在编译样式表!让我们看看如何设置 Grunt 以自动编译 WordPress 样式表。
注意
为了进行这个练习,我将假设你正在使用第二章中“监视 Less 文件的变化”部分安装的 Grunt。如果你还没有安装它,现在是回到那章并完成它的好时机。
我们将使用随 WordPress 3.8.x 及以上版本一起提供的标准TwentyFourteen
主题;这个过程对其他主题也同样适用。
-
首先,打开你喜欢的文本编辑器,然后添加以下内容,并将其保存为
package.json
,位于TwentyFourteen
主题的根目录中:{ "name": "WordPress_Meets_Grunt", "version": "0.0.0", "author": "Alex Libby", "dependencies": { "grunt-cli": "latest", "grunt-contrib-concat": "latest", "grunt-contrib-uglify": "latest", "grunt-contrib-less": "latest", "grunt-contrib-watch": "latest" } }
-
接下来,我们需要创建一个 Grunt watch 文件,当 Grunt 的 watch 功能确定有变化时,它将执行一系列操作。将以下框架添加到一个新文件中,并将其保存为
gruntfile.js
,位于你的主题文件夹的根目录中:module.exports = function(grunt) { grunt.registerTask('watch', [ 'watch' ]); grunt.initConfig({ }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-less'); grunt.loadNpmTasks('grunt-contrib-watch'); };
-
基本的 Grunt 文件包含了我们将要使用的 Node 插件的引用——我们现在需要为每个插件添加配置选项。让我们首先为
grunt-contrib-concat
添加配置选项,以便将任何 JavaScript 文件合并成一个,如下所示:grunt.initConfig({ concat: { js: { options: { separator: ';' }, src: [ 'javascript/*.js' ], dest: 'public/js/main.min.js' }, },
-
接下来是
UglifyJS
的选项。在上一步骤的 concat 块下方立即添加以下代码:uglify: { options: { mangle: false }, js: { files: { 'public/js/main.min.js': ['public/js/main.min.js'] } } },
-
我们接下来需要添加的插件是最有趣的一个——Less。在上一部分的
}
关闭后立即添加以下代码:less: { style: { files: { "style.css": "style.less" } } },
-
最后,但同样重要的是,是
watch
。这部分监视代码的任何变化并调用相关命令:watch: { js: { files: ['javascript/*.js'], tasks: ['concat:js', 'uglify:js'], options: { livereload: true, } }, css: { files: ['style.less'], tasks: ['less:style'], options: { livereload: true, } } }
-
保存文件,然后在命令提示符中切换到你的主题位置。
-
我们现在需要配置 Grunt。尽管我们已经从第二章中安装了基本的应用程序,但我们仍然需要告诉它在 Less 文件发生变化时应该做什么。在命令提示符中运行以下命令:
npm install
-
最后一步是激活
watch
功能。一旦 Grunt 完成了上一步骤的变化,请在提示符中运行以下命令:grunt watch
-
记得我们在这个章节早期创建的子主题吗?回到你的子主题文件夹,然后打开
style.less
,并在样式表中更改一个字符。 -
按照常规方式保存你的工作。如果一切顺利,Grunt watch 将会检测到变化并重新编译样式表文件:
我们可以通过检查我们的theme
文件夹来确认这一点,其中style.less
和style.css
文件的日期和时间戳相同:
呼吸一下!这有一大堆代码;让我们花点时间回顾一下在这个练习中我们取得了什么成果。
如果你花过时间使用 Grunt 作为任务管理器,那么使用package.json
和gruntfile
文件对你来说应该是熟悉的;如果没有,你去了哪里?Grunt 正迅速成为自动化诸如编译 Less 文件等无趣任务的既定标准;了解 Grunt 是非常值得的!
在我们的练习中,我们已配置 Grunt 使用多个 Node 包,如 Less、watch、UglifyJS 和 concat。简而言之,Grunt 和 JSON 包文件告诉 Grunt 如何压缩和连接 JavaScript 或 Less 文件(如配置中设置的那样);watch 设置为在源文件有任何更改时立即运行任务。
只要 Grunt watch 启动并正确重新编译了我们的文件,我们就可以自由地继续进行更多更改。我们可以使用 Less 文件动态编译我们的样式表,就像我们在在 WordPress 中添加 Less 支持部分中看到的那样,或者我们可以简单地使用编译后的文件作为主题中的正常样式表。
小贴士
在 GitHub 上有一个gruntfile.js
文件的完整版本,地址为gist.github.com/alibby251/579e3c0308e3cd732b39
。
摘要
呼呼!我们在本章中涵盖了很多内容!让我们花点时间考虑一下我们学到了什么。
我们使用 Less 与 WordPress 的探索之旅以快速回顾每个 WordPress 主题的结构开始,我们检查了在 TwentyFourteen 核心主题中你会看到的基本文件,并涵盖了本章每个练习所需的基本知识。
我们开始我们的开发工作,首先查看创建子主题及其原因;然后我们学习了如何在主题中添加对 Less 的支持到你的函数文件中。
我们快速地偏离了一下,看看我们如何为特定用户定制导入;如果你作为本地管理员开发,而其他人使用编译后的 CSS 样式表文件,这将非常有用。
然后,我们继续前进,探讨了如何使用插件导入 Less;我们看到了在大多数情况下,这会被优先考虑,但在一个插件众多的网站上,可能更明智的做法是简单地使用functions.php
文件导入它。
我们随后详细探讨了将现有样式表转换为使用 Less 等价物的技巧。由于某些样式表的大小实在太大,我们强调了保持这个过程迭代的重要性。然后,我们简要地看了看如何使用 Less 创建自己的主题;我们看到了如果你还没有准备好开发自己的主题,你可以在 Less 中使用任何预构建的主题!
最后,我们通过详细探讨如何使用 Node.js 和 Grunt 自动化整个编译过程来结束我们对 Less 和 WordPress 的旅程。虽然这最初可能看起来令人畏惧,但它将极大地回报你的努力,节省编译 Less 文件的时间!
就在这个时候,我们告别了 WordPress 的使用。在我们接下来的章节中,我们将介绍另一个使用 Less 的知名产品:Twitter Bootstrap。现在,我想问问,谁还没有听说过 Twitter 呢?
第十章:使用 Less 与 Bootstrap
要使用 Bootstrap 还是不要使用 Bootstrap,这是一个问题...
除了莎士比亚的《哈姆雷特》中的明显误引之外,许多开发者可能会问自己是否想要在他们的下一个项目中使用框架。
框架的一个明显优势是它们可以帮助您非常快速地将网站搭建起来——Bootstrap 也不例外。作为 Twitter 为统一其内部项目而开发的内部工具,Bootstrap 迅速成为 GitHub 上排名第一的项目,其用户群体包括 NASA 和 MSNBC。
那么,为什么在关于 Less 的书中要谈论这个呢?很简单;正如您将发现的,Bootstrap 是基于 Less 构建的;它是帮助您习惯使用 Less 的完美工具。在本章中,我们将涵盖以下主题:
-
Bootstrap 的 Less 文件结构
-
Bootstrap 的混入
-
为您的网站配置 Bootstrap
-
开发使用 Bootstrap 的工作流程
好奇吗?让我们开始吧...!
解构 Bootstrap 的 Less 文件结构
因此,您已经决定冒险使用 Bootstrap;它,就像互联网上可用的许多其他框架一样,是帮助快速搭建网站的好方法。然而,本章是关于 Less 在 Bootstrap 中的应用,对吧?绝对如此;Less 在生成用于样式化 Bootstrap 库中每个元素的 CSS 中发挥着关键作用。为了了解这一点,让我们更详细地查看库。首先,我们将从官方网站下载它。
下载库
我们首先需要下载库的一个副本——为此,请访问 getbootstrap.com/
并点击下载 Bootstrap。Bootstrap 库在撰写本文时处于版本 3.2.0,可以通过多种方式获得,包括通过 CDN 或使用 Bower。
我们感兴趣的版本是源代码版本,所以请点击源代码并保存存档的副本到安全的地方。一旦下载,将内容的一个副本提取到您的硬盘驱动器上——在打开存档时,我们将看到以下内容:
我们感兴趣的文件夹自然是 less
文件夹——如果我们打开它,我们可以在文件夹内看到一系列 Less 混入文件。
有许多 Less 文件包含我们可以用于构建启用 Bootstrap 网站的混入(mixins),它们可以分为四个类别,即:
-
工具
-
布局
-
皮肤
-
组件
我们将在本章后面的解构 Bootstrap 的混入部分中涵盖这些类别。同时,让我们继续前进,熟悉在您的网站上安装 Bootstrap。
为您的网站配置 Bootstrap
虽然我们已经下载了 Bootstrap 的源代码版本,但这并不是您默认会使用的版本。
嘿?我听到你在问。你完全有理由这样做——毕竟,下载了你不会使用的东西有什么意义,对吧……?好吧,我们将在本章后面使用它;现在,知道这包含了构成 Bootstrap 样式的所有混合器,并且这些混合器可以在以后日期轻松自定义就足够了。
目前,我们将使用编译版本。在章节后面的“构建更真实的网站”部分,我们将看到当我们直接访问 Bootstrap 混合文件时会发生什么效果。
让我们改变一下方向,看看添加 Bootstrap 到你的网站需要什么:
-
首先,在你的硬盘上创建一个新的文件夹,并将其命名为
projects
。 -
将我们在上一节中下载的
bootstrap
文件夹的内容复制到这个文件夹中。 -
打开你选择的文本编辑器,并添加以下代码:
<!DOCTYPE html> <html lang="en"> <head> <title>Bootstrap Demo</title> </head> <body> <h1>Hello, world!</h1> </body> </html>
-
接下来,在
</head>
标签之前添加以下行——这些是由 Bootstrap 用于使网站响应式的:<meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1">
-
我们需要添加 Bootstrap 的基本样式,所以请立即在关闭
</head>
标签之前添加以下行:<link href="css/bootstrap.min.css" rel="stylesheet">
-
将文件保存为
bootstrap.html
在projects
文件夹中——如果我们预览结果,我们会看到这样:
当然,这不会让世界变得不同,但它确实说明了安装 Bootstrap 是多么容易!我们将在本章后面的“构建更真实的网站”部分深入探讨一个真实世界的例子。需要记住的关键点是,Bootstrap 是一组有效的 CSS 样式规则——只要我们在代码的适当位置使用适当的规则,我们就可以使用它们来制作任何东西。Bootstrap 对于帮助构建基本网站非常理想;然后它为我们提供了在以后日期将其发展成为更复杂事物的基石。
使用 Internet Explorer 8 或以下版本
在我们查看制作更详细的内容之前,我们需要在使用 Bootstrap 时注意一些事情——这关系到我们老朋友,也就是 Internet Explorer。
之前的演示在现代浏览器中可以完美工作——值得注意的是,如果你仍然需要使用 IE8,那么你需要在你的 <head>
部分添加以下代码:
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src = "https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js">
</script>
<script src = "https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js">
</script>
<![endif]-->
Internet Explorer 8(或更低版本)默认不支持 HTML5,因此我们需要使用两个 JavaScript 库来为 HTML5 和媒体查询提供回退支持。
好的;你还在吗,我希望?好的;让我们继续。这是一个深入研究使用 Bootstrap 构建更真实示例的绝佳机会。
构建更真实的网站
虽然我们可以使用 Bootstrap 来制作各种不同的网站,但 Bootstrap 真正发挥其作用是在用于模拟网站时。即使颜色一开始并不完美,至少也能感受到页面或网站在布局方面的样子。这并不是说颜色方案应该被忽视;一旦我们有了网站布局的清晰想法,它们可以随后进行。
为了说明 Bootstrap 在创建模拟页面方面的有用性,我们将查看创建一个可以作为博客文章或网站上的在线文章的示例页面。为了这个示例的目的,我们需要这本书附带的代码下载的副本——它包含所需的 HTML 标记的副本;由于空间原因,我们无法在文本中全部复制!好吧——现在我们已经有了代码下载的副本,让我们开始吧:
-
从代码下载中提取
blogpage.html
文件的副本,它包含我们示例页面的 HTML 标记。将文件保存在我们在上一个练习中创建的projects
文件夹中。 -
打开你选择的文本编辑器,然后将以下行添加到文件的
<head>
标签中:<meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Bootstrap Theme Demo</title> <link href="css/bootstrap.min.css" rel="stylesheet"> <link href="css/bootstrap-theme.min.css" rel="stylesheet">
-
接下来,我们需要下载一个小型的 JavaScript 文件——这是 Ivan Malopinsky 的 Holder 插件。这个插件对于运行 Bootstrap 不是必需的,但它为图像占位符提供了很好的效果。Holder 可以从
github.com/imsky/holder/zipball/v2.3.2
下载,并将holder.js
从存档中提取到我们projects
文件夹内的js
文件夹中。提示
代码下载中有一个这个插件的压缩版本,存储为
docs.min.js
。 -
保存
blogpage.html
—如果我们在一个浏览器中预览结果,我们就可以看到我们模拟的页面在所有细节上的完美展示。
那么,这里发生了什么?虽然看起来我们有很多代码,但实际上,我们只有一个重要的代码块:
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
...
<link href="css/bootstrap.min.css" rel="stylesheet">
你可能会问,这为什么如此重要?好吧,这很简单——Bootstrap 是关于提供一套完整的样式功能集,可以帮助你快速启动。Bootstrap 并不是要永久替代,但它是一个很好的起点来开发你自己的样式。确实,正如我们将在第十一章中看到的那样,使用 Less 抽象 CSS 框架,仅仅依赖 Bootstrap 并不总是好事!
在这个例子中,我们设置了三个元标签——这些标签处理要使用的字符集、在显示页面时应支持 IE 的版本以及移动设备上的网站显示。
注意
如果你想要了解更多关于 IE 兼容性和视口标签的信息,那么阅读微软在www.modern.ie/en-us/performance/how-to-use-x-ua-compatible
上的文章是值得的,该文章描述了设置此标签的最佳实践。Mozilla 有一篇有用的文章介绍了如何在代码中应用视口标签,你可以通过访问developer.mozilla.org/en/docs/Mozilla/Mobile/Viewport_meta_tag
来查看。
前两个可以在大多数网站上看到——真正有趣的是指向 Bootstrap CSS 文件的链接。这是一个预编译文件,包含了 Bootstrap 的样式,这些样式是从构成库的 Less 混入生成的。我们在代码中引用了它,并使用它来应用 HTML 标记中定义的样式。
注意
然而,值得注意的是,如果你想使用 Bootstrap 附带的一些 jQuery 插件,那么你还需要添加对 jQuery 本身的链接以及 Bootstrap 插件的链接:
<script src="img/jquery-2.1.1.min.js"></script>
<script src="img/bootstrap.min.js"></script>
如果你仍然需要支持 IE8 或更低版本,那么将 jQuery 的引用更改为jquery-1.11.1.min.js
;jQuery 2 版本在这些早期版本的 IE 中不受支持。
编译 Bootstrap 的 CSS 和 JavaScript
现在我们已经看到了 Bootstrap 如何有效地帮助我们启动网站,我们可以决定想要从仅仅使用预编译的 CSS 文件转向自己编译代码。
做这件事的主要原因是为了更新或修改代码以适应我们的需求——我们不应该忘记 Bootstrap 旨在以这种方式进行定制!幸运的是,Bootstrap 使用 Grunt,我们之前在书中讨论并安装了它(在第二章,构建 Less 开发工具包)。Bootstrap 自带预配置的package.json
文件,使得编译变得非常简单。我们只需要做的是:
-
打开一个命令提示符窗口,然后导航到
/bootstrap
文件夹的根目录,并输入以下命令:npm install
这将自动安装编译 Bootstrap 所需的全部依赖。
-
在同一个命令窗口中,输入以下内容:
grunt
这将运行 JSHint 和 QUnit 测试,并将 CSS 和 JavaScript 文件编译到 Bootstrap 文件夹内的
/dist
文件夹中。
这很简单,对吧?好,让我们继续前进,认识一下 Bootstrap 自带的一些混入(mixins)。
检查 Bootstrap 的混入
在本章的开头,我们简要地看了 Bootstrap 库下载的文件结构;现在是一个深入了解这个结构的绝佳机会。
如果我们打开下载的存档的副本并导航到 less
子文件夹的根目录,我们可以看到这些混合器分布在 29 个混合器文件中,可以分为以下类别:工具类、组件、皮肤和布局。
大多数这些混合器都关注于提供 Bootstrap 的核心样式——特别值得注意的是:
-
bootstrap.less
: 这是主 Less 文件,当编译和压缩后,将形成bootstrap.min.css
-
theme.less
: 这包含了一些核心主题样式
注意,如果你直接从 GitHub 下载 Bootstrap 版本,你会注意到这个额外的文件夹:
这个文件夹包含了控制主题样式的混合器;如果我们查看文件夹内部,我们会看到一些额外的混合器,这些混合器用于创建生产下载文件中将成为 bootstrap-theme.min.css
的内容。
如果我们进一步探索这个文件夹,我们会看到其中存储的大多数文件都有与核心混合器相同的名称,但它们包含的样式是 Bootstrap 中主题的基础。值得注意的是,这些混合器不是在 www.getbootstrap.com
可用的 Less 下载存档的一部分;要使用它们,我们需要直接从 GitHub 下载并使用 Grunt/Node.js 编译。
注意
Bootstrap 中可用于的所有混合器都存储在 \less
子文件夹中——你还可以在 GitHub 上查看原始源文件版本,地址为 github.com/twbs/bootstrap/tree/master/less
。变量存储在 variables.less
中——这在上文提到的 \less
文件夹中,并在 GitHub 上可访问 github.com/twbs/bootstrap/blob/master/less/variables.less
。
现在我们已经看到了库的构成,让我们花点时间反思一下库中可用的某些混合器。
解构 Bootstrap 的混合器
如果我们要查看 Bootstrap 中可用于的混合器,我们可以看到它们被分成几个组。这些组包括:
-
核心变量和混合器
-
重置和依赖
-
核心 CSS
-
组件文件
-
使用 JavaScript 的组件文件
-
工具类
让我们逐一详细地看看每一个,从核心变量和混合器开始。
核心变量和混合器
核心变量和混合器可能是所有混合器中最小的一组,但却是最重要的——它包含了 variables.less
,其中列出了 Bootstrap 中可用的所有预定义变量。这个组中包含的第二个文件是 mixins.less
。虽然它的设计更简单,但同样扮演着重要的角色:它包含了用于构建 bootstrap-theme.css
文件的 @import
语句。
重置和依赖
在分组中接下来的是重置和依赖混合,引用一句俗语,这些“名副其实”!Normalize.less
使用了 Nicolas Gallagher 创建的normalize.css
项目,该项目也可在 GitHub 上找到,并可以从github.com/necolas/normalize.css
下载。
如果我们将网站设置为可打印的,那么print.less
是必不可少的;它包含将 Bootstrap 重新对齐所需的媒体查询,以便允许打印。Glyphicons.less
是库的有用部分——它控制显示 Bootstrap 库中包含的任何图标的样式。
核心 CSS 样式
在接下来的分组中,我们有一些执行不同角色的混合文件:
混入文件名 | 用途 |
---|---|
scaffolding.less |
控制基本网站上的元素,直接或间接(通过引用其他混合文件的样式) |
type.less |
设置 H1 到 H6 字体大小的默认字体大小,以及一些额外的样式,如警告或信息文本 |
code.less |
使用如<code> 和<pre> 等标记时确定样式 |
grid.less |
设置用于控制 Bootstrap 响应式网格功能的基本样式 |
tables.less |
控制我们插入网站中的任何表格的样式 |
forms.less |
将样式应用于我们网站内托管的所有表单 |
buttons.less |
设置应用于我们网站上任何按钮的基本样式 |
组件
到目前为止,我们查看的大多数样式都涵盖了网站的结构;让我们看看组成我们可以添加到任何网站中的视觉元素的组件文件:
混入文件名 | 用以定义样式 |
---|---|
component-animations.less |
对网站上的任何组件进行动画处理 |
dropdowns.less |
下拉菜单 |
button-groups.less |
分组按钮 |
input-groups.less |
输入字段 |
navs.less, navbar.less |
导航栏和按钮 |
forms.less |
表单和非表单元素 |
breadcrumbs.less |
面包屑路径 |
pagination.less, pager.less |
网站中的分页 |
labels.less |
各种标签样式,例如警告或危险样式 |
badges.less |
按钮或导航中的徽章 |
jumbotron.less |
巨幕 |
thumbnails.less |
缩略图图像和标题 |
alerts.less |
警告信息和对话框 |
progress-bars.less |
进度条 |
media.less |
媒体对象,如视频和图像 |
list-group.less |
分组或链接列表中的项目 |
panels.less |
面板和面板元素,例如标题 |
responsive-embed.less |
响应式嵌入项目,如 iFrames |
wells.less |
Wells |
close.less |
关闭图标 |
工具类
核心 Bootstrap 文件中的最后一组包含的是实用工具类——这些存储在 utilities.less
和 responsive-utilities.less
中。这些文件包含一些与任何其他混合文件不直接相关的样式,但仍然在 Bootstrap 网站上发挥作用。例如,.clearfix()
混合和用于切换内容的混合。
现在让我们改变焦点,关注构成 Bootstrap 主题样式的混合文件。
拆解 Bootstrap 的主题混合
除了核心样式和混合之外,Bootstrap 还提供了一些额外的混合,这些混合被整合到 Bootstrap 主题的 JavaScript 和 CSS 文件中。
您可以在 GitHub 仓库中 less
文件夹下的 mixins
子文件夹中查看这些内容——值得注意的是,当从 www.getbootstrap.com
下载文件时,这些内容不会出现在“源代码”选项中。让我们看看这个文件夹里有什么——混合分为几个组。
通用工具
混合文件名称 | 用途 |
---|---|
hide-text.less |
在使用 CSS 图像替换时隐藏图像 |
opacity.less |
设置透明度级别 |
image.less |
使图像响应式。 |
labels.less |
定义标签的颜色 |
reset-filter.less |
当移除渐变背景时,为 IE 重置过滤器 |
resize.less |
如果溢出不可见,则调整任何元素的尺寸 |
responsive-visibility.less |
为 responsive-utilities.less 提供响应式状态 |
size.less |
使用快捷混合设置对象的高度和宽度 |
tab-focus.less |
为标签添加 Webkit-style 焦点 |
text-emphasis.less |
为文本添加强调 |
text-overflow.less |
处理文本溢出——需要设置 display: inline 或 display: block 以实现适当的样式 |
组件
尽管我们现在已经定义了大多数 Bootstrap 组件所需的样式,但仍有一些样式是特定于主题文件的;这些样式在以下混合组中处理:
混合文件名称 | 用途 |
---|---|
alerts.less |
设置警告中的背景、边框和前景色值,以及 <hr> 元素和警告内的链接。 |
buttons.less |
创建默认样式,以及 :hover 、:focus 、:active 和 disabled 样式按钮。 |
panels.less |
定义用于面板元素的色彩。 |
pagination.less |
处理页面分页的样式设置。 |
list-group.less |
定义选择或悬停在列表元素上时使用的样式。 |
nav-divider.less |
设置下拉菜单或导航列表中的分隔符。 |
forms.less |
生成用于表单的验证样式。 |
progress-bar.less |
为进度条设置背景色。 |
table-row.less |
设置用于控制表格行外观的额外样式。 |
皮肤
到目前为止,我们已经定义了许多主题样式;其中一些是在应用 Bootstrap 主题文件时添加的:
Mixin 文件名称 | 描述 |
---|---|
background-variant.less |
此 mixin 在悬停时设置并加深背景颜色。 |
border-radius.less |
随着border-radius 的本地浏览器支持的到来,此 mixin 并非严格必需,但为了以成对的方式设置半径值,它是有用的。 |
gradients.less |
此 mixin 设置了多种渐变格式的样式,例如条纹和径向渐变。 |
布局
任何主题的关键部分是将元素正确地定位在页面上;这个 mixin 组合处理了 Bootstrap 主题的这个问题:
Mixin 文件名称 | 用于 |
---|---|
clearfix.less |
实现由 Nicholas Gallagher 在 nicolasgallagher.com/micro-clearfix-hack/ 创建的微清除浮动技巧 |
center-block.less |
在主题中居中对齐块级元素 |
nav-vertical-align.less |
在导航栏中垂直居中元素 |
grid-framework.less |
从任何给定的@grid-columns 值生成正确的网格类数量。由 Bootstrap 提供 |
grid.less |
生成语义网格列 |
现在我们已经了解了库的构成,我们可能很想知道是否可以使用库中的不同元素,而不仅仅是将库直接集成到我们的代码中,这样会浪费资源。然而,如果我们想实际更改一些默认样式,而无需下载所有内容呢?幸运的是,这是可能的——让我们看看如何自定义您的 Bootstrap 下载。
自定义我们的下载
到目前为止,我们使用了 Bootstrap 的标准下载——虽然这为我们服务得很好,但开始引入我们自己的样式可能会有些尴尬。
幸运的是,Bootstrap 团队为我们提供了一种方法,允许我们构建自定义下载;虽然可能需要一点工作来确定要输入的值,但它至少允许我们根据喜好调整值!让我们看看它是如何工作的。
注意
在这样做之前,我们需要对我们的代码进行一个小小的修改——打开你的blogpage.html
副本,并注释掉这一行:
<link href="css/bootstrap-theme.css" rel="stylesheet">
现在,不必担心。为什么?所有的一切很快就会变得清晰!
首先,浏览 getbootstrap.com/customize/#less-variables-section
——在这里,我们可以看到一系列我们可以选择包含或排除在下载中的选项。如果你花过时间使用 jQuery UI,那么这个过程应该很熟悉——这是一个选择或取消选择适当的复选框以包含我们下载中所需组件的问题。
这是一个三步过程——让我们首先选择我们想要在下载中使用的基 CSS、组件和实用工具。
接下来,我们需要更改我们打算包含在下载中的每个组件的值。一个很好的例子是 按钮 部分——我们创建了一个按钮作为我们评论表单的一部分,所以让我们继续更改图像上的颜色,作为我们的定制下载的一部分。
让我们回到之前深入研究的 blogpage.html
演示——如果我们使用 DOM 检查器,例如 Firebug,查看按钮的源代码,我们可以看到正在使用的类。
我们可以清楚地看到正在使用的两个类——基础 .btn
和 .btn-primary
。使用 DOM 检查器,例如 Firebug,我们可以看到 .btn
的编译样式:
.btn {
-moz-user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
cursor: pointer;
display: inline-block;
font-size: 14px;
font-weight: normal;
line-height: 1.42857;
margin-bottom: 0;
padding: 6px 12px;
text-align: center;
vertical-align: middle;
white-space: nowrap;
}
单独来看,这不会展示太多——一旦我们查看 .btn-primary
类,它就会真正开始有意义:
.btn-primary {
background-color: #428bca;
border-color: #357ebd;
color: #fff;
}
在这个阶段,如果我们浏览 getbootstrap.com/customize/#less-variables
,我们就可以看到我们下载中可以自定义的所有 Less 变量。我们可以看到 #428bca
的值是由 @btn-primary
的值设置的。
然而,不那么容易注意到的是 #357ebd
的设置方式——这个值是通过 @btn-primary-border
变量设置的,它被加深了 5%。
小贴士
要查看颜色变亮或变暗的效果,请访问十六进制颜色工具网站 www.hexcolortool.com
,输入你的十六进制值(不带井号),然后点击 变亮 或 变暗 以查看一系列颜色及其值。
我们还可以看到按钮的颜色是如何设置的——值得浏览 GitHub 上的 buttons.less
混合文件 github.com/twbs/bootstrap/blob/master/less/buttons.less
,在那里我们可以看到第 60 行的混合效果:
.btn-primary {
.button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);
}
现在我们已经看到了变量是如何链接到混合的,让我们通过为我们的按钮设置一个漂亮的红色阴影来更改我们的下载。
修改下载中的值
修改 Bootstrap 的代码下载非常简单——我们只需选择我们的主颜色,更改已显示的颜色,然后在页面底部点击 下载 以获取我们的定制库。现在让我们来做这件事——你会看到有多简单:
-
首先,浏览
getbootstrap.com/customize/#less-variables
并更改@brand-primary
的值为#be0000
,如图所示: -
接下来,滚动到页面底部,点击 编译和下载—当提示保存文件夹时,将其保存到安全位置。
我们现在有了库,但需要更新我们的代码。记得我让你注释掉引用
bootstrap-theme.css
文件的行吗?好吧,这就是原因:定制的下载只适用于核心样式,而不适用于已应用的主题。如果我们没有注释掉这一行,那么我们的更改将是多余的——主题会覆盖它! -
到目前为止,请继续在我们的项目文件夹中重命名 CSS 文件夹——打开我们刚刚下载的存档文件,并将
css
文件夹复制到项目文件夹中。
如果我们浏览blogpage.html
文件的副本并刷新屏幕,我们可以看到提交按钮上使用的更新后的颜色。
如果我们打开一个 DOM 检查器,例如 Firebug,我们可以看到代码已经更改:
.btn {
...
border: 1px solid transparent;
...
}
查看.btn-primary
样式,我们可以看到由于我们的 CSS 更改而产生的新值:
.btn-primary {
background-color: #be0000;
border-color: #a50000;
color: #fff;
}
.btn-primary {
background-image: linear-gradient(to bottom, #be0000 0px, #810000 100%);
background-repeat: repeat-x;
border-color: #700;
}
我们可以更改很多样式——世界是我们的牡蛎!为了帮助更改颜色,改变现有的十六进制颜色代码比替换显式颜色函数更容易。如果我们保留计算语句不变,那么我们可以确保它们正确渲染更新颜色的正确色调,例如:hover
。
小贴士
伴随本书的代码下载中包含了一个修改过的 CSS 文件夹版本,它包含了这种颜色更改。你需要提取REDcss
文件夹的副本并重命名它,以替换 Bootstrap 附带默认的css
文件夹。
让我们改变一下节奏,继续前进——使用 Bootstrap 的一个关键部分是开发你自己的工作流程过程;虽然没有正确或错误答案,但我们将查看一个你可以为你的项目开发的例子。
开发使用 Bootstrap 的工作流程
现在我们已经看到了如何为创建基本网站配置 Bootstrap,我们使用 Bootstrap 的旅程中的最后一个关键阶段是开始开发一个帮助我们尽可能高效的工作流程。
最终,设计我们的工作流程将是一件非常个人化的事情——同样的方法并不适合每个人!关键在于找到适合你的方法;为了给你一个如何着手的方法,值得阅读 Erik Flowers 的一篇文章,该文章可在www.helloerik.com/bootstrap-3-less-workflow-tutorial
找到。
总结来说,他的工作流程集中在以下步骤:
-
从
www.getbootstrap.com
下载 Bootstrap 库的副本。 -
决定你想要使用哪种方法来编译你的 Less 文件——是使用像 Crunch!这样的预处理器应用程序,通过命令行,还是作为 Sublime Text 等编辑器的附加包?
-
创建一个源文件夹来存放你的 Less 文件——名称不是关键,只要你知道它存储了什么和在哪里。
-
在源文件夹中创建一个名为
vendor
的文件夹,并将 Bootstrap Less 文件的副本存储在其中——这是为了帮助你避免修改核心文件,这些文件在升级 Bootstrap 时会被覆盖。 -
在你的源文件夹中,创建一个名为
styles.less
的文件,该文件导入bootstrap/bootstrap.less
。 -
将所需的任何其他 Less 文件存储在顶级源文件夹中,然后使用相同的格式将它们导入到
styles.less
中。 -
将你的 Less 样式规则添加到这些单独的文件中,而不是
styles.less
文件中。 -
将
styles.less
编译到你想引用styles.css
的任何位置;根据需要,单独或作为使用 Grunt 等包的一部分来最小化或压缩文件。
虽然涉及几个步骤,但这应该能让你对示例工作流程有一个感觉——值得注意的是,其中一些可以,潜在地,自动化;这个问题的关键是确保它与你的开发工作流程中现有的任何流程相匹配。
摘要
对于最初是为 Twitter 内部使用而创建的项目,Bootstrap 迅速成为 GitHub 上世界上最受欢迎的项目之一。让我们花点时间回顾一下本章中我们涵盖的内容。
我们的旅程从下载库开始,然后配置它在我们的项目中使用。然后我们创建了一个基本示例来展示如何轻松地将它添加到项目中;然后我们将其发展成一个更现实的示例,以便更好地展示 Bootstrap 的外观。
我们继续前进,探讨了如何轻松编译 Bootstrap 的混入(mixins)以生成有效的 CSS 代码;然后我们覆盖了代码下载中的less
文件夹的结构,以便查看可用的混入以及它们如何构成 Bootstrap。然后我们通过深入了解如何自定义下载来更好地满足我们的需求,完成了对 Bootstrap 的探讨。
让我们继续前进——在下一章中,我们将探讨如何使用 Less 抽象 CSS 框架,以及为什么使用 Bootstrap 实际上并不像最初看起来那么好!
第十一章。使用 Less 抽象 CSS 框架
回到 2011 年底,流行的社交网站 Twitter 发布了 Bootstrap——这个框架留下了如此深刻的印象,它很快成为了 GitHub 上最受欢迎的项目!
任何花时间开发过的人至少都听说过 Bootstrap,即使他们还没有机会使用它。在前一章中,我们简要地介绍了 Bootstrap,并说明了它是如何使用 Less 将规则编译成有效的 CSS,以及你可以如何实验性地使用可用的许多混入来创建自己的样式。
问题在于,作为一个框架,Bootstrap 并非没有自己的缺陷——它鼓励我们用几十个类来超载 HTML!这与过去十年中发展起来的趋势相悖,即内容应该与表现分离。在本章中,我们将看到为什么这是不好的做法,以及我们如何通过巧妙地使用 Bootstrap 的混入来解决这一问题。
在本章中,我们将涵盖以下主题:
-
发现使用框架的问题
-
保持你的 HTML 清洁
-
简化复杂样式
想要了解更多?让我们开始吧…!
发现使用框架的问题
回想一下前一章,我们介绍了 Bootstrap,并说明了 Less 是如何用来创建编译成干净、语义化 HTML 的样式的…Bootstrap 看起来不错,易于使用,并为我们的网站提供了一个美好、一致的主题,对吧?
错误——它有一个特别棘手的问题:Bootstrap 直接在 HTML 中嵌入 CSS 类。我们可以争论这并没有什么问题,除了使用的样式名称并不总是语义化的!
提供语义代码的整个概念已经多年来一直处于开发者的思维前沿。一些框架,如 Scaffold(用于 PHP)或 Compass(用于 Ruby),早在 2009 年就认识到了这个问题,然而 Bootstrap 仍然强迫我们在 HTML 代码中使用非语义的 CSS 样式。为了了解这一切的含义,让我们深入探讨,看看一个示例,并了解我们如何使用 Less 来纠正这个问题。
诊断问题
为了更直观地看到问题,我们需要查看一个启用 Bootstrap 的网站的源代码;具有讽刺意味的是,主要的 Bootstrap 网站有几个示例,清楚地显示了这个问题!
首先,导航到getbootstrap.com/examples/blog/
,这是 Bootstrap 博客主题的演示网站。在页面上任何地方右键单击以选择浏览器中看到的源代码。如果你滚动到第 42 行或附近,你会看到以下内容:
在截图上,第 50 行和第 52 行已被突出显示,这是非语义代码的完美示例;添加的这三种样式都属于 Bootstrap。你可能会问:“为什么我们不能使用它们,它们显然是 Bootstrap 的一部分?”
注意
如果你想了解分离标记的好处,那么不妨看看杰弗里·泽尔达曼(Jeffery Zeldman)所著的《使用 Web 标准》(Designing with Web Standards)这本书(从第 3 版开始,伊森·马科特也参与了编写)。
答案很简单——HTML 标记应该描述内容的含义,而不是其他任何内容。我们在这个代码片段中遇到的问题有两个:
-
这使得更新任何代码样式变得困难——如果需要更改样式,那么必须在网站上的每个出现位置进行更改。对于一个小型网站来说,这最多是繁琐的,但如果网站很大,那就成了噩梦!
-
将 Bootstrap 的样式名称硬编码到你的 HTML 代码中意味着你现在依赖于 Bootstrap。如果 Twitter 更改了 Bootstrap 的类(这已经发生了),那么你刚刚给自己带来了一大堆不必要的麻烦。
注意
总是关注代码中使用的版本是一个好主意,而不仅仅是使用最新版本。遵循后一种做法会让你容易遇到麻烦!
幸运的是,我们困境的答案就藏在 Bootstrap 本身及其一系列混入(mixins)中。我们可以在代码中不直接使用 Bootstrap 的类名,而是通过创建更多语义化的名称,并将 Bootstrap 类应用到这些名称上,从而在代码中抽象出一个层。为了了解这将如何工作,让我们通过几个简单的示例来探讨,以 Bootstrap 的 Jumbotron 主题演示作为我们更改的基础。
保持 HTML 代码整洁
如果我们查看 Bootstrap 的 Jumbotron 示例的源代码,我们可以清楚地看到一些非语义示例,类似于在 Blog 示例中使用的那些;我们将以此为基础,探讨我们可以用来修复问题的解决方案。
有三个对我们来说有趣的示例;第一个在 67 行:
<div class="row">
下一个示例紧接着在 68 行:
<div class="col-md-4">
我们将要查看的第三个也是最后一个示例,出现在 71、76 和 81 行:
<p><a class="btn btn-default" href="#" role="button">View details »</a></p>
不言而喻,还有更多的示例存在;你可以看到我们的三个选定的示例分别在哪里被使用:
所有这三个示例都使用了过于具体的名称,这些名称描述的是它们的功能,而不是它们应用到的内容。我们可以轻松地将使用的样式名称更改为更具语义性的名称,使用一种可以在代码的其他地方轻松重用的技术。
让我们看看这项技术是如何工作的;它基于直接引用作为 Bootstrap 库一部分包含的 Less 混入。
修复代码
在我们开始编辑任何代码之前,我们首先需要下载这本书附带代码的副本。在这里,我们将找到一个(未经过滤的)Jumbotron 主题副本,我们可以用它来完成这个练习:
为了这个练习的目的,我将假设你已经提取了本章所附带的代码副本,并将其存储在一个名为jumbotron
的文件夹中,以便进行编辑。我们还需要一份 Bootstrap 库的副本,我们可以从主网站getbootstrap.com/getting-started/#download
下载,然后点击源代码选项下的下载源代码。
假设我们已经一切准备就绪,让我们开始吧:
-
打开我们从 Bootstrap 网站下载的 zip 存档文件,然后提取
less
文件夹,并将其复制到我们的jumbotron
文件夹中。 -
在一个单独的文件中,添加以下代码,将其保存为
semantic.less
,位于jumbotron
文件夹内的css
子文件夹中:@import "../less/variables.less"; @import "../less/mixins.less"; @import "../less/buttons.less"; @import "../less/grid.less"; .wrapper { .container; } .left-content { .make-md-column(4); } .middle-content { .make-md-column(4); } .right-content { .make-md-column(4); } .heading-row { .make-row(); .clearfix; }
-
现在,我们需要更改我们的 HTML,所以打开
jumbotron.html
并添加以下高亮行:<!-- Custom styles for this template --> <link href="css/jumbotron.css" rel="stylesheet"> <link href="css/semantic.css" rel="stylesheet"> </head>
-
接下来,我们将重命名三个列中的每一个;向下移动并查找第一个
<div class="col-md-4">
标签,它位于第 60 行左右。这可以删除并按照以下代码进行替换;你还需要在代码的下方重复两次:<div class="container"> <!-- Example row of columns --> <div class="row"> <div class="left-content"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="btn btn-default" href="#" role="button">View details »</a></p> </div>
-
我们的第三个更改涉及到标题行容器;
row
并不足够具有语义性,因此我们将对其进行更改:<!--<div class="container">--> <div class="wrapper"> <!-- Example row of columns --> <div class="heading-row"> <div class="left-content"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="view-details" href="#" role="button">View details »</a></p> </div>
-
我们最后的更改涉及到用于包裹三个列的
<div>
标签。容器并不特别具有语义性,因此我们将将其更改为使用wrapper
作为替代。请先删除容器DIV
行,然后按照以下所示进行替换:<div class="wrapper"> <!-- Example row of columns --> <div class="heading-row"> <div class="left-content"> <h2>Heading</h2>
如果我们在浏览器中预览结果,我们不应该期望在视觉上看到任何变化,但可以放心地知道我们已经开始在代码中使用更具语义的类名。
这里有一个非常合理的观点——问为什么我们在这里使用wrapper
而不是container
是一个完全合理的问题。我们同样可以使用任何一个,这都没有问题。不过,我的偏好是使用wrapper
,纯粹是因为它包含了所有的代码(或多或少!)。
探索我们的解决方案
因此,现在我们已经在我们的示例中有了语义代码,这意味着什么以及它是如何工作的?这基于两个关键元素:一个是替换,另一个是了解我们可以使用的可用的 Bootstrap 混入(mixins)。
在这个例子中,我们利用了构成 Bootstrap 中创建列和行的基础的 Less 混入组。我们首先导入四个 Less 文件,这些文件包含我们需要使用的混入,然后创建四个新的样式(形式为left-content
、middle-content
、right-content
和heading-row
),并将make-md-column
、make-row
或clearfix
混入适当地分配。为了确保我们的 HTML 反映了这些更改,我们随后用新的、更具语义的样式名称替换了原始样式。
简化复杂样式
我们可以在我们的代码中进一步抽象和简化正在使用的表示类;例如,我们将编辑代码以替换代码中两种按钮类型所使用的 CSS 样式名称:
-
让我们先再次打开
jumbotron.html
文件。在这里,我们需要删除以<p><a class="btn btn-default"
开头的行,并按指示进行替换:<!--<div class="container">--> <div class="wrapper"> <!-- Example row of columns --> <div class="row"> <div class="left-content"> <h2>Heading</h2> <p>Donec id elit non mi porta gravida at eget metus. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Etiam porta sem malesuada magna mollis euismod. Donec sed odio dui. </p> <p><a class="view-details" href="#" role="button">View details »</a></p> </div>
-
我们还需要更改分配给 了解更多 按钮的当前类,所以请按照所示进行修改:
Use it as a starting point to create something more unique.</p> <p><a class="learn-more" role="button">Learn more »</a></p> </div>
-
现在我们已经分配了新的样式名称,让我们重新工作
semantic.less
中列出的 Less 样式规则,以反映我们 HTML 中的更改,通过将相关的混合分配给我们的样式类:.learn-more { .btn; .btn-primary; .btn-lg; } .view-details { .btn; .btn-default; }
保存文件。如果一切顺利,我们的代码将看起来像这个截图提取:
如果我们在浏览器中预览我们的工作结果,我们不应该期望在视觉上看到任何差异,但要知道我们的代码现在更加语义化。这并不意味着我们只能做这些更改;在这个例子中,肯定还有更多的空间去做;这是我将留给我的读者们去解决的问题,但我会给你一个提示:查看导航…
同时,让我们花点时间来探索我们在这里所取得的成果——我们使用了本章前面在 探索我们的解决方案 部分中概述的相同解决方案。
在这种情况下,我们利用了构成 Bootstrap 中按钮支持的 Less 混合组。我们所做的就是在我们 Less 代码中创建了一个新的样式规则,称为 .learn-more
,然后分别将其分配给之前使用的三个 Less 混合:.btn
、.btn-primary
和 .btn-lg
。
注意
需要注意的是,由于 Bootstrap 对 CSS 类的期望,这个过程不适用于分组按钮;查看 stackoverflow.com/questions/24113419/
和 stackoverflow.com/a/24240819
,了解一些关于为什么这不适合分组按钮以及如何绕过它的有用讨论。
关键是要将它们按正确的顺序排列,以便我们保持与之前相同的外观。只要我们这样做,页面的外观就不应该有任何变化。然后,我们用 .view-details
按钮重复了同样的过程,但这次,我们给它分配了 .btn
和 .btn-default
样式。
注意
jumbotron.html
的完整版本以及所做的更改。您可以在代码下载中找到它,名为 jumbotron_updated.html
。
摘要
在这个网络开发的现代时代,设计师们经常使用框架来帮助快速搭建网站。Bootstrap 通常被认为是当今使用最广泛的框架之一。
我们通过检查像 Bootstrap 这样的框架的关键缺陷开始了这一章,即表示 CSS 必须直接包含在 HTML 中。
我们更详细地审视了在行内使用 Bootstrap 的 CSS 样式的问题,并讨论了如何使用一种方法来规避这些问题。然后我们继续应用同样的技术来简化我们的 HTML,这样我们仍然可以使用 Bootstrap 的样式框架,同时去除对其的任何依赖,这可能会影响我们未来开发网站的方式。
在下一章中,我们将转变方向,探讨一个我们可以真正利用 Less 的强大功能的话题,即处理网站或在线应用程序中的颜色。
第十二章:使用 Less 进行颜色处理
想象一下这样的场景——你是一名设计师,正在为一家百货公司制作最新的促销广告。你花了几个小时创作你的杰作,提交给上级审批…结果发现销售总监讨厌你选择的颜色。他认为这不起作用(“对比度不够…”),所以又回到了画板。只有你知道他非常挑剔他的颜色选择,你知道这并不总是有效…
听起来熟悉吗?如果我们能选择我们的主色调,并且让代码(是的,代码)自动为你选择一个颜色,这个颜色不仅技术上可行,而且符合你选择的主色调,会怎么样呢?听起来不可能吗?在 Less 中就不是这样——欢迎来到颜色处理的领域!在本章中,我们将涵盖以下主题:
-
在 Less 中引入颜色管理
-
颜色空间和格式
-
颜色函数
-
生成调色板
-
混合模式示例以及与 Photoshop 的对比
-
使用 W3C 和 WCAG 标准进行颜色管理
感到好奇了吗?让我们开始吧…
在 Less 中引入颜色管理
打印机配置文件…色度计…sRGB…嗯?你可能是一名开发者,心想,“我对颜色管理一无所知;这一切究竟是什么意思?”
好吧,让我们先从背景说起:想象一下,你在一艘船上拍了一张红旗的照片(是的,我知道,请继续听我讲),在屏幕上看起来是橙色调,但打印出来却变成了紫色。现在,我敢打赌你真的很困惑……让我来解释一下。
这一切都是关于颜色管理的。简单来说,它是确保你的打印机、相机和电脑都能准确显示相同颜色的艺术。这听起来非常合理,对吧?毕竟,所有设备都应该显示相同的颜色,无论是什么设备…
错了。颜色管理的关键是每个设备都以不同的方式重现颜色。从某种意义上说,它们都在说不同的语言,并且没有我们自己的眼睛那么复杂;这就是我们需要色度计来平衡一切的地方…!
现在明白了吗?然而,Less 与这个有什么联系呢?嗯,Less 中正是同样的原理——我们需要确保颜色得到正确的平衡;把蓝色和紫色放在一起是不好的,因为它们太相似了。幸运的是,Less 有一系列功能可以帮助我们做到这一点。我们可以选择一个主色调,比如紫色,然后使用darken()
或lighten()
等函数来选择与主色调相配的颜色。然后 Less 会将这个函数编译成有效的 CSS;例如,如果我们选择#6600FF
(一种紫色调),我们可以让 Less 将其亮度提高 10%以产生#801AFF
。这个值将在 Less 编译你的代码时在屏幕上显示。
我们将深入研究 Less 支持的各个函数,但让我们暂时将注意力转向一点理论,以帮助我们更好地理解颜色格式和空间的重要性。
检查颜色空间和格式
当我们想到颜色时,我们大多数人可能会想到红色、绿色或蓝色,但我们是否曾想过颜色空间?如果答案是“没有”,那么再想想;你刚刚提到了我们可以使用的几种颜色空间之一。
颜色空间是唯一指定颜色的方法。最著名的是红色、绿色和蓝色(RGB)。然而,还有其他可供选择,例如色调、饱和度和亮度(HSL),它的近亲包括支持 alpha(HSLa)或HSV(色调、饱和度和值)。Less 对它们的支持较少;我们很快会详细探讨这些,但首先,让我们看看如何使用基本的数学运算符来创建新的颜色。
使用算术运算符
你有多少次花几个小时为客户调整调色板,结果却发现他们想改变全部?简单地改变一种颜色是不可能的,你需要改变它们全部…
我们可以使用 Less 来帮助我们。它包含了一系列我们可以用来自动化颜色创建和操作的函数。我们可以从颜色中选择红色、蓝色或绿色的色调,或者使用 HSL 从颜色中获取色调、亮度和饱和度级别。然而,我们还可以做一些你可能不会看到,但完全有道理的事情:使用简单的数学运算符,如+
或–
来创建我们的颜色。
尝试这个简单的实验。如果你已经安装了 Crunch!,那么在其中的一个新文件中添加以下内容,并保存:
@basecolor: #333;
.container {
color: @basecolor *2;
background-color: @basecolor - #111;
}
编译后,我们得到两种颜色,它们都来自一种基本颜色:
.container { color: #666666; background-color: #222222; }
这行编译后的代码给我们……一种非常深的灰色,以及……另一种深灰色。并不是我心中所想的颜色,但嘿,它很好地展示了原理;我们可以很容易地从一种单一的基本颜色中创建多种颜色。关键是要确保我们得到正确的数字平衡,即在基本颜色与我们使用运算符计算的颜色之间。让我们看看我们是否可以改进这一点,并开始探索创建更多吸引人的颜色的函数世界。
使用颜色函数
Less 中可用的函数可以用来提供一些有趣的颜色。花时间熟悉可用的选项是值得的,尤其是因为使用不同的方法可以产生相同的颜色!
函数可以分为四组——它们涵盖了颜色定义、通道、操作和混合。让我们依次查看每一组函数,从定义颜色格式开始。
定义颜色格式
在我们能够改变颜色之前,我们自然需要定义它们。我们可以简单地提供一个 HEX 代码,但这并不总是足够的;Less 允许我们做更多。Less 提供了一些方法,使用不同的格式来获取颜色,这些是你最可能最常使用的三种:
函数 | 从 | 示例值 |
---|---|---|
rgb |
十进制红色、绿色和蓝色(RGB)值 | rgb(90, 129, 32) |
hsl |
色调、饱和度和亮度(HSL)值 | hsl(90, 100%, 50%) |
hsv |
色调、饱和度和值(HSV)值 | hsv(90, 100%, 50%) |
小贴士
更多信息,请参阅附录中的完整函数列表,Less 中的颜色函数。我创建了一个 CodePen 来展示这些效果。这是在codepen.io/alibby251/pen/horqx
可用的。
这些方法意味着我们并不局限于始终只使用 HEX 代码——毕竟,你能说出#8a5c16
是深橙色吗?我怀疑不能!定义颜色的更好方法是使用RGB
(或者如果我们想定义透明度,则使用RGBA
);然后我们可以提取单个基本颜色,如我们下一个演示所示。
从 HEX 到 RGBA 转换颜色
这是一个非常简单的练习,我们将取一个颜色,提取其组成的基本颜色,并在屏幕上显示它们。然后我们可以使用这些颜色来产生新的颜色。我们将从设置我们演示的标记开始:
-
首先下载这本书附带代码的副本。从中,提取
hextorgb.html
的副本并将其保存到我们的项目文件夹中。这将成为我们演示的基础。 -
我们现在需要添加我们的样式,所以在一个新文件中添加以下内容,从定义我们页面的基本样式开始:
body { margin-left: 10px; padding: 0; } h3 { margin-top: 10px; margin-bottom: -5px; font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif; width: 100px; position: absolute; float: left; }
-
接下来是 Less 样式。我们首先需要从基本颜色中提取红色、蓝色和绿色样式:
@r: red(#8a5c16); @g: green(#8a5c16); @b: blue(#8a5c16);
-
一旦我们有了基本颜色,我们将它们设置为 mixin,这将定义我们框的背景颜色:
.original() { background-color: rgba(@r,@g,@b, 1); } .red() { background-color: rgba(@r,0,0, 1); } .green() { background-color: rgba(0,@g,0, 1); } .blue() { background-color: rgba(0,0,@b, 1); }
小贴士
如果你需要支持 IE8,那么
RGBA()
将不起作用。相反,使用类似以下的内容:background:rgb(R,G,B); filter:alpha(opacity=XX);
在这里,
R
、G
和B
分别对应红色、绿色和蓝色值;XX
是表示所需透明度级别的数字。 -
框单独显示不会非常美观,所以让我们添加一些字体样式:
.font-style() { font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif; width: 160px; font-size: 12px; text-align: center; padding: 15px; font-size: 14px; line-height: 1.42857; margin-top: 5px; color: #ffffff; }
-
最后但同样重要的是,我们需要调整每个框的位置,并设置背景颜色:
.box { margin-left: 120px; .font-style; } .original-box { .original; } .red-box { .red; } .green-box { .green; } .blue-box { .blue; }
-
将 Less 代码保存为
hextorgb.less
。如果我们预览我们的工作结果,我们应该在屏幕上看到四个显示的框;第一个是我们选择的颜色,后面跟着它的每个组成的基本颜色:
在这一点上,您可能会问这里发生了什么。这是一个好问题。尽管它看起来有很多 Less 代码,但实际上,它都归结为使用三个函数,即red()
、green()
和blue()
。我们首先提取主颜色,然后使用各种混入中的rgba()
函数来创建background-colors
并将它们分配给屏幕上显示的三个框。
现在让我们继续前进,将重点转向查看 Less 中的另一个颜色函数组,即处理颜色通道。
使用 Less 通道化颜色
现在我们已经建立了一个适合工作的颜色空间,我们可能会遇到需要提取和可能修改现有颜色的一部分的需求。幸运的是,Less 包含一系列可以帮助这方面的函数;让我们看看您最可能使用的三个函数;完整的列表可以在书的附录附录“Less 中的颜色函数”中找到:
函数 | 提取 | 示例值 |
---|---|---|
hue |
HSL 颜色空间中颜色对象的色调通道。返回介于 0 到 360 之间的整数值。 | hue(hsl(90, 100%, 50%)) |
saturation |
HSL 颜色空间中颜色对象的饱和度通道。返回介于 0 到 100%之间的百分比值。 | saturation(hsl(90, 100%, 50%)) |
lightness |
HSL 颜色空间中颜色对象的亮度通道。返回介于 0 到 100%之间的百分比值。 | lightness(hsl(90, 100%, 50%)) |
小贴士
更多信息,值得阅读 Less 官方网站上的文档lesscss.org/functions/#color-channel
。
虽然理解这些函数的工作原理是关键,但我们只有在使用它们时才能真正感受到它们的强大。让我们通过构建一个至少使用这些函数之一来工作的演示来纠正这一点,形式是一些简单的警告框。
创建警告框
Sebastian Ekström,一位瑞典开发者,提供了一个如何使用 Less 中的亮度和暗度函数的完美示例。我在这里对其进行了一些小的修改,以使用 HSL 颜色代替标准的十六进制代码。您可以在codepen.io/sebastianekstrom/pen/uHAtL
查看这个示例的原始版本。
让我们开始吧。我们首先需要下载一些图标;为了这个演示的目的,我将假设您已经使用了以下这些:
-
确认对话框(
www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org/Status-dialog-information-icon.html
) -
错误对话框(
www.iconarchive.com/show/nuoveXT-2-icons-by-saki/Status-dialog-error-icon.html
) -
警告对话框(
www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org/Status-dialog-warning-icon.html
)
如果你想要使用替代图标,那么相应地调整代码。
-
从代码下载的副本中,提取
alerts.html
的副本。这将成为我们演示的基础。 -
接下来,让我们创建我们的 Less 样式。在一个新文件中,添加以下颜色样式,从主要文本颜色开始:
@text-color: hsl(0,0%,53.3%); @button_confirm: #008000; @button_warning: #ffc53a; @button_error: #ff0000; body { background: hsl(0,0%,13.3%); }
-
接下来,添加以下两个混合函数;这些确定要使用的背景颜色:
.text-color(@text-color) when (lightness(@text-color) > 40%) { color: #000000; } .text-color(@text-color) when (lightness(@text-color) < 40%) { color: #ffffff; }
小贴士
注意到
when
语句的使用吗?将只使用一个文本颜色;这将由@text-color
的亮度值是否高于或低于40%
来决定。如果是高于,则使用纯黑色;如果是低于,则使用白色代替。 -
我们接下来的两个混合函数控制字体格式化和基本按钮设计:
.h3-text() { background-repeat: no-repeat; font-size: 1.5rem; padding-left: 40px; } .button(@button_type) { text-decoration: none; padding: 1em 3em; width: 20%; margin: 1% auto; display: block; text-align: center; font-family: sans-serif; border-radius: 5px; line-height: 40px; border: 1px solid #000000; background: @button_type; }
-
我们现在可以将我们的样式结合起来。我们首先调用创建确认对话框的混合函数,然后依次调用警告和错误对话框的混合函数:
#confirm { .button(@button_confirm); .text-color(@button_confirm); h3 { background-image: url(confirmation.png); .h3-text; } } #warning { .button(@button_warning); .text-color(@button_warning); h3 { background-image: url(warning.png); .h3-text; } } #error { .button(@button_error); .text-color(@button_error); h3 { background-image: url(error.png); .h3-text; } }
将文件保存为css
子文件夹中的alerts.less
。如果一切顺利,我们将看到三个对话框,背景为全黑的背景:
好的,所以我们现在可以设置我们的颜色空间并提取我们选择的基色。然而,我们将如何使用这些颜色?仅仅提取颜色可能不足以满足需求;我们很可能需要做更多的事情。Less 没有问题。我们可以对我们的选择颜色进行操作,以产生我们想要的任何颜色!
颜色运算
到目前为止,你可能正在问自己,“为什么我们需要在颜色上使用运算符?”当然,那是你用数字做的事情,对吧…?
并非必然。使用简单的算术运算符,正如我们在使用算术运算符部分之前所看到的,将完美地工作,但如果我们需要更改颜色,并最终选择使用我们提供的固定计算看起来很糟糕的颜色呢?显然,我们需要一个更好的方法…!
幸运的是,Less 中存在许多我们可以使用的函数,并且假设我们有合适的颜色作为起点,我们可以使用这些函数中的任何一个来产生不同的色调,或者改变色调、饱和度或亮度级别等。让我们花点时间考虑你可能会最常使用的三个:
函数 | 函数用途 | 示例值 |
---|---|---|
lighten |
通过绝对量增加 HSL 颜色空间中颜色的亮度。 | lighten(#a52a2a, 20%); |
darken |
通过绝对量减少 HSL 颜色空间中颜色的亮度。 | darken(#a52a2a, 20%); |
fade |
设置颜色的绝对透明度。这可以应用于无论颜色是否已经有不透明度值的所有颜色。 | fade(#a52a2a, 20%); |
小贴士
更多信息,请参阅本书末尾的完整函数列表,附录,Less 中的颜色函数。我还创建了一个 CodePen,展示了这些效果,可在codepen.io/alibby251/pen/KGltj
找到。
这在任何网站上都很合理,但在使用颜色并更新它们会是一场噩梦的大型网站上更是如此。相反,我们可以选择我们的主颜色,将其分配给一个变量,并使用函数生成剩余的颜色。让我们看看这如何在实践中快速简单地工作,通过一个基于我们使用的H
属性的文本颜色变化的快速示例。
使文本颜色变深或变浅
我们的两个真实世界演示中的第一个非常简单。假设我们在网站上有很多文本样式,它们使用相同颜色的不同色调。
我们可以轻松地在 CSS 中设置颜色,但这会错过 Less 的一个主要关键部分;为什么我们要明确设置它们,当我们可以让 Less 为我们做这件事时?为了了解这意味着什么,让我们快速搭建一个演示,创建一些不同的样式,用于标准的H1
到H6
标记,如下所示:
让我们开始:
-
对于这个演示,我们需要下载这本书附带代码的副本。从中,提取
altercolor.html
的副本并将其保存到我们的项目文件夹中。这将成为我们演示的基础。 -
在一个单独的文件中,继续添加以下样式,从我们的基本字体 mixin 开始,以样式化文本:
.font-family() { font-family: Helvetica, arial, times new roman; font-weight: bold; }
-
接下来是设置我们的基本颜色的变量:
@base_color: #893939;
-
我们都需要添加创建字体样式的至关重要的 mixin 调用:
h1 { color: @base_color; .font-family; } h2 { color: saturate(@base_color, 30%); .font-family; } h3 { color: fadeout(red, 70%); .font-family; } h4 { color: mix(blue, @base_color, 50%); .font-family; } h5 { color: lighten(@base_color, 20%); .font-family; } h6 { color: darken(@base_color, 20%); .font-family; }
将文件保存为css
子文件夹中的altercolor.less
。如果我们预览我们的工作,我们应该期望看到六个语句,样式如本练习开始所示。
简单而优雅,不是吗?通过一点工作和一种颜色,我们使用 Less 自动设置了所有样式。我们的演示正在动态创建样式,但我们可以轻松地将 Less 语句预编译成有效的 CSS 代码,并使用它。我们只需要在设计页面时使用正确的H
属性即可!
让我们继续前进,看看 Less 的一些更多功能,我们可以使用——混合组。这些函数的工作方式与图形软件包(如 Photoshop 或 GIMP)中可用的选项类似。让我们更详细地探索这些。
颜色混合
到目前为止,我们已经看到我们可以定义一个颜色空间,从中提取其组成元素(如色调或绿色的级别)并可以通过淡入或旋转原始颜色来转换颜色。还有另一种使用 Less 改变颜色的方法——混合。
原则上与之前相同,我们需要两种颜色,但效果却大不相同。让我们快速看一下你可能会最常使用的三个功能:
功能 | 功能用途 | 示例值 |
---|---|---|
multiply |
此功能将两种颜色相乘。 | multiply(#9ec1ef, #091d37); |
screen |
这与multiply 相反。结果是颜色更亮。 |
screen (#9ec1ef, #091d37); |
overlay |
条件性地使亮通道更亮,暗通道更暗。 | overlay (#9ec1ef, #091d37); |
提示
对于更多信息,请参阅书末附录中给出的完整函数列表附录,“Less 中的颜色函数”。我还创建了一个 CodePen,展示了这些效果的实际应用,可在codepen.io/alibby251/pen/IKqEk
查看。
现在我们已经看到了 Less 中可用的各种颜色混合模式,让我们继续看看这些模式与在 Photoshop 中执行类似操作相比如何。
与 Photoshop 比较 Less
在 CSS 中使用混合模式可能会提出一个非常重要的问题——Less 与 Photoshop 等应用程序相比如何?
好消息是,对于那些已经熟悉 Photoshop 中混合模式的人来说,Less 中存在相同的值,尽管范围不如 Photoshop 广泛。我们可以使用诸如 lighten、darken、hardlight 等值来产生与在 Photoshop 中创建图像相似的效果。
提示
两个如何使用混合模式的良好例子可以在css-tricks.com/basics-css-blend-modes/
找到;也可以看看www.dummies.com/how-to/content/photoshop-ccs-blending-modes.html
,以了解这些模式如何在最新版本的 Photoshop(撰写本文时为 CC 版)中与其他混合模式相匹配。
缺点是混合模式的支持仍然非常新;例如,background-blend-mode
(撰写本文时)的支持仅限于现代浏览器的最新版本,IE 除外。
除了这个限制之外,花时间熟悉如何在 Less/CSS 中复制 Photoshop 中的相同效果绝对是值得的。正如我们已经看到的,我们可以使用一系列混合值。作为一个 CSS 可能性的测试者,你可以看看 Bennett Feely 使用background-blend-mode
产生的出色渐变,你可以在bennettfeely.com/gradients/
看到这些渐变。
要真正了解如何在 Less 中使用混合模式,强烈建议你至少了解以下这三个:screen
、multiply
和overlay
。其他的功能将陆续介绍。让我们花点时间更详细地介绍这三个模式:
-
屏幕
:它忽略了黑色,使图像看起来更亮,浅色调看起来被冲淡。 -
乘法
:这是直接相反的,深色调得到加强,而浅色会透过任何清晰或明亮的东西。 -
叠加
:这是屏幕和乘法的平衡;它忽略了中间调,使混合结果同时变亮和变暗,以增加对比度。
在这一点上,让我们改变方向,继续前进。我们可以轻松地使用混合模式来帮助产生新的颜色,或者有趣的效果(尤其是与图像一起!);除非我们已经想清楚我们的网站调色板将是什么样子,否则这不会真正有效。
在这一点上,我们可以真正充分利用 Less,来计算适合我们调色的板的价值。在我们这样做之前,让我们从创建成功调色的板的基础知识开始,以帮助设定场景。
介绍调色板
我们在设计网站时都会使用颜色。颜色对于我们的设计至关重要,是成败的关键。创建一个统一且有趣的网站依赖于正确选择构成我们调色的板上的颜色。从历史上看,我们经常使用白色或彩色背景;随着我们品味的演变,选择构成我们调色的板上的正确颜色也变得同样重要。
任何成功调色板的关键,甚至在深入到制作它之前,是真正理解颜色是如何工作的。色彩理论是一个复杂的主题,我们可以通过理解不同色调和色相如何相互作用以及这种相互作用对网站访问者的影响来掌握它。
为了帮助我们通过选择正确颜色来创建调色的板的雷区,我们可以使用一些技巧:
-
尝试根据你选择的颜色选择合适的调色板类型。有几种调色板类型可供选择,但特别值得注意的是类似色、互补色和三色。
-
相反,基于当前趋势选择颜色。例如,这可能是一些柔和的粉彩色,它们在制作舒缓的平面设计中变得流行。
-
另一个选择是使用鲜艳的颜色,这些颜色通常饱和度很高,可以使元素真正突出。颜色范围通常有限,有很多白色或灰色空间,以帮助平衡在这个调色板中使用的鲜明颜色。
-
我们甚至可以尝试单色设计,这通常基于黑色或灰色的色调,具体元素用红色或蓝色突出显示。单色调色板有助于传达情感或心理信息,而我们可以使用强调色来突出设计中的重要元素。
注意
选择颜色时,一个很好的工具是 Adobe 的 Kuler,可在
kuler.adobe.com/create/color-wheel/
找到。它显示了一些你可以使用的其他调色板,例如三色或复合;一旦你熟悉了创建调色板,尝试这些是有价值的。
现在让我们花点时间更详细地看看这些调色板类型。
分析调色板示例
消费者如何经常被网站上的颜色所引导,这一点令人惊讶;例如,一项研究发现,60-80%的顾客购买决策仅受颜色的影响!让我们花点时间考虑几个例子,以展示选择正确颜色的重要性。
Trüf,一家位于洛杉矶的网页设计公司,使用单色设计,用红色突出其网站的关键元素——你可以看到他们的设计在www.trufcreative.com
。
类似的使用颜色,但针对不同的网站,Etch 在其大胆的背景中使用了各种色调,用粉色元素使设计真正脱颖而出。他们的网站是www.etchapps.com
。
为了感受选择颜色的重要性,请查看 Column Five Media 网站上的信息图表,网址为www.columnfivemedia.com/work-items/infographic-true-colors-what-your-brand-colors-say-about-your-business
;那里有一些非常揭示的事实!
值得注意的是,在实际情况下必须考虑可访问性;这通常由提供给视觉障碍访客的产品或服务的吸引力所决定;Geri Coady 已经制作了一份有用的指南形式的电子书,可在www.fivesimplesteps.com/products/colour-accessibility
上购买。
让我们继续前进,把注意力转向我们一直期待的事情——选择一些颜色。
选择我们的颜色
到目前为止,我们已经了解了选择颜色的重要性以及这将对我们的网站访客产生的影响;选错颜色将会是灾难性的!相比之下,一旦我们知道我们想要使用哪些颜色,创建我们的调色板就真的很容易了。
第一阶段是选择我们的主色。Column Five Media 的信息图表建议,世界上前 100 个顶级品牌中只有 5%使用超过两种颜色;这里的关键是使用适合你项目的颜色数量。一个很好的经验法则是选择至少 2-3 种颜色来搭配,同时使用中性浅色或深色作为背景。然后我们可以使用 Less 从你的主色选择中产生所需的任何色调。
使用照片作为我们的来源
你有多经常想知道你将从哪里获得设计灵感?我敢打赌答案经常是,而且我敢打赌照片将在这个来源列表中占有一席之地!
照片是灵感的完美来源。我们可以从中选择一个主色,然后手动选择合适的颜色。但这可能会有些运气成分;并不是每个配色方案都会奏效,但使用这种方法的关键是实验,直到找到能够为你的设计提供良好和谐的色彩。
我们可以采取更实际的方法。Adobe 发布了 Kuler,一个出色的应用程序(和网站),帮助我们根据所使用的色板类型选择合适的颜色。
我们可以选择一个颜色,然后让 Kuler 为我们选择合适的颜色,或者我们可以上传我们选择的照片,并从中选择合适的颜色。在下面的屏幕截图中,我们可以看到从照片中选择颜色的结果,例如我在第一本书《jQuery Tools UI Library》中使用的那张照片,由 Packt Publishing 出版。
相比之下,如果我们从最左边的紫色(#a67097
)开始,并在 Kuler 的色彩轮上使用它,我们会得到一个完全不同的结果,使用的是类似色板:
这实际上取决于你的项目在颜色方面的需求;为了帮助这一点并了解对访客的影响,阅读 Rachel Shillcock 在 Tuts+上的一篇文章是值得的,文章地址为webdesign.tutsplus.com/articles/understanding-the-qualities-and-characteristics-of-color--webdesign-13292
。
小贴士
为了获得良好的灵感来源,可以看看 Kuler 上其他人创建的色板;它们位于kuler.adobe.com/explore/newest/
。
使用工具,如 Kuler,选择颜色可以是一次有趣的体验。它打开了一个充满可能性的世界,尽管一个人的和谐感可能与其他人不同!选择,选择……
为了帮助减少创建色板时的猜测,我们可以轻松地利用 Less 的强大功能,根据我们选择的颜色创建一个合适的色板。让我们看看这在实践中是如何工作的。
使用 Less 创建颜色色板
现在我们已经选择了我们的配色方案,我们可以开始创建我们的色板。实际上有数百种工具可供选择,但我们希望 Less 为我们做所有繁重的工作。
现在,我有一个坦白要讲:虽然我们可以让 Less 为我们做艰苦的工作,但我们仍然需要计算出生成我们颜色的公式。或者,我们不需要?
幸运的是,有一位热心的朋友,Jimmy King(Meltmedia 的开发者),已经为这个目的制作了一个非常简单但非常出色的工具。如果我们访问jimmyking.me/colors.less
,不仅可以将颜色选择器设置为我们选择的颜色,还可以预览适合不同类型色板的颜色。更重要的是,我们甚至可以得到生成颜色的 Less 代码!
让我们用一个快速演示来实施这个想法,演示使用之前练习中的#a67097
颜色创建一个基于三色的色板:
-
从本书附带的代码中下载并解压
colorpalette.html
副本;我们将以此作为我们的标记的基础。 -
在一个单独的文件中,添加以下 Less 语句,从创建定义我们颜色的变量开始:
@baseColor: rgba(166,112,151,1); @distance: 120; @triad1: @baseColor; @triad2: spin(@baseColor, (180 - (@distance * 0.5))); @triad3: spin(@baseColor, (180 + (@distance * 0.5)));
注意
我们在这个步骤中使用了 spin 函数;spin 用于在 HSV 颜色轮中旋转颜色的色调角度。你可以在
lesscss.org/functions/#color-operations-spin
了解更多关于这个操作的信息。 -
接下来,添加以下混入(mixins)。请注意,我们可以将这些与代码中显示的彩色样式规则结合起来;我为了清晰起见将它们分开:
.triad1() { background-color: @triad1; } .triad2() { background-color: @triad2; } .triad3() { background-color: @triad3; }
-
我们还需要一些基本的字体样式;这不是必需的,但它有助于使其看起来更好!请继续添加以下混入:
.font-style() { font-family: "Open Sans","Helvetica Neue", Helvetica, Arial, sans-serif; width: 160px; font-size: 12px; text-align: center; padding: 15px; font-size: 14px; line-height: 1.42857; margin-top: 5px; color: #ffffff; }
我们几乎完成了。接下来是最重要的混入(mixins);这些创建框并使用适当的背景颜色来样式化它们:
.box { margin-left: 250px; .font-style; } .firstcolor { .triad1; } .secondcolor { .triad2; } .thirdcolor { .triad3; }
-
我们需要让这个演示看起来更专业一些,所以请继续添加以下样式:
body { margin-left: 10px; padding: 0; } h3 { margin-top: 10px; margin-bottom: -5px; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; width: 300px; position: absolute; float: left; }
-
将文件保存为
colorpalette.less
。如果我们在一个浏览器中预览结果,我们将看到类似于以下截图的内容:
到目前为止,你可能正在想,“这里发生了什么?”好吧,如果我们回到吉米的工具,你们中那些眼尖的人应该能注意到,我使用了公式来生成一个三色色板。我们所做的一切只是将这些公式打包成一个小的演示,在这个演示中,我们根据每个公式的结果设置三个框的背景颜色。
吉米为多种不同的色板类型产生了公式,所以我们不必重新发明轮子,我们只需选择我们的主色,然后在我们决定使用哪个色板后,自动生成代码的副本!不过,关键点是,关于颜色是否有效,绝对没有讨论的余地;这些颜色是数学上选择的,以产生和谐的色板。
小贴士
在制作色板时,尽量决定并坚持一个合适的命名约定。没有固定的格式规则,但一致性和重用是当务之急!
因此,我们已经看到制作色板是多么容易,吉米的工具使获取创建每种颜色所需的所有重要计算变得轻而易举。这让我有了一个想法…如果我们放弃 Photoshop 并在浏览器中设计会怎样?
放弃旧习惯
什么??不可能吧,我听到你说!我们不可能做到这一点…
或者我们可以…?好吧,虽然听起来可能令人惊讶,但这完全可能;更重要的是,Less 可以帮助使这个过程变得无痛。让我来解释。
从历史上看,设计师和开发者一直依赖使用 Photoshop 来创建网站的草图。"这没什么问题",你可能会说。然而,这会加倍工作量;客户无法使用设计来查看其外观和功能,而且无法即时做出更改。此外,Photoshop 价格昂贵。我们只需要高端的 PC 或 Mac 才能充分利用它;对于成本敏感的小型网站开发者来说,他们真的能证明这种成本是合理的吗?
相比之下,直接在浏览器中设计使过程更加动态;我们可以快速轻松地做出更改,尤其是如果使用了 Less 的话!我们甚至可以仅通过几次点击就生成几个样式表,这些样式表可以完全改变网站的外观;在 Photoshop 中创建设计意味着为每个后续设计从头开始重新创建基本视图。尽管我们愿意这样做,但每次设计都可能会有一些细微的差异,尽管每个案例都遵循了相同的过程!
然而,我们不应该忘记,设计的真正关键不是专注于颜色,而是内容。如果我们在这方面做得正确,那么颜色就会自然而然地就位。
注意
为了帮助大家感受在浏览器中设计的心态,Creative Bloq 发布了对网页开发者 Sean Fioritto 的采访,采访内容可在www.creativebloq.com/css3/why-web-developers-should-sketch-css-not-photoshop-51411711
找到。这是一篇很有趣的阅读材料!
然而,如果我们真的负担不起停止使用 Photoshop,那么我们至少可以使我们的开发工作流程更智能。CSS Hat 开发了一个插件,可以将任何设计转换为等效的 Less 代码,并将它们导出为 Less 文件。它可在www.csshat.com
找到,并且有适用于 Windows 和 Mac 的版本,两个版本的许可证价格均为 35 美元。
注意
要看到它的实际应用,Kezz Bacey 编写了一个两部分的教程,展示了如何轻松地使用这个插件来生成更少的 Less 代码;教程的第一部分可在webdesign.tutsplus.com/tutorials/how-to-improve-your-photoshop-workflow-with-csshat-and-pnghat--cms-20786
找到,第二部分在webdesign.tutsplus.com/tutorials/how-to-code-a-photoshop-layout-with-csshat-lesshat-and-pnghat--cms-20997
。
我们几乎完成了在 Less 中使用颜色的迷你之旅。在我们完成并进入下一章查看动画之前,我们需要看看每个设计师在设计时都应该考虑的一些法律要求。当然,这是 WCAG 标准;让我们更详细地看看这些。
与 W3C 和 WCAG 标准合作
在本章中,我们一直在进行探索之旅,了解 Less 中的各种不同功能如何帮助简化创建新颜色所需的工作。在创建颜色方面,我们还有一项重要内容尚未涉及,设计师必须注意:确保符合 WCAG 可访问性指南。
克服网站访问障碍
在这个现代时代,人们希望所有网站都对每个人可访问;但事实并非总是如此。访问可能因多种原因而被阻止,在颜色的方面,它们是:
-
对于无法区分特定颜色且因此无法访问依赖于这些颜色来传达意义的信息的访客(例如,红绿色盲)
-
需要使用无法显示使用颜色的信息的设备的访客
-
对于那些难以看到前景和背景颜色非常接近的网站的访客,他们可能存在颜色缺陷
那么,我们如何解决这些问题并确保我们创建的网站是可访问的?
介绍 WCAG
WCAG 编制了一份广泛的指南列表,以帮助设计师确保合规性,这些指南可以在www.w3.org/TR/WCAG/
查看。虽然设计师可以选择在 A、双 A 或三 A 级别中选择合规性,但这些指南需要遵循。
WCAG 建议可能难以阅读,但仍然有两个关键因素需要考虑,总结如下:
-
不应仅使用颜色来传达任何信息;一个标有OK的绿色按钮比一个简单的绿色圆圈更可取
-
文字(以及文字的图像)应至少具有 4.5:1 的对比度比率,除非使用大号文字,或者文字是装饰性图像或品牌标志的一部分
为了确保信息不太可能违反 WCAG 合规性,我们可以使用以下几条指南:
-
避免使用彩色文字或强烈的背景颜色
-
建议使用黑色文字在白色背景上(避免使用下划线文字,因为您的客户可能会认为文字是超链接,而实际上并不是)
-
使用标准字体(例如,Arial,Times New Roman)
-
不应使用大写字母作为整个页面标题或文本块的字体
此外,我们可以使用一些工具来帮助我们决定是否达到了正确的对比度水平。两个这样的例子可以在www.dasplankton.de/ContrastA/
和webaim.org/resources/contrastchecker/
找到。
注意
在线有大量资源可供进一步阅读,包括针对特定公司或政府机构的案例研究和指南。以下是一些例子:
值得注意的是,Less 库已被修改以帮助合规。尽管它还没有完全合规,但一个有助于合规的更改示例是github.com/less/less.js/pull/1704
上发出的拉取请求;这涉及到对 Less 中颜色函数(如乘法或叠加)所做的更改。
使网站可用
好吧,鉴于我们刚刚讨论了如何使网站合规,这个问题可能看起来有些奇怪,对吧?
嗯,是的,也不是。在为这本书进行研究时,我遇到了一个关于确保遵守 WCAG 指南以及为什么遵守它们实际上可能对您的网站有害的精彩讨论。
简而言之,原始问题的回答者讨论了尽管它们并不完美,但背后团队所做的好工作。他谈论了需要谨慎应用指南,并且只有最适合网站的那些指南应该被使用。他提到,许多残疾人通常会找到绕过那些本应隐藏在视线之外的信息的方法,从某些方面来说,他们是帮助测试网站可用性的完美人选!
注意
你可以在stackoverflow.com/questions/21415785/wcag-vs-real-users-opinions
上阅读完整的讨论。
摘要
在 Less 中的色彩管理可以看作是一种矛盾;虽然工具相对简单易用,但它们可以用来制作复杂的设计,这些设计的复杂程度仅限于你的想象力。在本章中,我们介绍了一些你可以用来提取、混合和混合颜色的工具。让我们花点时间回顾一下本章所学的内容。
我们首先用一点理论来设定场景并介绍色彩管理;我们还了解了一些关于色彩空间和格式的知识。我们使用 Less 的探索之旅从查看使用简单的算术运算符,如乘法或除法开始;紧接着是介绍 Less 中可用的各种颜色函数以及这些函数与使用 Photoshop 相比如何。
接下来是关于调色板的介绍和一些示例分析,以说明仔细选择颜色的重要性。这包括使用照片作为潜在的颜色来源,然后我们使用 Less 创建了一个颜色调色板。
接下来,我们讨论了一些可能被视为有争议的话题,那就是放弃旧习惯,转而使用类似 Less 的工具直接在浏览器中开发。虽然有些人可能会认为这并不合理,但我们讨论了为什么这种做法可能会带来好处的一些原因;对于那些无法面对这种转变的人来说,我们介绍了一种简单的方法,可以从 Photoshop 自动创建 Less 样式。为了结束本章,我们探讨了开发者必须遵守关于颜色使用的 WCAG 指南,为什么这些指南被制定,以及我们在应用它们到我们的网站上需要小心谨慎的原因。
哇!我们确实覆盖了很多内容!接下来,让我们进入下一章,本章将探讨我们如何使用 Less 来简化项目中的动画开发。
第十三章。使用 Less 进行动画
你见过多少使用 Flash 的动画网站?好吧,相当多。我敢打赌,你一有机会就想跳过动画,对吧?
是的,我想是这样的;现在没有多少人举手了…
我们不能忘记那些使用 Flash 的网站的老日子,我们经常想跳过那些设计糟糕的动画,这些动画往往不提供任何有用的内容,反而使网站变慢。听起来熟悉吗?
幸运的是,情况已经有所改变;在接下来的几页中,我们将看到如何使用 CSS3 动画来达到原本需要 Flash 才能实现的效果。CSS3 动画的使用消除了对重型 Flash 插件的需求(对于现代浏览器而言),并且如果做得恰当,可以使网站运行更快,浏览体验更愉快,对最终用户更具吸引力。我们将深入研究使用 Less 来简化编码一些真实世界示例的过程,以便使我们的开发工作流程变得更加容易。
在本章中,我们将涵盖以下主题:
-
CSS 动画的工作原理
-
过渡和变换
-
动画菜单
-
使用 Less 简化动画标记
感兴趣吗?让我们开始吧…
介绍动画
在互联网的早期,经常可以看到动画 GIF,它们经常被随意地贴在网站上——通常的借口是它们“看起来很酷”,即使它们实际上并没有真正起到任何作用!
现在,动画越来越多地被用于互联网上——这通常以 SVG 图像、背景视频、声音等形式出现。这种越来越被使用的技术如 Flash,但随着 HTML5 的出现,设计师们找到了在浏览器中不使用 Flash 就能原生地重现许多效果的方法。
现在,浏览器厂商正在为他们的每个产品版本添加越来越多的功能;这意味着 CSS3 动画正在逐渐取代 Flash,以至于 Adobe 已经停止为移动平台开发 Flash,转而专注于 HTML5。
在接下来的几页中,我们将游览 CSS3 动画,查看各种元素,如过渡和变换,以及我们如何使用 Less 来帮助简化动画开发的过程。你可能会惊讶地发现,当使用 Less 制作动画时,并没有很多新技术需要掌握——实际上,我们迄今为止所涵盖的所有技术都可以用来帮助使开发过程变得更简单。
让我们先快速看一下什么是一个好的动画——毕竟,如果它们不成功,就没有创建它们的必要了!
创建一个好的动画
你有多经常查看一个网站,却发现它看起来就像有人在偏头痛中大脑的内部?太多的网站屈服于将一切动画化的诱惑——动画是一个秘密成分,当使用得当时会产生最大的影响。
那么,什么因素使动画变得出色?这取决于网站的环境,但有一些好的建议,每个设计师都应该遵循:
-
不要过度使用吸引注意力的元素——访客希望感觉他们可以控制他们的浏览体验,所以当他们到达所需信息时立即弹出订阅对话框是非常不恰当的!用它来突出他们可能错过的内容,而不是分散他们的注意力。
-
当动画用于突出上下文和导航功能时,动画效果很好;一个很好的例子是提供有用本地信息的动画侧边栏。侧边栏的内容会频繁更改,因此使用动画可以帮助指出新信息给用户。
-
在一些网站上,讲述故事是使用动画的一种方式。虽然这可能对某些网站来说有些过度,但流行的全页滚动效果效果很好,因为它暗示还有更多内容可以阅读,这有助于保持用户的兴趣。
-
如果使用了动画,那么让它看起来真实可信。你可以在元素上使用任何效果,例如弹跳或震动,但如果它们不可信,那么用户会发现它们是干扰,并且会感到非常不快!
现在让我们继续前进,将我们的注意力转向更深入的话题:动画是如何工作的?这是创建成功动画的关键。正如我们即将看到的,不同类型的动画看起来很相似,但它们有一些关键的区别;这可能会影响我们如何使用它们来在我们的网站上开发效果。
CSS 动画的工作原理
我们已经讨论了动画的一般概念,但这个术语涵盖了至少四种我们可以在 Less 中使用的不同类型。它们是动画、过渡、2D 变换和 3D 变换。
在这四个属性中,有两个需要特别注意它们的工作方式:动画和过渡。这并不意味着变换不那么重要——情况并非如此。它们只是以与过渡不同的方式工作,更容易理解和使用。
动画和过渡看起来可以提供相同的结果,但它们的工作方式不同。两个关键的区别是:
-
过渡基于两种状态——如果我们切换 CSS 状态或触发了一个伪类,例如
:hover
或:focus
,它将改变元素从起始位置到结束位置。 -
动画可以使用多个
@keyframes
或在起始状态和结束状态之间设置的位置。
剩下的两个动画属性,2D 和 3D 变换,它们的工作方式并不相同——它们可以操纵元素的大小和外观,但通常是在原地(尽管它们可以在元素移动时使用)。
既然我们已经了解了动画的工作原理,现在是深入了解每种动画属性的好时机。
介绍动画类型
当我们谈论创建动画时,这可以理解为我们在移动内容;虽然这是完全正确的,但我们不仅限于简单地移动元素。我们同样可以将元素从一个状态过渡到另一个状态,或者弯曲并操纵它们在屏幕上的外观。让我们更详细地查看每种动画类型,从动画开始。
动画内容
使用动画内容来移动对象,可以用作 Flash 的替代品。它们定义了一组元素属性的变化——我们可以在定义动画时控制这些属性的行为,包括它们的频率。
动画和过渡之间的关键区别在于,动画可以在没有任何用户交互的情况下触发,一旦页面加载即可。过渡只能在元素变得活跃时触发,例如button
元素或div
元素。
简单动画将遵循以下格式:
animation: <name of animation> <duration of the animation>
让我们通过创建一个简单的动画来改变框的颜色来测试这个。为此,我们需要这本书附带的代码下载副本;从这些代码中提取animatebox.html
和animatebox.css
的副本。
如果我们运行演示,我们可以期待看到框经过几种紫色调,然后恢复到原始颜色,如下面的截图所示:
这里的关键是我们的 CSS 中的@keyframes animbox
;这包含了动画中每个关键帧应进行的更改。我们不得不包含它两次以支持 Chrome、Safari 和 Opera:
/* Chrome, Safari, Opera */
@-webkit-keyframes animbox {
0% { background: #85486d; }
25% { background: #9F6287; }
50% { background: #B87BA0; }
100% { background: #D295BA; }
}
/* Standard syntax */
@keyframes animbox {
0% { background: #85486d; }
25% { background: #9F6287; }
50% { background: #B87BA0; }
100% { background: #D295BA; }
}
动画有点抖动——这将是由于每个关键帧之间的大间隔;我们可以使用更小的间隔来获得更平滑的体验。
注意
你可以在www.w3schools.com/css/css3_animations.asp
了解更多关于 CSS3 动画的不同属性。
让我们继续并看看过渡是如何工作的。
过渡元素
过渡实际上是将元素从其原始状态转换为新状态的动画;动画与过渡的关键区别在于,过渡只能在它们被明确触发时发生——例如,当鼠标悬停在 DIV 或按钮上时。
简单过渡将遵循以下格式:
transition: <the css property you want to add the effect to> <the effect duration>
让我们通过创建一个简单的过渡来增加一个框的大小来测试这个。为此,我们需要这本书附带的代码下载副本;从这些代码中提取transitionbox.html
和transitionbox.css
的副本。如果我们运行这个演示,我们可以期待看到框的大小增加,然后恢复到原始大小:
这里的关键是我们的 CSS 中#transitionbox
DIV 的过渡代码——这包含了动画中每个关键帧应进行的更改。我们不得不包含它两次以支持 WebKit 浏览器:
-webkit-transition: width 2s; transition: width 2s;
如果两秒钟不够,我们总是可以调整动画执行所需的时间。
注意
你可以在 www.w3schools.com/css/css3_transitions.asp
了解更多关于 CSS3 动画的不同属性。
现在我们继续前进,看看剩下的两个选项,即 2D 和 3D 变换。
变换元素
初看之下,你可能会误以为变换和过渡是相同的;毕竟,你可以轻松地使用 translate()
来移动一个对象,而动画则可以用来实现其他效果。
然而,有两个关键的区别:过渡可以作为动画元素的一部分应用,而变换则是完全独立的。过渡允许你将更改应用于几乎任何 CSS 属性,而变换则用于移动、缩放、旋转、旋转或拉伸页面上的任何元素:
一个简单的变换将遵循以下格式:
transform: <the transform action you want to use>(<the value to apply to the transform>)
让我们通过创建两个简单的变换来测试这一点:第一个变换对一个盒子执行 2D 旋转,第二个变换则沿着第二个盒子的 x 轴执行 3D 旋转。
为了做到这一点,我们需要这本书附带的代码下载的副本;从中提取 transformbox.html
和 transformbox.css
的副本。如果我们运行这个演示,我们预计在悬停在任何一个上面时,两个盒子都会旋转;左侧的盒子旋转了 30 度,右侧的盒子在其 x 轴上旋转了 130 度,如本节开头所示截图所示。
关键在于我们 CSS 中的变换代码——对于第一个盒子,我们将其旋转 30 度;第二个盒子在其 x 轴上旋转 130 度。注意 2D 变换的支持比 3D 变换要好得多;我们仍然需要为大多数桌面浏览器使用 webkit
前缀:
#transform2dbox:hover {
transform: rotate(30deg);
}
#transform3dbox:hover {
-webkit-transform: rotateX(130deg); /* Chrome, Safari, Opera */
transform: rotateX(130deg);
}
一旦浏览器对 3D 变换的支持得到改善,我们就可以从第二个演示的第二行中删除第一行。
注意
你可以在 www.w3schools.com/css/css3_2dtransforms.asp
和 www.w3schools.com/css/css3_3dtransforms.asp
了解更多关于 CSS3 变换的不同属性。
我们在探索这些迷你演示的过程中稍微提到了对 CSS3 动画的支持;现在是详细探讨支持的合适时机。
支持浏览器中的动画
在继续之前,我们需要讨论一个小问题,那就是浏览器的支持。在这里,你应该在使用动画时不会有任何麻烦;CSS3 动画的所有关键元素已经由主要浏览器支持了一段时间:
IE | Firefox | Chrome | Safari | Opera |
---|---|---|---|---|
10+ | 5+ | 5+ | 4+ | 12+ |
请务必查看网站 Can I Use (www.caniuse.com
),因为一些动画的新元素在撰写时可能仍然需要供应商前缀。
移动设备支持同样良好;唯一的例外是 Opera Mini,它不支持动画。Android 的 Chrome 在开始时有点问题,但这个问题已经解决,所以支持不会成为问题。然而,重要的是要记住,移动设备没有快速的处理器,所以复杂的动画将运行缓慢,并且在这个平台上应该尽量减少。
好的,理论就到这里!让我们继续到你们一直等待的部分:编写一些代码。
使用 Less 简化动画标记
好的,我们终于到了你一定迫不及待想要到达的点:编写一些代码!别担心,我们很快就会到达那里。我只是想涵盖一个小但关键的观点,关于我们如何使用 Less 使编码动画更简单。为了说明这一点,我们将重新工作本章中我们之前创建的动画演示的关键部分。
如果我们回顾动画演示的关键部分,我们有以下内容:
/* Chrome, Safari, Opera */
@-webkit-keyframes animbox {
0% { background: #85486d; }
25% { background: #9F6287; }
50% { background: #B87BA0; }
100% { background: #D295BA; }
}
/* Standard syntax */
@keyframes animbox {
0% { background: #85486d; }
25% { background: #9F6287; }
50% { background: #B87BA0; }
100% { background: #D295BA; }
}
看起来相当合理,对吧?嗯,就像往常一样,我们可以做得更好!让我们看看我们如何做到:
-
我们可以做的第一个改变是将
animatebox.css
保存为animatebox.less
——我们将引入一些混合器,因此将其保存为 Less 文件将允许我们在本练习的后续部分将其编译成有效的 CSS。 -
我们需要修改 HTML 标记以包含对新 Less 文件和 Less 库的引用;因此,请在
<head>
标记之间添加以下内容:<link rel="stylesheet/less" href="css/animatebox-updated.less"> <script src="img/less.min.js"></script>
-
接下来,让我们将
@keyframes
代码转换为一个通用的动画混合器——删除代码末尾现有的两个块(第 15-29 行),然后用以下代码替换它:.keyframes (@name, @color0, @color25, @color50, @color100) { @-webkit-keyframes @name { 0% {background: @color0} 25% {background: @color25;} 50% {background: @color50;} 100% {background: @color100;} } @keyframes @name { 0% {background: @color0} 25% {background: @color25;} 50% {background: @color50;} 100% {background: @color100;} } }
-
接下来,我们添加一个新的混合器,它引用了我们刚刚创建的
@keyframes
代码:.keyframes(animbox, #85486d, #9F6287, #B87BA0, #B87BA0);
如果我们重新运行演示,我们应该看到效果没有变化。那么有什么不同,我们为什么在这里这样做?嗯,我们这样做有几个好处。
我们将 @keyframes
代码移动到了自己的混合器中——虽然这里的代码可能看起来没有缩短,但当我们创建更大、更复杂的动画并需要重复以允许供应商前缀时,好处将真正显现。
.keyframes
混合器现在可以放入我们的混合器库中;这意味着我们可以将库导入未来的项目中:
@import "animations.less";
在我们的代码中引用混合器:
.some-animation {
.keyframes(…);
…
}
使用 Less 简化我们的代码并不仅仅是让它更短;它还关于使其可重用并更容易添加到未来的项目中!
小贴士
代码中有一个更新的演示可用——提取并运行 animatebox-updated.html
来查看结果。
让我们继续,并专注于 Less 的实际应用。你有多少次为网站设计菜单,然后想到它变得越来越代码重复,需要动画?好吧,可能是一个有点牵强的问题,但这是可能的……
创建动画菜单
菜单是许多网站的典范;我们都需要某种形式的导航,但导航菜单的样式很大程度上取决于网站设计师的想象力。
我们甚至可以更进一步,给菜单添加一些有用的效果;我们至少可以动画下拉动作,使它们滑入得更加优雅。为了做到这一点,我们将回顾书中早期的一个练习——记得,在第四章,使用变量、混入和函数中,我们创建了一个使用一些 Less 函数的简单网页?好吧,我们将在这个页面上添加一个菜单,完成后,它将看起来类似于这个:
好的,让我们开始吧:
-
对于这个练习,我们需要这本书附带的代码下载副本;从中,提取
menus.html
的副本。它包含来自第四章,使用变量、混入和函数的代码副本,以及为我们菜单添加的额外标记和一些对导入 Less 文件的细微更改。 -
接下来,打开你选择的文本编辑器,并将以下代码添加到一个新文件中——我们将逐节分析它,从我们的菜单的主要容器开始:
#navigation { width: 788px; height: 35px; font-family: 'Kite One', sans-serif; font-weight: normal; font-size: 14px; ul { position: relative; z-index: 1000; list-style: none; margin: 0; padding: 0; } }
-
接下来是顶级菜单项:
#navigation > ul > li { position: relative; float: left; margin-right: 10px; &:hover ul ul { height: 0; } &:hover ul { height: 220px; } & > a:hover ul { height: 220px; } }
-
这些条目需要变成链接;所以,请继续添加这个样式规则:
#navigation > ul > li > a { background-color: #2c2c2c; color: #aaaaaa; display: block; padding: 8px 14px; text-decoration: none; transition: background-color 0.3s ease 0s; &:hover { background-color: #666666; color: #eeeeee; ul ul { height: 0; } } }
-
一些我们的子菜单有二级子菜单,所以我们需要在我们的样式中考虑到这些子菜单:
#navigation ul ul { width: 340px; position: absolute; z-index: 100; height: 0; overflow: hidden; transition: height 0.3s ease-in; li { background-color: #eaeaea; width: 170px; transition: background-color 0.3s ease; &:hover { background-color: #999; & > a { color: #ffffff; } & > ul { height: 220px; } } } }
-
这种样式适用于我们的第一级子菜单:
#navigation ul ul li a { display: block; text-decoration: none; margin: 0 12px; padding: 5px 0; color: #4c4c4c; &:hover { color: #ffffff; & > ul { height: 220px; } } }
-
最后,但绝对不是最不重要的——这为我们的二级子菜单提供了容器:
#navigation ul ul ul { left: 170px; width: 170px; li a { border: 0 !important; } }
-
我们需要一个箭头来告诉子菜单的用户,所以现在让我们添加一个箭头:
.arrow { background: url(arrow.png) right center no-repeat; }
-
将文件保存为
menus.less
。我们的menus.html
文件已经有一个链接到它,还有一个链接到base.less
;后者包含来自第四章,使用变量、混入和函数的原始代码,但已适当地重命名文件。
在这个阶段,如果我们预览结果,我们可以看到新的菜单,如图所示,这是本练习开始时的截图。
那么,我们在这里做了什么?在这个例子中,我们保持了非常简单;menus.less
中的大多数样式都是为了提供基本的样式来渲染我们的菜单。
我们添加了三个过渡语句,以给我们的菜单添加微妙的触感,使它们每个都能更平滑地滑入,然后突然出现。记住,动画元素可以为网站提供额外的动态感;在这个例子中,如果变换样式不被理解,那么菜单仍然可以工作,但不会在屏幕上优雅地渲染。
使用 Less 的库
在过去的几页中,我们创建了一些不同复杂性的优秀演示——它们展示了可以使用动画做什么,以及我们如何使用 Less。
问题在于,这里有一个小但关键的问题。有多少人注意到我们是从头开始创建每个演示的,包括所有的混合?我想是这样,Less 的一个原则是 DRY(不要重复自己)。
如果我们回顾一下第四章,使用变量、混合和函数,我们讨论的主题之一是在我们的代码中使用外部库。这样做意味着我们可以避免编写大量的混合——虽然我们这里的例子可能过于简单,不足以证明使用外部库的必要性,但在更复杂的网站上我们肯定需要至少使用一个外部库。
幸运的是,当处理动画时,我们可以继续使用 DRY(不要重复自己)的原则;有一些基于 Less 的库可以处理动画属性(这包括过渡和变换):
-
LESS Prefixer (
lessprefixer.com/
) -
More-or-less (
more-or-less.org/
) -
Animate.less (
github.com/machito/animate.less
) -
LESS Hat (
github.com/madebysource/lesshat
) -
Bootstrap 的 LESS (
github.com/twbs/bootstrap/
) -
LESS Elements (
www.lesselements.com/
)
我们甚至可以更进一步——如果 Less 中没有你喜欢的库,我们总是可以使用一个普通的 CSS 库。
这里的技巧是将它保存为 Less 文件,并以通常的方式将其合并。随着时间的推移,我们可以逐步将其转换为我们的技能提高。这种方法的优点是 Less 仍然会以正常的方式编译原始版本——别忘了,毕竟 Less 是 CSS 的超集。考虑到这一点,让我们看看一些纯 CSS 动画库的例子:
-
魔法 CSS (
github.com/miniMAC/magic
) -
Animate.css (
github.com/daneden/animate.css
) -
Effeckt.css (
github.com/h5bp/Effeckt.css
))
现在我们已经看到了一些我们可以使用的库的细节,让我们花点时间尝试将其中之一转换为 Less。我听到你问,“我为什么要这样做?”简单,虽然有一些好的 Less 库可用,但你可能会找到一个你更喜欢的 CSS 动画库,但没有 Less 版本。如果你找到了,那么我们就需要将其转换为使用 Less!
从其他库转换
Less 的美丽之处在于它是 CSS 的超集——这意味着将现有的 CSS 库转换为它的 Less 等价物比最初看起来要容易。其背后的技巧全在于规划——为了证明这一点,让我们通过使用 Magic CSS 动画库的简单示例来操作。
让我们从下载库的副本开始——我们可以通过浏览到raw.githubusercontent.com/miniMAC/magic/master/magic.css
并保存本地副本来完成此操作。使用你选择的文本编辑器打开magic.css
的副本,然后将其重新保存为magic.less
——就这样!
如果你期待更多,我很抱歉让你失望;从技术上讲,这是将库转换为它的 Less 等价物的最低要求。然后我们可以使用 Crunch!编译它,或者如果你已经按照第二章中的详细说明配置了 Sublime Text,那么编译将在你保存工作的时候完成。
现在,我们可以保持这个状态,但……我们的代码中有相当多的重复,这并不理想;我们肯定可以做得更好。现在让我们解决这个重复问题:
-
创建一个新文件,并将其保存为与原始
magic.less
文件相同的文件夹中的keyframes.less
。 -
在第 468 行或附近查找
@-moz-keyframes magic {
——从这一行选择到末尾,这将是在第 4595 行或附近。 -
将以下内容复制粘贴到您刚刚创建的
keyframes.less
文件中,然后保存文件。 -
回到
magic.less
。你需要导入你刚刚创建的新文件;所以,请继续在顶部添加以下行:@import "keyframes.less";
-
你也可以通过在
@import
语句下方立即添加以下行来改进动画类:.vendor(@property, @value) { -webkit-@{property}: @value; -moz-@{property}: @value; -ms-@{property}: @value; -o-@{property}: @value; @{property}: @value; }
-
现在来到了繁琐的部分:你需要将每个动画类转换为使用新的 mixin。让我们以第一个为例,它是
.magictime
:.magictime { -webkit-animation-duration: 1s; -moz-animation-duration: 1s; -ms-animation-duration: 1s; -o-animation-duration: 1s; animation-duration: 1s; -webkit-animation-fill-mode: both; -moz-animation-fill-mode: both; -ms-animation-fill-mode: both; -o-animation-fill-mode: both; animation-fill-mode: both; }
-
我们可以轻松地将动画类转换过来——这个技巧在于使用诸如 Sublime Text 之类的工具中的搜索和替换。我们可以更新
animation-duration
和animation-fill-mode
行以使用 Less mixin,然后删除剩余的行。 -
一旦完成搜索和替换工作,剩余的行可以完全删除。我们将得到以下作为第一个示例:
.magictime { .vendor(animation-duration, 1s); .vendor(animation-fill-mode, both); }
-
我们可以使用相同的过程,直到将
magic.less
中的所有动画类都转换完毕。
到目前为止,我们将有一个半转换的 CSS 文件——这将完美地工作。然而,我们可以使用同样的原则同时转换keyframes.less
文件——这将是留给你自己解决的问题!提示:代码下载中有一个示例,如果你真的卡住了...
使用供应商前缀——一个警告
话虽如此,我们必须关注的一个重要观点是:我们花了这么多时间转换文件,但我们可能正在遵循一个坏习惯!嗯——你怎么看待这个问题,我听到你问?
好吧,有些人会争论这个过程是一个反模式——一种不应该遵循的实践,因为它可能会使 CSS 比实际需要的更冗长。
注意
关于反模式,你可以参考 Mark Daggett 的有用文章,值得一读,可在markdaggett.com/blog/2011/12/04/css-anti-patterns/
找到。
我们可以进一步补充,因为供应商前缀会来来去去;将它们移动到一个文件中可能会帮助我们减少需要编写的代码量,但会假设供应商前缀对所有属性都是相同的。这不会是事实——问题是,我们无法在动画属性不再需要它们之前移除任何一个,而这可能还需要一段时间!
我在这里使用这个过程纯粹是为了说明它是如何完成的——这并不意味着它应该这样做。更好的做法是使用 Autoprefixer,例如 Alejandro Beltrán 的 Autoprefixer,它可以在github.com/ai/autoprefixer
找到。有一个 Autoprefixer 的插件可以允许它在 Sublime Text 中工作——这个插件可以从github.com/sindresorhus/sublime-autoprefixer
下载。
好的,让我们暂时放下编码,继续前进。我们花了一些时间使用 Less 来创建动画,并将一些从 CSS 转换过来。不过,有一个让人烦恼的问题,我相信你们也会问:使用 CSS 真的比使用 JavaScript 更好,还是其中还有更多我们最初没有意识到的内容?
使用 CSS 或 JavaScript
如果你曾经使用过 JavaScript(更有可能,jQuery),那么你就会知道我们可以用它来制作一些复杂的动画。在 CSS 中实现相同的效果可能会让一些人眼前一亮,但他们可能会问:哪个更好?如果你认为是 CSS,那么你是对的……也是错的!让我来解释一下。
传统观念一直认为 CSS 更好——毕竟,JavaScript 和 jQuery 使用自定义动画处理程序,这些处理程序每秒会在 30 到 60 次之间重复代码。这会给浏览器带来比仅运行纯 CSS 更大的压力。
然而,很多人都在为其中任何一个技术辩护;在网站上使用这两种技术都有明确的论点和反对意见。例如,在 CSS-Tricks 网站上,Jack Doyle(专业动画库 GSAP 的创建者)详细阐述了为什么使用 CSS3 动画并不总是正确的方向;CSS3 还有很长的路要走才能与 Flash 相媲美。
开发者 David Walsh 已经写了一篇同样有用的文章,该文章还解释了为什么可能会有一些情况下我们应该使用 CSS 或 JavaScript,以及前者的限制可能需要使用后者。然而,要真正扭转局面,请转到css3.bradshawenterprises.com/blog/jquery-vs-css3-transitions/
;你可以看到一个很好的演示,证明当使用 jQuery 等 JavaScript 库来动画化大量元素时,它们的性能实际上比 CSS 差。
注意
David 的文章可在davidwalsh.name/css-js-animation
找到;它绝对值得一读!
没有正确或错误答案;唯一确定的方法是使用 Chrome 开发者工具等工具测试你的动画,以评估对浏览器的影响。不过,一个很好的经验法则是使用纯 CSS 进行动画和 2D 变换。然而,如果你的动画涉及复杂的基于时间线的效果或你移动了大量元素,那么 JavaScript 将是一个更好的选择(动画通常需要比 JavaScript 更多的代码来创建相同的效果)。
只有测试才能告诉你是否做出了正确的选择;从查看你能在 CSS 中实现多少开始,如果 CSS 无法处理你的需求或对浏览器管理效果效率要求过高,则回退到使用 JavaScript。
注意
你可以在css-tricks.com/myth-busting-css-animations-vs-javascript/
上阅读完整的帖子。
好的,让我们继续前进;我们已经看到了为什么选择是否需要使用 jQuery 而不是 Less/CSS 很重要。假设你仍然使用 Less/CSS 来提供某种形式的动画,有一些技巧我们可以使用来帮助提高这些动画的性能;现在让我们来看看这些技巧。
提高动画的性能
与 CSS 动画一起工作可以非常有成效,但我们必须注意性能——如果没有谨慎处理,动画可能会导致浏览器不必要的负担,或者在移动设备上工作时会耗尽电池电量!
不幸的是,存在许多可能影响性能的因素,我们可能无法控制:
-
浏览器性能: 所有浏览器在处理 CSS3 和 JavaScript 时表现都不同。
-
GPU 性能: 一些浏览器现在将动画和过渡操作卸载到 GPU 上,在这种情况下,速度/性能受 GPU 限制。如果你使用的是集成 Intel GPU,与 NVIDIA 或 AMD 独立显卡相比,它可能不会非常流畅。
-
CPU 性能: 如果浏览器没有卸载到 GPU(因此成为瓶颈),主 CPU 将被使用。
-
浏览器中打开的其他标签页/窗口的数量:浏览器通常在标签页之间共享进程,因此其他标签页或浏览器中发生的其他动画或 CPU 消耗操作可能会造成性能下降。
-
在 CSS 代码中使用渐变或阴影属性:这可能会对性能造成重大影响,因此在动画元素时避免使用这些属性。
目前,提高性能的最好方法是将同时进行动画或过渡的事物数量限制在最少。
强制 CSS 动画使用硬件加速
虽然并非所有希望都破灭了——我们可以在代码中添加一个简单的属性transform: translateZ(0);
来强制浏览器在桌面或移动浏览器中触发硬件加速。这将把渲染任务交给 GPU,而不是 CPU。
例如,如果我们有一个名为.animate
的类,它看起来会像这样:
.accelarate {
-webkit-transform: translateZ(0);
-moz-transform: translateZ(0);
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
transform: translateZ(0);
//Add other properties below this line...
...
}
注意我们为什么需要为每个浏览器添加供应商前缀?translateZ(0)
属性仍然是实验性的,因此需要所有供应商前缀以确保完全支持。浏览器支持良好,但需要注意,过度使用它可能会导致性能问题和电池耗尽。
要查看性能是否受到影响的一个好方法是使用 Chrome 的时间轴和配置文件选项,在开发者工具选项中。请查看 Addy Osmani 在addyosmani.com/blog/performance-optimisation-with-timeline-profiles/
上的文章,他讨论了如何使用开发工具来衡量性能。这篇文章已经 2-3 年了,开发工具的工作方式已经有所变化,但原则仍然是有效的。
摘要
在网页或网站上对元素进行动画处理就像走钢丝——一步走错就能将一个看起来令人惊叹的网站变成一个真正的狗食般的混乱,这会让所有访问者都感到沮丧!在本章中,我们介绍了动画的基础知识,并看到了如何使用 Less 简化这个过程。在我们进入下一章之前,让我们花点时间回顾一下我们学到了什么。
我们首先简单介绍了什么是好的动画,然后转向检查 CSS 动画的工作原理。然后我们探讨了不同类型的动画,最后涵盖了这项技术至关重要的浏览器支持。
接下来,我们研究了如何通过重新设计一个简单的动画演示来使用 Less,从而简化动画样式的创建。然后我们转向创建一个更贴近现实世界的例子,即一个简单的菜单演示,它使用过渡来动画化下拉元素。在完成演示后,我们继续探讨如何使用 Less 库来帮助我们进行动画样式设计,并看到第四章中使用变量、混入和函数的原则在开发动画样式时可以轻松应用。在介绍了一些 CSS 动画库的例子之后,我们查看如何将其中之一转换为它的 Less 等价物。
在继续之前,我们讨论了监控供应商前缀的重要性以及有些人如何看待使用供应商混入(mixins)作为一种应被劝阻的反实践。然后我们讨论了性能可能受到一些我们无法控制的因素的影响,在查看我们如何启用硬件加速以提升性能之前。
哇!这是一次多么精彩的旅行!然而,这还没有结束:在这本书的最后一章,我们将探讨你如何为 Less 库做出贡献并帮助其扩展。毕竟,没有我们的帮助,它今天不可能达到这样的地位…!
第十四章。扩展和为 Less 做贡献
在这本书的整个过程中,我们涵盖了一系列主题,从入门 Less 到在 CMS 系统中使用它或创建颜色。
到这个时候,我们可以说,世界就是你的牡蛎。希望这本书已经足够激发你的兴趣,去开发下一个杀手级网络应用。然而,我怀疑有些人会说,“如果我想修改 Less 本身怎么办?”
这是一个合理的问题。毕竟,许多开源应用(Less 也不例外)的宗旨是,如果你在项目中得到了帮助,就尝试为项目做出贡献。幸运的是,有几种方式你可以做出贡献,从报告问题和错误到提交 Less 未来版本的补丁和功能请求。
在本章中,我们将快速浏览一些你需要知道的信息,以便能够为项目做出贡献。在本章中,我们将涵盖以下主题:
-
如何找到 Less 仓库
-
如何报告错误
-
如何贡献代码
-
测试
-
文档
想了解更多?让我们开始吧...!
定位 Less 仓库
到目前为止,我们已经花了不少时间学习 Less 及其工作原理。总有一天,我们可能会发现我们的代码存在问题,需要帮助。
对于大多数开源应用或项目,原始源代码将以某种形式提供;Less 也不例外。库和文档的源文件存储在 GitHub 的两个不同仓库中;它们可以从 Less 主网站的右上角访问:
我们可以通过这些链接访问 GitHub 仓库,或者直接通过 URL:
-
对于主要文档仓库,请访问
github.com/less/less-docs
。 -
要记录任何关于 Less 文档的问题,请访问
github.com/less/less-docs/issues
;你还可以查看任何现有的问题列表。 -
你可以在
github.com/less/less.js
找到感兴趣的 主要仓库。这是 Less 的源代码仓库,任何更改或更新都将作为每个版本的一部分合并到核心中。 -
如果你需要记录任何问题,请访问
github.com/less/less.js/issues
;有一个活跃的社区将能够提供建议和帮助解决问题。
现在我们已经看到了我们可以去哪里寻求更多帮助,让我们将注意力转向可能是最重要的一步:记录我们的求助请求。
在 Less 中查找和报告问题
一旦你开始使用 Less,无疑会有需要一些帮助的情况。Less 团队建议最佳的帮助请求记录位置是在流行的 Stack Overflow 网站上,它是www.stackoverflow.com
。然而,如果你遇到的问题与网站上文档相关,那么应该在 GitHub 的 Less 文档区域记录,网址为github.com/less/less-docs
。
任何请求帮助的请求都不应该在 GitHub 的 Less 区域记录;这些应该保留用于记录和修复代码中的错误。Less 核心团队发布了一套指南,以帮助提出问题,确保它们有最佳的成功解决机会:
-
搜索现有问题:团队收到了很多重复的问题,所以首先检查是否有人已经报告了相同的问题,以及是否已经发布了修复方案。
-
创建一个隔离和可重现的测试用例:这有助于确保问题在 Less 库中;查看
css-tricks.com/reduced-test-cases/
以获取如何创建此类测试用例的一些提示。 -
使用最新版本进行测试:令人惊讶的是,很多问题都是通过更新到 Less 的最新版本解决的。
-
包含一个实时示例:你可以使用
www.less2css.org
来帮助创建和分享你的隔离测试用例。 -
分享信息:尽可能多地分享有关你问题性质的信息。以下是一些有用的信息片段,将有助于:
-
提及操作系统和版本
-
描述你是如何使用 Less 的
-
如果你将其用于浏览器,请包括浏览器和版本以及你使用的 Less.js 版本
-
包括你是否使用命令行(
lessc
)或外部工具 -
尝试包括重现错误的步骤
-
如果你对你报告的错误有解决方案或建议,请包括它,或者发起一个 pull request——不要假设维护者知道如何修复它,仅仅因为你知道!
如果你发现问题不仅仅是关于如何做某事的问题,而且库本身确实存在错误,那么你可能需要提交一个错误报告。让我们看看如何在 GitHub 中实现这一点。
报告库中的错误
不,这并不是一个找借口去消灭你找到的每一个昆虫(请原谅这个双关语),而是一个机会,如果你在 Less 中遇到问题或错误,可以寻求帮助。
Less 团队欢迎任何关于错误的报告,一旦修复,可以帮助改进代码;以下指南值得注意:
-
使用 GitHub 问题搜索功能:检查该问题是否已经被其他人报告;重复努力是不值得的,但你可能想加入现有的问题日志,以帮助优先处理该问题。
-
检查问题是否已修复:尝试使用最新的主分支或开发分支下载来重现它,这些通常可以在存储库中找到。
-
隔离问题:创建一个简化测试用例和一个实时示例;Chris Coyier 在
css-tricks.com/reduced-test-cases/
上有一篇有用的文章,介绍了如何生成这样的测试用例。
一份好报告的关键是提供足够的信息供他人工作,但不要过度。找到正确的平衡并不容易。这需要随着时间的积累而积累经验。然而,你可以通过提供关键细节来帮助他人,例如:
-
你的环境是什么?问题是仅限于一个浏览器,还是会在不同的浏览器中显现?
-
重现问题的步骤是什么,它们是否一致?
-
你期望看到什么样的结果?
所有这些细节(以及更多)将帮助人们修复你发现的任何错误;为了帮助呈现正确的信息,你可以遵循以下有用的格式:
注意
简短且描述性的示例错误报告标题
请提供问题的总结以及它发生的浏览器/操作系统环境。如果合适,包括重现错误的步骤。
-
这是第一步。
-
这是第二步。
-
进一步的步骤等等。
<url>
是一个指向简化测试用例的链接,展示了问题。
任何其他与报告问题相关的信息。这可能包括你已识别为导致错误的代码行以及潜在解决方案(以及你对它们的评价)。
如果你想要帮助修复一些错误,那么你需要遵循一个过程。让我们改变方向,看看你如何可以帮助贡献到这个库。
为 Less 源代码做出贡献
一旦你更习惯于使用 Less,你可能会想要为项目做出一些贡献。毕竟,项目所有者花费了无数小时开发这个库,所以任何帮助都是受欢迎的。
你可以帮助贡献到项目的两种方式是提交功能请求和创建拉取请求。在我们查看它们之前,有一些小工作值得完成,那就是安装 Node.js 和 Grunt。
准备工作
如果你花时间在为 Less 开发代码提交,那么安装两个工具是至关重要的;这些是 Less 整个开发过程的关键:
-
Node.js:可以从
www.nodejs.org
为你的平台下载。在撰写本文时,最新版本是 0.10.28。 -
Grunt:可以从
www.gruntjs.com
获取;在撰写本文时,版本为 0.4.5。
接下来,我们需要安装 Grunt。在命令提示符中输入以下内容并按 Enter:
npm install -g grunt-cli
现在我们已经设置了基本环境,让我们依次查看每种贡献方法,首先是功能请求。
提交功能请求
功能请求总是受欢迎的。建议您花点时间了解您的想法是否与项目的愿景相符。
提供一个足够有力的新功能案例取决于您能提供的详细程度。请记住,由于项目是开源的,您可能发现先对现有项目进行分叉,然后再添加您的新功能更可取。
值得检查是否有人已经提出了建议。团队总是欢迎新想法,但除非有充分的理由,否则不会添加功能。可能更可取的是在第三方构建系统(如 assemble-less)中实现新功能,而不是在核心库内部实现。
创建拉取请求
如果您提交的功能请求已经引起关注,并且可能被提交到源代码中,团队总是鼓励在可能的情况下提交拉取请求。
团队要求,如果您创建拉取请求,它应保持范围,避免包含不相关的提交。我总是试图遵循每次提交一个更改的原则,这使得在以后需要时更容易移除。如果您的拉取请求旨在实施重大更改,例如移植到新语言,那么首先询问开发者是值得的;否则,这可能意味着您可能会花费大量时间开发开发者可能不想合并到主库的新功能。
如果您的拉取请求解决了现有问题,但使用了不同的(或更好的)解决方案,那么它应该作为一个新问题提出,而不是作为现有拉取请求的替代。提交的任何拉取请求都应附带一组测试。我们将在本章后面更详细地介绍这一点。
无论开发拉取请求的原因是什么,您都应该遵循一些简单的标准,以确保提交的代码的一致性:
-
总是使用空格,而不是制表符
-
以分号结束行
-
大致遵循 jsHint 标准
提交的任何补丁都将由 Less 团队根据 Apache 许可证进行许可。
注意
为了帮助您通过 Git 提交时遵循一致的过程,值得看看 Nicolas Gallagher 提出的流程,该流程可在 github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md
找到。
使用 Git 与 GUI
值得注意的是,使用 Git 需要一定的技能水平。通常使用基于 GUI 的客户端比使用命令行更容易;在 git-scm.com/downloads/guis
可以找到一些流行的客户端列表。我个人的最爱是 GitHub for Windows,可在 windows.github.com
获取。
注意
如果你想了解更多关于 Git 的知识,那么查看由 Packt Publishing 出版的 Git: Version Control for Everyone,作者是 Ravishankar Somasundaram,或者访问网站 git-scm.com/book
。
测试您的提交
提交任何功能更改的关键部分是确保你的代码已经通过了 linting 过程,以分析任何潜在的错误。有几种方法可以做到这一点,但首选的是使用 Grunt;已经产生了包来帮助这个过程。
一个很好的例子是 Jacob Gable 编写的 Less Lint Grunt 插件,可在 github.com/jgable/grunt-lesslint
获取。对于更深入的选择,您可以查看 Axisto Media 的 Tom Loudon 的文章,在 coderwall.com/p/g1kqzg
,该文章详细介绍了使用 Grunt 添加预 Git 提交 linting 的过程。
一旦你的代码通过了 linting,那么它需要经过测试。为此,我们需要做以下操作(假设你已经按照本章前面“准备就绪”部分中的说明安装了 Node 和 Grunt):
-
克隆 Less 仓库。这可以通过命令行完成,也可以使用 GitHub for Windows 这样的 GUI。
-
打开命令提示符,然后更改文件夹到您存储 Less 仓库本地副本的位置。
-
在命令提示符下,输入
npm install
以安装 Less 的 npm 依赖项。 -
完成后,在提示符下输入以下命令:
grunt browsertest-server
现在,您可以访问 http://localhost:8088/tmp/browser/
来查看测试运行器页面。您还应该在提示符下能够输入 lessc <文件名>.less
;这将由 Less 编译并在屏幕上渲染;这将允许您将其与本地编译的 CSS 版本进行比较,以查看是否产生相同的结果。
为 Less 文档做出贡献
到目前为止,我们已经看到了如何为 Less 库做出贡献,无论是报告问题或错误,还是通过贡献新功能的建议和代码。如果你的问题出在文档上怎么办?
Less 团队维护源文档在 GitHub 上;在这里,您可以找到在 www.lesscss.org
发布的所有文档的源代码,如果您发现任何问题,可以选择提出问题,或者提交拉取请求以帮助维护文档。所有文档内容都可以在 ./content
目录中找到:
注意
要了解 Less 的工作方式,查看 Less 示意图是值得的,该示意图可在www.gliffy.com/go/publish/4784259
找到。
在本地安装文档
要开始更新文档,我们需要在自己的电脑上建立一个本地副本。这需要安装 Assemble (assemble.io/
),按照以下步骤操作:
-
浏览到 Less 文档的 GitHub 区域,该区域位于
github.com/less/less-docs
,然后点击下载 ZIP以获取 Less 文档的最新版本。 -
在您的电脑上创建一个文件夹。为了本练习的目的,我们将假设它被命名为
lessdocs
;将存档文件的内容提取到这个文件夹中。 -
打开命令提示符,并将当前位置更改为
lessdocs
文件夹。 -
在提示符下,输入
npm install
以安装 Assemble,然后等待其完成过程: -
完成后,输入此命令以构建文档:
node data/utils/pkg && grunt
当这完成时,您将能够离线查看文档,并使用它向 GitHub 提交拉取请求,供 Less 团队考虑。
遵循编码指南
现在我们已经在本地上安装了文档的副本,我们准备开始贡献!然而,在我们这样做之前,有一些值得注意的指南,这将有助于使文档保持一致、可读和可维护。让我们更详细地简要查看这些标准,从 Markdown 标准开始:
-
使用
#
作为标题,而不是下划线。下划线不是语义化的,不够灵活,并且在代码高亮显示器中并不总是被正确突出显示。 -
总是在
#
和标题之间添加一个空格。 -
将内联代码用单个反引号包裹,或将代码块用三个反引号(代码分隔符)包裹。
-
在代码块中,总是在第一个代码分隔符之后使用正确的语言。尽管 GitHub 不会高亮显示 Less,但使用正确的语言时,我们的文档更有可能出现在 GitHub 和 Google 的搜索结果中。例如,使用
js`
lessjs` for Less and ````
jscss ````用于 CSS。
对于 Less 代码的标准化维护也存在类似的指南;它们在CONTRIBUTING.md
页面中完整重现,该页面列在github.com/less/less-docs
的主索引中;值得注意的主要点包括适当的间距、多行格式化的使用以及正确使用引号。
注意
值得一看的是报告问题、错误和功能请求的指南,这些指南基于 Nicolas Gallagher 创建的通用集合,适用于任何 GitHub 项目;您可以在github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md
查看原始集合。
如果您遵循这些指南,将有助于保持与 Less 相关的文档的一致性和可管理性。
摘要
在学习 Less 的过程中,我们涵盖了大量内容,最后查看您可以通过报告问题和错误,或提交代码以帮助修复或改进库中现有功能的形式回馈项目。
我们本章从查看如何访问 Less 的两个源代码库开始,还涵盖了您可以在 GitHub 问题日志中记录源代码和文档中的问题和错误。
我们转向查看提交功能或拉取请求时应遵循的指南,并快速查看提交的任何代码应如何与 Less 测试进行测试,并进行 lint 检查以确保代码质量得到保持,并修复任何错误。
我们随后探讨了您如何通过报告问题或改进建议来为文档做出贡献。我们讨论了在查看确保 Less 项目文档质量得到保持所需遵循的标准之前,需要下载和安装文档的本地副本。
到此,我们已到达本书的结尾。我真诚地希望您像我一样享受学习如何使用 Less 的旅程,并且它对您的未来项目有所帮助。
附录 A. Less 中的颜色函数
Less 库包含了一些我们可以用来在网站上操作颜色的颜色函数——本附录列出了每个函数的详细信息,包括定义颜色格式、通道颜色、执行颜色操作和混合颜色这四个组。
定义颜色格式
以下是一系列处理 Less 中颜色格式的颜色函数:
函数 | 函数的作用 | 示例值 |
---|---|---|
rgb |
从十进制红色、绿色和蓝色(RGB)值创建一个不透明颜色对象 | rgb(90, 129, 32) |
rgba |
从十进制红色、绿色、蓝色、alpha(RGBA)值创建一个透明颜色对象 | rgba(90, 129, 32, 0.5) |
argb |
创建一个#AARRGGBB 格式(不是#RRGGBBAA! )的颜色十六进制表示 |
argb(rgba(90, 23, 148, 0.5)); |
hsl |
从色调、饱和度和亮度(HSL)值创建一个不透明颜色对象 | hsl(90, 100%, 50%) |
hsla |
从色调、饱和度、亮度和 alpha(HSLA)值创建一个透明颜色对象 | hsl(90, 100%, 50%, 0.5) |
hsv |
从色调、饱和度和值(HSV)值创建一个不透明颜色对象 | hsv(90, 100%, 50%) |
小贴士
有关更多信息,请阅读 Less 主站上的文档lesscss.org/functions/#color-definition
。我还创建了一个 CodePen,展示了这些效果的实际应用——可在codepen.io/alibby251/pen/horqx
找到。
使用 Less 颜色通道
以下是可以让我们在 Less 中进行颜色通道操作的函数列表:
函数 | 函数的用途 | 示例值 |
---|---|---|
色调 |
从 HSL 颜色空间中提取颜色对象的色调通道 | 色调(hsl(90, 100%, 50%)) |
饱和度 |
从 HSL 颜色空间中提取颜色对象的饱和度通道 | 饱和度(hsl(90, 100%, 50%)) |
lightness |
从 HSL 颜色空间中提取颜色对象的亮度通道 | lightness(hsl(90, 100%, 50%)) |
hsvhue |
从 HSV 颜色空间中提取颜色对象的色调通道 | hsvhue(hsv(90, 100%, 50%)) |
hsvsaturation |
从 HSV 颜色空间中提取颜色对象的饱和度通道 | hsvsaturation(hsv(90, 100%, 50%)) |
hsvvalue |
从 HSV 颜色空间中提取颜色对象的值通道 | hsvvalue(hsv(90, 100%, 50%)) |
红色 |
提取颜色对象的红色通道 | 红色(rgb(10, 20, 30)) |
绿色 |
提取颜色对象的绿色通道 | 绿色(rgb(10, 20, 30)) |
蓝色 |
提取颜色对象的蓝色通道 | 蓝色(rgb(10, 20, 30)) |
alpha |
提取颜色对象的 alpha 通道 | alpha(rgba(10, 20, 30, 0.5)) |
亮度 |
计算颜色对象的亮度(感知亮度) | 亮度(rgb(100, 200, 30)) |
luminance |
计算未进行伽玛校正的亮度值 | luminance(rgb(100, 200, 30)) |
小贴士
有关更多信息,请阅读 Less 主站上的文档lesscss.org/functions/#color-channel
。
对颜色进行操作
以下是可以应用于 Less 代码的操作函数列表:
函数 | 函数的用途 | 示例值 |
---|---|---|
saturate |
通过绝对量增加 HSL 颜色空间中颜色的饱和度。 | saturate(hsl(0, 59.4%, 40.6%), 20%); |
desaturate |
通过绝对量减少 HSL 颜色空间中颜色的饱和度。 | desaturate(hsl(0, 59.4%, 40.6%), 20%); |
lighten |
通过绝对量增加 HSL 颜色空间中颜色的亮度。 | lighten(hsl(0, 59.4%, 40.6%), 20%); |
darken |
通过绝对量减少 HSL 颜色空间中颜色的亮度。 | darken(hsl(0, 59.4%, 40.6%), 20%); |
fadein |
减少颜色的不透明度(或增加不透明度),使其更不透明。 | fadein(hsl(0, 59.4%, 40.6%), 20%); |
fadeout |
增加颜色的不透明度(或减少不透明度),使其更不透明。 | fadeout(hsl(0, 59.4%, 40.6%), 20%); |
fade |
设置颜色的绝对透明度。无论颜色是否已经具有不透明度值,都可以应用于颜色。 | fade(hsl(0, 59.4%, 40.6%), 20%); |
提示
更多信息,请参阅 Less 主站上的文档lesscss.org/functions/#color-operations
。我还创建了一个 CodePen,展示了这些效果的实际应用——可在codepen.io/alibby251/pen/KGltj
找到。
颜色混合
我们最后的一组函数用于处理 Less 中的颜色混合:
函数 | 函数的作用 | 示例值 |
---|---|---|
multiply |
乘以两种颜色。 | multiply(#9ec1ef, #091d37); |
screen |
与multiply 相反。结果是颜色更亮。 |
screen (#9ec1ef, #091d37); |
overlay |
结合了multiply 和screen 的效果。条件性地使亮通道更亮,暗通道更暗。 |
overlay (#9ec1ef, #091d37); |
softlight |
与overlay 类似,但避免了纯黑色变为纯黑色,纯白色变为纯白色。 |
softlight (#9ec1ef, #091d37); |
hardlight |
与overlay 相同,但颜色角色相反。 |
hardlight (#9ec1ef, #091d37); |
difference |
在通道基础上从第一个颜色中减去第二个颜色。 | difference (#9ec1ef, #091d37); |
exclusion |
与difference 类似,但对比度较低。 |
exclusion (#9ec1ef, #091d37); |
average |
在每个通道(RGB)的基础上计算两种颜色的平均值。 | average (#9ec1ef, #091d37); |
negation |
与difference 相反。 |
negation (#9ec1ef, #091d37); |
提示
更多信息,请参阅 Less 主站上的文档lesscss.org/functions/#color-blending
。我还创建了一个 CodePen,展示了这些效果的实际应用——可在codepen.io/alibby251/pen/IKqEk
找到。