LESS-Web-开发基础知识-全-
LESS Web 开发基础知识(全)
原文:
zh.annas-archive.org/md5/E32D57C9868AAE081EFB9D0BCBCFBAE6
译者:飞龙
前言
在 1999 年 HTML 4.01 引入后,Web 发生了快速变化。许多新设备,如平板电脑和手机,应运而生。移动互联网变得更快、更便宜和更稳定。W3C 于 2007 年启动了 HTML5 工作组。2012 年 12 月,W3C 将 HTML5 指定为候选推荐标准。HTML5 与 CSS3 一起工作。如今,所有主要浏览器(Chrome、Safari、Firefox、Opera、IE)都支持 HTML5。
CSS3 的影响是巨大的。如今,CSS3 不仅用于为 HTML 文档设置样式,而且在设计的责任方面也扮演着重要的角色。最后但并非最不重要的是,CSS3 通过动画和过渡等功能扩展了 CSS。
我们不需要外部 Flash 组件来进行复杂的动画。看看www.hongkiat.com/blog/css3-animation-transition-demos/
或查看以下截图中的有趣的猫头鹰:
在前面的截图中,猫头鹰仅使用 HTML5 和 CSS3 构建。通过按下按钮,实时版本可以眨眼和看。
响应式设计允许您使用只有一个代码库构建网站的一个版本,该版本在不同设备上(如手机、平板电脑和台式机)运行良好并且外观良好。不需要为不同的移动和台式机版本构建任何技术原因,如下图所示:
有了所有这些新东西,CSS(或 Web)开发人员的工作变得更加复杂。Web 开发人员需要了解复杂的 CSS3、浏览器和设备之间的差异、动画和其他样式效果。编写正确和功能性的 CSS 代码将是第一要务;使这些代码可读、可维护并在所有主要浏览器上运行将是第二要务。CSS 文件在开发和维护过程中会变得越来越混乱。CSS 没有修改现有值或重用常见样式的能力。此外,在 CSS 中无法进行数学运算或定义变量。这就是 Less 的用武之地。
Less(Leaner CSS)是由 Alexis Sellier 设计的动态样式表语言。它始于 2010 年,现在由 Less 核心团队维护和扩展。Less 帮助您使 CSS 代码可维护、可重用,并防止代码重复。
在本书中,您将学习如何编写、编译和理解 Less。我们将帮助您更快、更具成本效益地进行 Web 开发。您将获得将 Less 集成到当前和新项目中的实用技巧。阅读本书后,您将能够使用 Less 编写清晰和可读的 CSS3。与花费时间调试特定设备或浏览器的复杂 CSS 代码相比,您可以更多地关注真正的设计任务。
您的客户将对您的先进和稳定的设计感到满意。这将减少开发和维护时间,从而降低设计成本。
Less 通过函数和变量扩展了 CSS。从语义上讲,有效的 CSS 也是有效的 Less。最初的 Less 版本是用 Ruby 编写的;现在,Less 是用 JavaScript 编写的。
Less 被称为 CSS 预编译器。这意味着最终产品将用于生产。在这种情况下,最终产品将是有效的、紧凑的和可读的 CSS 代码。此外,预编译的 Less 代码也可以实时编译。Less 提供了服务器端和客户端选项来实现这一点。通过现代 Web 浏览器中的 LESS.js 进行实时客户端编译,可以轻松进行测试。服务器端编译还提供了使用 Less 构建应用程序以及创建动态 CSS 的机会。
此外,其他人也知道 Less 的强大。Twitter 的 Bootstrap 和 Roots 等项目都依赖于 Less。这些项目使用 Less 构建了清晰和可扩展的框架。您不能忽视这一证据。停止编写带有错误和浏览器缺陷的繁琐 CSS,并通过阅读本书了解 Less。
Less 是开源的,根据 Apache 许可证授权。在撰写本书时,最新版本是 1.7。Less 的源代码将在 GitHub 上维护。每个人都可以为其做出贡献。你可以免费使用 Less。
本书涵盖内容
第一章,“用 Less 改进 Web 开发”,展示了 CSS3 如何为网页设计师带来了高级功能,如渐变、过渡和动画。它还解释了 CSS 代码变得更加复杂和难以维护。Less 帮助你使你的 CSS 可维护、可重用,并防止代码重复。
第二章,“使用变量和混合”,解释了为什么变量允许你在一个地方指定广泛使用的值,然后在整个样式表中重复使用它们,从而使全局更改变得像改变一行代码一样容易。混合允许你将一个类的所有属性嵌入到另一个类中,只需将类名包含为其属性之一。本章还解释了参数化混合是什么以及如何使用它们。
第三章,“嵌套规则、操作和内置函数”,解释了使用嵌套规则来使继承清晰,并使样式表更短。本章还解释了如何创建属性之间的复杂关系以及如何使用 Less 的内置函数。
第四章,“避免重复造轮子”,教你 Less 代码和混合可以变得复杂,因为它们处理不同的浏览器和设备。本章还解释了预构建的混合和其他帮助你(重新)使用它们的来源。
第五章,“在你自己的项目中集成 Less”,教你如何为新项目组织文件,或者准备使用 Less 的项目。
第六章,“Bootstrap 3、WordPress 和其他应用”,解释了 Bootstrap 是什么,并展示了使用 Less 与 Bootstrap 的优势。本章还教你如何使用 Less 构建 Web 应用程序或将其集成到你的 WordPress 主题中。
你需要什么
为了理解并充分利用本书的内容,我们希望你之前已经用 CSS 构建过网站。需要基本的 CSS 理解。理解 CSS 选择器和 CSS 优先级将帮助你充分利用本书。我们还将在第一章中简要介绍这些 CSS 方面。理解在 JavaScript 等函数式语言中使用函数和参数的基础知识将是有价值的,但不是必需的。如果你对函数和参数一无所知,不要惊慌。本书包含清晰的示例。即使没有任何(函数式)编程知识,你也可以学会如何使用 Less,本书将帮助你做到这一点。最重要的技能将是学习的意愿。
本书的所有章节都包含示例和示例代码。运行和测试这些示例将帮助你发展你的 Less 技能。你需要一个现代的网络浏览器,如 Google Chrome 或 Mozilla Firefox 来运行这些示例。使用任何首选的文本或 CSS 编辑器来编写你的 Less 代码。
这本书是为谁准备的
每个与 CSS 一起工作并希望在真正的设计任务上花更多时间的网页设计师都应该阅读这本书。无论你是初学者网页设计师还是使用 CSS 多年的人,都将从阅读本书中受益,并学会如何利用 Less。我们还推荐这本书给现代网页设计和计算机科学的教师和学生。Less 不依赖于平台、语言或 CMS。如果你使用 CSS,你可以并且会从 Less 中受益。
约定
在本书中,您会发现许多不同类型信息的文本样式。以下是一些样式的示例,以及它们的含义解释。
文本中的代码词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL 和用户输入显示如下:“请注意,在这种情况下,ID 是以#
开头的唯一选择器;相同 HTML 元素的选择器[id=]
算作属性。”
代码块设置如下:
.box-shadow(@style, @c) when (iscolor(@c)) {
-webkit-box-shadow: @style @c;
-moz-box-shadow: @style @c;
box-shadow: @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
.box-shadow(@style, rgba(0, 0, 0, @alpha));
}
当我们希望引起您对代码块的特定部分的注意时,相关的行或项目会以粗体显示:
.box-shadow(@style, @c) when (iscolor(@c)) {
-webkit-box-shadow: @style @c;
-moz-box-shadow: @style @c;
box-shadow: @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
.box-shadow(@style, rgba(0, 0, 0, @alpha));
}
任何命令行输入或输出都是这样写的:
# lessc -c styles.less > styles.css
新术语和重要单词以粗体显示。您在屏幕上看到的单词,例如菜单或对话框中的单词,会以这种方式出现在文本中:“点击下一步按钮会将您移动到下一个屏幕。”
注意
警告或重要提示会出现在这样的框中。
提示
技巧和窍门会出现在这样的样式中。
第一章:使用 Less 改进 Web 开发
在现代网页设计中,无法想象没有 CSS。有了 CSS3,网页设计师可以依赖于高级功能,如渐变、过渡和动画。另一方面,CSS 代码变得更加复杂和难以维护。Less是一种 CSS 预处理器,它使用现代编程语言的概念扩展了 CSS。Less 使您能够在编写 CSS 时使用变量、函数、操作,甚至规则或选择器嵌套。Less帮助您使用不要重复自己(DRY)原则编写 CSS。DRY 原则防止您在代码中重复任何信息。
本章将涵盖以下主题:
-
CSS3 介绍
-
将 Less 编译成 CSS
-
供应商特定规则
-
CSS3 圆角、动画和渐变
-
使用 box-sizing border-box
-
服务器端编译和使用 GUI
使用 CSS3 为您的 HTML 设置样式
在网页设计中,您将使用 HTML 来描述文档的结构,使用 CSS 语言来描述它们的呈现,包括字体、颜色和布局。当前标准的 HTML5 和 CSS3 版本适用于大多数现代浏览器和移动设备。CSS3 通过其他新的选择器、文本效果、背景渐变和动画扩展了旧的 CSS。CSS3 的强大功能、新功能以及在使用 HTML5 和 CSS3 的移动设备上的高接受度使它们成为现代网页设计的标准。HTML5 和 CSS3 的组合非常适合构建响应式网站,因为它们在手机(和其他设备)上的高接受度。
HTML5 和 CSS3 一起引入了许多新功能。在本书中,您将了解到学习它们概念时最重要的功能。
使用 CSS 选择器为您的 HTML 设置样式
使用Less(和 CSS),您可以使用选择器来为您的 HTML 代码设置样式。CSS 选择器是用于识别应该设置样式的网页 HTML 元素的模式或名称。CSS 选择器在编写Less代码时起着重要作用。
对于body p.article {color:red}
,这里的选择器是body p.article
。选择器不仅仅指一个元素。它们可以指向多个元素,不同的选择器可以指向同一个元素。例如,单个p
选择器指的是所有的p 元素
,包括具有.article
类的p 元素
。在冲突的情况下,级联和特异性决定应该应用哪些样式。在编写Less代码时,我们应该牢记上述规则。Less使得编写复杂的 CSS 变得更容易,而不会改变您的网站外观。它不会对最终的 CSS 引入任何限制。使用Less,您可以编辑结构良好的代码,而不是改变最终 CSS 的效果。
CSS3 引入了许多新的和方便的选择器。其中之一是:nth-child(n)
,它使得在 HTML 文档中可以对每四个段落的p
标签进行样式设置成为可能。这样的选择器为 CSS3 添加了强大的功能。现在我们能够仅使用 CSS 执行操作,而在过去我们需要 JavaScript 或硬编码样式(或至少需要类)。这也是学习Less的原因之一。强大的选择器将使 CSS 变得更加重要,但 CSS 代码也变得繁琐和难以维护。Less将在 CSS 中解决这个问题,甚至使复杂的代码变得灵活和易于维护。
注意
请访问developer.mozilla.org/en-US/docs/Web/CSS/Reference#Selectors
获取完整的 CSS 选择器列表。
CSS 中的特异性、继承和级联
在大多数情况下,许多 CSS 样式可以应用于同一个 HTML 元素,但只有一个样式会获胜。W3C 规范描述了哪些 CSS 样式具有最高优先级并最终将被应用。您可以在以下部分找到这些规范。
关于重要性顺序的规则在 CSS3 中并没有发生重大变化。它们被简要提及,以帮助你理解Less/CSS 中一些常见的陷阱以及如何解决它们。迟早,你会遇到这样的情况,你试图将 CSS 样式应用到一个元素,但它的效果却看不见。你会重新加载,拔头发,一遍又一遍地检查拼写错误,但什么都不会有用。这是因为在大多数情况下,你的样式将被另一个具有更高优先级的样式所覆盖。
CSS 中级联的全局规则如下:
-
找到适用于所讨论的元素和属性的所有 CSS 声明。
-
内联样式具有最高的特异性,除了
!important
。CSS 中的!important
语句是一个用于增加声明权重的关键字。!important
语句添加在 CSS 属性值的末尾。之后,检查是谁设置了声明;作者设置的样式比用户或浏览器(默认)定义的样式具有更高的特异性。默认意味着样式是由 Web 浏览器设置的,作者样式是由网页中的 CSS 定义的,用户样式是由用户通过其 Web 浏览器的设置设置的。用户的重要性高于默认值,而带有!important
语句的代码(参见第二章,使用变量和混合中的Less含义)将始终具有最高的特异性。请注意,像 Firefox 这样的浏览器有选项来禁用页面以使用其他替代的用户定义字体。在这里,用户设置将覆盖网页的 CSS。这种覆盖页面设置的方式不是 CSS 优先级的一部分,除非它们使用!important
设置。 -
计算特异性,这将在下一节中讨论。
-
如果两个或更多规则具有相同的优先级和特异性,则最后声明的规则获胜。
作为Less/CSS 设计师,你在大多数情况下将使用计算的 CSS 特异性。
CSS 特异性的工作原理
每个 CSS 声明都有一个特异性,这将根据声明的类型和选择器的使用来计算。内联样式将始终具有最高的特异性,并且将始终被应用(除非被前两个级联规则覆盖)。在实践中,你不应该在许多情况下使用内联样式,因为它会违反 DRY 原则。它还会阻止你在一个集中的位置上更改样式,并阻止你使用Less进行样式设置。
内联样式声明的一个示例如下所示:
<p style="color:#0000ff;">
之后,选择器中 ID 的数量将是计算特异性的下一个指标。#footer #leftcolumn {}
选择器有 2 个 ID,#footer {}
选择器有 1 个 ID,依此类推。
提示
请注意,在这种情况下,ID 是以#
开头的唯一选择器;相同 HTML 元素的选择器[id=]
计为一个属性。这意味着div.#unique {}
有 1 个 ID,而div[id="unique"] {}
有 0 个 ID 和 1 个属性。
如果两个声明的 ID 数量相等,则选择器中类、伪类和属性的数量将很重要。类以点开头。例如,.row
是一个类。伪类,比如:hover
和:after
,以冒号开头,而属性,当然,是href
、alt
、id
等。
#footer a.alert:hover {}
选择器得分为 2(1 个类和 1 个伪类),而#footer div.right a.alert:hover {}
选择器得分为 3(2 个类和 1 个伪类)。
如果这两个声明的值相等,我们可以开始计算元素和伪元素。最新的变量将使用双冒号(::
)定义。伪元素允许作者引用其他无法访问的信息,比如::first-letter
。下面的例子展示了它是如何工作的。
#footer div a{}
选择器得分为 2(2 个元素),而#footer div p a {}
选择器得分为 3(3 个元素)。
当你的样式没有直接应用时,你现在应该知道该怎么做了。在大多数情况下,使你的选择器更具体以使你的样式应用。例如,如果#header p{}
不起作用,那么你可以尝试添加#header #subheader p{}
ID,一个#header p.head{}
类,等等。
当级联和!important
规则无法给出明确的答案时,特异性计算似乎是一项困难且耗时的工作。虽然Less在这里无法帮助你,但诸如 Firebug(和其他开发者工具)之类的工具可以使特异性可见。下面是使用 Firebug 的一个示例,其中具有最高特异性的选择器显示在屏幕顶部,被覆盖的样式被划掉:
Firebug 中特异性的示例
使用灵活盒子构建你的布局
Flexbox 布局(也称为灵活盒子)是 CSS3 的一个新特性。它在创建响应式和灵活的布局方面非常有用。Flexbox 提供了根据不同屏幕分辨率动态更改布局的能力。它不使用浮动,并包含不会与其内容折叠的边距。不幸的是,目前主要浏览器对 Flexbox 布局的支持并不完整。我们关注 Flexbox 是因为它的强大,而且作为 CSS 的一个重要特性,我们也可以使用Less来生成和维护它。你可以在gist.github.com/bassjobsen/8068034
上访问一组用于 CSS3 Flexbox 的Less mixin。你可以使用这些 mixin 来使用Less创建 Flexbox 布局,而不使用重复的代码。
这些 mixin 现在不会被详细解释,但以下示例显示了Less如何减少创建 flex 容器所需的代码。使用 CSS,你可能会使用以下代码:
div#wrapper {
display: -webkit-flex;
display: -moz-flex;
display: -ms-flexbox;
display: -ms-flex;
display: flex;
}
提示
下载示例代码
你可以从你在www.packtpub.com/
的帐户中下载你购买的所有 Packt 图书的示例代码文件。如果你在其他地方购买了这本书,你可以访问www.packtpub.com/support/
并注册,以便直接通过电子邮件接收文件。
然而,如果你使用Less,可以通过插入以下代码行来产生相同的效果:
div#wrapper { .flex-display; }
你可以使用 Google Chrome 来测试你的 Flexbox 布局。在撰写本书时,Firefox 和 Internet Explorer IE11 也提供了对 Flexbox 布局的全面或更好的支持。之所以提到 Flexbox,是因为它们有潜力在未来的网页设计中扮演重要角色。目前,它们超出了本书的范围。本书将重点介绍如何使用Less、CSS 媒体查询和网格来创建响应式和灵活的布局。
注意
请访问developer.mozilla.org/en-US/docs/Web/Guide/CSS/Flexible_boxes
获取更多信息、示例和浏览器兼容性。
编译 Less
在深入研究 CSS 理论之后,你最终可以开始使用Less。如前所述,它与 CSS 具有相同的语法。这意味着任何 CSS 代码实际上也是有效的Less代码。使用Less,你可以生成可以用于样式化你的网站的 CSS 代码。从Less制作 CSS 的过程称为编译,你可以通过服务器端或客户端编译Less代码。本书中给出的示例将使用客户端编译。在这里,客户端指的是在浏览器中加载代码,并使用本地机器的资源将Less代码编译成 CSS 代码。本书使用客户端编译,因为这是最容易入门的方式,同时也足够好用于开发你的Less技能。
提示
需要注意的是,客户端编译的结果仅用于演示目的。对于生产环境,特别是在考虑应用程序性能时,建议使用服务器端的预编译。Less捆绑了一个基于Node.js的编译器,还有许多其他的 GUI 可用于预编译你的代码。这些 GUI 将在本章末讨论。
开始使用 Less
最后,你可以开始使用Less了。你需要做的第一件事是从www.lesscss.org/
下载Less。在本书中,将使用版本 1.6 的less.js
。下载后,应该创建一个 HTML5 文档。它应该包括less.js
和你的第一个Less文件。
请注意,你可以从www.packtpub.com上本书的可下载文件中下载示例,包括less.js
的副本。
首先,看一下这个简单但结构良好的 HTML5 文件:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example code</title>
<meta name="description" content="Example code">
<meta name="author" content="Bass Jobsen">
<link rel="stylesheet/less" type="text/css" href="less/styles.less" />
<script src="img/less.js" type="text/javascript"></script>
</head>
<body>
<h1>Less makes me Happy!</h1>
</body>
</html>
你可以看到,使用以下代码将Less文件添加到了这个文档中:
<link rel="stylesheet/less" type="text/css" href="less/styles.less" />
当使用rel="stylesheet/less"
时,代码将与样式表相同。在Less文件之后,你可以使用以下代码调用less.js
:
<script src="img/less.js" type="text/javascript"></script>
事实上,这就是你开始的全部内容!
为了保持清晰,暂时忽略了html5shiv
(可以在code.google.com/p/html5shiv/
访问)和Modernizr(可以在modernizr.com/
访问)。这些脚本为旧版浏览器如 IE7 和 IE8 添加了对新的 CSS3 和 HTML5 特性的支持和检测。预计你将使用现代浏览器,如 Mozilla Firefox,Google Chrome,或 IE8 之后的任何版本。这些浏览器将完全支持 HTML5、CSS3 和媒体查询,这在阅读本书和做练习时是需要的。
提示
你已经知道在大多数情况下只能在开发和测试中使用less.js
;仍然有一些情况可以在生产中使用less.js
的客户端。为了支持旧版浏览器的less.js
,你可以尝试使用 es5-shim(github.com/es-shims/es5-shim/
)。
现在,在浏览器中打开http://localhost/index.html
。你会看到Less makes me Happy!标题文字以默认的字体和颜色显示。之后,你应该在你喜欢的文本编辑器中打开less/styles.less
。Less和 CSS 的语法在这里没有区别,所以你可以在这个文件中输入以下代码:
h1{color:red;}
接着,重新加载你的浏览器。你应该会看到标题文字变成了红色。
从上面的代码中,h1
是选择器,用于选择你的 HTML 中的H1
属性。color
属性已经在大括号中设置为red
。这些属性将被应用到你的选择器上,就像 CSS 一样。
提示
不需要运行一个 web 服务器。在浏览器中导航到你的硬盘上的index.html
就足够了。不幸的是,这对所有浏览器都不起作用,所以最好使用 Mozilla Firefox。本书中的示例使用的是http://localhost/map/
,但根据你的情况,可以替换为类似于file:///map/
或c:\map\
的内容。
使用自动重新加载的观察功能
less.js
文件有一个watch功能,它会检查你的文件是否有更改,并在发现更改时重新加载你的浏览器视图。使用起来非常简单。执行以下步骤:
-
在你想要打开的 URL 后面添加
#!watch
。 -
在
index.html
后面添加#!watch
,然后重新加载浏览器窗口。 -
所以,在浏览器中打开
http://localhost/index.html#!watch
,开始编辑你的Less文件。你的浏览器将在不需要重新加载的情况下反映你的更改。 -
现在在你的文本编辑器中打开
less/styles.less
。在这个文件中,写入#h1{color:red;}
然后保存文件。 -
现在你应该导航到你的浏览器,应该会看到Less makes me Happy!以红色显示。
-
重新排列你的屏幕,以便在同一个窗口中同时看到文本编辑器和浏览器。
-
此外,如果你在
less/styles.less
中将red
改为blue
,你会发现浏览器跟踪这些更改,并在文件保存后以蓝色显示Less makes me Happy!。
相当酷,不是吗?
提示
本代码示例中使用颜色名称而不是十六进制值。例如,代码使用red
而不是#ff0000
。基本颜色名称由 less.js 转换为它们的十六进制值,并写入 CSS 中。在本书中,始终使用命名颜色。
调试你的代码
由于我们只是人类,我们容易犯错或打字错误。能够看到你的错误并调试你的代码是很重要的。如果你的Less文件包含错误,它根本无法编译。因此,一个小小的打字错误会破坏整个文档的样式。
使用less.js
也很容易进行调试。要使用调试或允许less.js
显示错误,可以将以下代码添加到你的index.html
中:
<link rel="stylesheet/less" type="text/css" href="less/styles.less" />
<script type="text/javascript">less = { env: 'development' };</script>
<script src="img/less.js" type="text/javascript"></script>
如你所见,带有less = { env: 'development' };
的这一行是新的。这一行包含less
作为less.js
使用的 JavaScript 变量。实际上,这是一个全局Less对象,用于将一些设置解析给less.js
。本书中将使用的唯一设置是env: 'development'
。有关更多设置,请查看以下网站:lesscss.org/#client-side-usage-browser-options
。
提示
env: 'development'
还可以防止Less缓存。Less 不会在浏览器缓存中缓存文件。相反,文件会被缓存在浏览器的本地存储中。如果env
设置为production
,这种缓存可能会产生意想不到的结果,因为更改和保存的文件不会被编译。
要尝试这个新设置,再次编辑less/styles.less
并删除一个大括号,以创建h1{color:red
形式的无效语法,然后保存文件。
在你的浏览器中,你将看到一个如下截图的页面:
Less 解析错误示例
除了语法错误之外,还会显示名称错误。在名称错误的情况下,可能会使用未声明的函数或变量。
可以在全局Less对象中设置其他调试设置,也可以将设置附加到 URL 中。例如,你可以通过将以下代码添加到你的 HTML 文件中来指定dumpLineNumbers
设置:
<script type="text/javascript">less = { env: 'development',dumpLineNumbers: "mediaQuery"
};</script>
或者,你可以在 URL 中添加!dumpLineNumbers:mediaQuery
。这个设置可以让其他工具在Less源文件中找到错误的行号。将此选项设置为mediaQuery
可以使 FireBug 或 Chrome 开发工具可用于错误报告。类似地,将其设置为comments
可以使 FireLess 等工具实现相同的功能。例如,使用 FireLess 可以使 Firebug 显示Less原始文件名和Less生成的 CSS 样式的行号。
FireBug、Chrome 开发工具或默认浏览器检查元素功能(可以通过右键单击浏览器屏幕访问)也可以用来查看和评估编译后的 CSS。CSS 显示为内联 CSS,包裹在<style type="text/css" id="less:book-less-styles">
标签中。在以下截图中给出的示例中,你将看到一个 ID,其值为less:book-less-styles
。这个 ID 的值是根据book/less/styles.less
Less文件的路径和名称自动生成的:
Less 生成的 CSS 样式
本书中使用的示例代码
在本书中,你会找到许多代码示例。除非另有说明,这些示例的格式总是先显示Less代码,然后是编译后的 CSS 代码。例如,你可以在Less中编写以下代码行:
mixin() {
color: green;
}
p {
.mixin();
}
此代码将被编译为以下 CSS 语法:
p {
color: green;
}
Less 中的第一个布局
您必须首先在浏览器中打开first.html
(从本书的可下载文件中)然后在文本编辑器中打开less/first.less
。在浏览器中,您将看到一个页眉、正文和页脚的表示。
正如预期的那样,less/first.less
包含了Less代码,将由less.js
编译器转换为有效的 CSS。此文件中的任何错误都将停止编译器并抛出错误。尽管Less代码与普通 CSS 代码显示出一些相似之处,但这里描述的过程与直接编辑 CSS 完全不同。
以下截图显示了在 Web 浏览器中打开时此布局的外观:
Less 中的第一个布局
供应商特定规则
CSS3 引入了供应商特定规则,为您提供了编写一些仅适用于一个浏览器的附加 CSS 的可能性。乍一看,这似乎与您的期望恰恰相反。您想要的是一套标准和实用性,适用于每个浏览器的相同效果和解释的标准 HTML 和 CSS 集。供应商特定规则旨在帮助我们实现这一乌托邦。供应商特定规则还为我们提供了标准属性和替代语法的早期实现。最后但并非最不重要的是,这些规则允许浏览器实现专有的CSS 属性,否则这些属性将没有工作标准(并且可能永远不会成为标准)。
出于这些原因,供应商特定规则在 CSS3 的许多新功能中起着重要作用。例如,动画属性、border-radius和box-shadow都依赖于供应商特定规则。
供应商使用以下前缀:
-
WebKit:
-webkit
-
Firefox:
-moz
-
Opera:
-o
-
Internet Explorer:
-ms
使用 border-radius 构建圆角
边框半径是一个新的 CSS3 属性,它将使许多网页开发人员感到高兴。使用 border-radius,您可以给 HTML 元素设置圆角。在以前的几年中,已经看到了许多使用图像和透明度来实现圆角的实现。然而,这些方法不够灵活,难以维护。
实施需要供应商特定规则,尽管圆角不能用一行代码处理,但它的使用确实使圆角处理变得更加容易。
要给一个元素设置 10 像素半径的圆角,您可以使用带有供应商特定规则的 CSS 代码,如下所示:
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
对于具有不同半径的圆角,使用一个由空格分隔的值列表:10 px 5px 20px 15px;
。半径的顺序是:左上,右上,右下和左下。牢记这些规则,您将看到Less如何保持您的代码整洁。
您可以在浏览器中打开本章下载部分的roundedcorners.html
,并在文本编辑器中打开less/roundedcorners.less
。在浏览器中,您将看到一个具有圆角的页眉、正文和页脚的表示。
less/roundedcorners.less
中页眉的 CSS 如下所示:
#header{
background-color: red;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
您可以看到使用供应商特定规则,圆角已经创建为 10 像素的半径。如果您使用 CSS,您将不得不为页眉、页脚和正文重复供应商特定规则三次。为了更改这些规则或添加供应商,您还必须三次更改相同的代码。起初,您可能会想,“为什么不将选择器分组?”,类似于以下代码的方式:
#header, #content, #footer{
-webkit-border-radius: 10px;
-moz-border-radius: 10;
border-radius: 10px;
}
前面的代码在编写 CSS 或Less代码时在语法上是正确的,但随着代码库的增长,维护起来并不容易。基于属性对选择器进行分组在阅读和维护代码时是没有意义的。这样的结构也会引入许多重复和无结构的相同选择器的用法。
使用Less,你可以高效地解决这些问题。通过创建所谓的混合,你可以解决前面提到的问题。对于边框半径,你可以使用以下代码:
.roundedcornersmixin()
{
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
要使用这个混合,你将使用以下代码将其作为选择器的属性调用:
#header{
background-color: red;
.roundedcornersmixin();
}
这个Less代码的编译 CSS 现在将如下所示:
#header{
background-color: red;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
}
观察less/roundedcorners.less
文件中的原始代码,你会发现前面的代码无法适用于#content
。内容的边框半径是 20 像素,而不是用于页眉和页脚的 10 像素。再次,Less帮助我们高效地解决了这个问题。混合可以像在函数式编程中调用函数一样带参数调用。这意味着结合值和对该值的引用,可以调用混合以设置属性。在这个例子中,这将改变为以下代码:
.roundedcornersmixin(@radius: 10px){
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
在.roundedcornersmixin(@radius: 10px)
混合中,@radius
是我们的参数,其默认值将是10px
。
从这个点开始,你可以在你的代码中使用混合。.roundedcornersmixin(50px);
语句将设置半径为 50 像素的角,而.roundedcornersmixin();
语句将使用默认值 10 像素进行相同的操作。
使用这个,你可以重写less/roundedcorners.less
,使其变成以下代码:
/* mixins */
.roundedcornersmixin(@radius: 10px){
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header{
background-color: red;
.roundedcornersmixin();
}
#content{
background-color: white;
min-height: 300px;
.roundedcornersmixin(20px);
}
#footer{
background-color: navy;
.roundedcornersmixin();
}
提示
下载部分的less/roundedcornersmixins.less
文件包含了这段代码的副本。要使用这个,你还必须在 HTML 文件中将引用更改为<link rel="stylesheet/less" type="text/css" href="less/groundedcornersmixins.less" />
。
请注意,这段代码省略了 HTML 中div
和body
标签的一般样式。这些样式只是用来使演示看起来好看,并没有真正有用地展示Less。
重写Less代码后,重新加载浏览器或观察它是否应用了#!watch
技巧。你会发现输出结果完全相同。这向你展示了如何使用Less以更高效的结构化代码获得相同的结果。
使用 CSS 重置来防止跨浏览器问题
在谈论 CSS 中的层叠时,无疑会提到浏览器默认设置比作者首选样式具有更高的优先级。在编写Less代码时,你将覆盖浏览器的默认样式。换句话说,任何你没有定义的东西都将被分配一个默认样式,这是由浏览器定义的。这种行为在许多跨浏览器问题中起着重要作用。为了防止这些问题,你可以执行CSS 重置。最著名的浏览器重置是 Eric Meyer 的 CSS 重置(可在meyerweb.com/eric/tools/css/reset/
访问)。
CSS 重置会覆盖浏览器的默认样式规则,并为样式创建一个起点。这个起点在所有(或大多数)浏览器上看起来和行为都是一样的。在本书中,使用的是 normalize.css v2。Normalize.css 是 CSS 重置的现代、HTML5-ready 替代方案,可以从necolas.github.io/normalize.css/
下载。它让浏览器更一致地渲染所有元素,并使它们符合现代标准。
要使用 CSS 重置,您可以使用Less的@import
指令。使用@import
,您可以在主Less文件中包含其他Less文件。语法是@import "{filename}";
。默认情况下,指令的搜索路径从主文件的目录开始。虽然可以设置替代搜索路径(通过设置Less环境的路径变量),但本书中不会使用。
本书中的示例Less文件将在代码的前几行包含@import "normalize.less";
。再次强调,您应该特别注意这种解决方案的利润!
如果要更改或更新 CSS 重置,您只需替换一个文件。如果您必须管理或构建多个项目,那么您应该这样做,那么您可以简单地重用完整的重置代码。
创建背景渐变
CSS3 中的一个新功能是在元素的背景颜色中添加渐变的可能性。这可以替代复杂的代码和图像回退。
可以定义不同类型的渐变并使用两种或两种以上颜色。在下图中,您将看到不同颜色的背景渐变:
渐变示例(来自W3schools.com)
在下一个示例中,您可以使用两种颜色的线性渐变。背景渐变使用供应商特定的规则。
您可以利用圆角示例中的示例代码来添加渐变。
第一步是复制或打开less/gradient.less
,并在该文件开头添加一个新的 mixin,如下面的代码所示:
/* Mixin */
.gradient (@start: black, @stop: white,@origin: left) {
background-color: @start;
background-image: -webkit-linear-gradient(@origin, @start, @stop);
background-image: -moz-linear-gradient(@origin, @start, @stop);
background-image: -o-linear-gradient(@origin, @start, @stop);
background-image: -ms-linear-gradient(@origin, @start, @stop);
background-image: linear-gradient(@origin, @start, @stop);
}
这将从左侧(@origin
)到右侧创建渐变,颜色从@start
到@stop
。这个 mixin 有默认值。
IE9(及其早期版本)不支持渐变。可以通过添加background-color: @start;
来添加回退,这将为旧版浏览器创建统一的彩色背景。
在将 mixin 添加到您的代码后,您可以按照以下代码为我们的#header
,#body
和#footer
选择器调用它:
#header{
background-color: red;
.roundedcornersmixin();
.gradient(red,lightred);
}
#content{
background-color: white;
min-height: 300px;
.roundedcornersmixin(20px);
.gradient();
}
#footer{
background-color: navy;
.roundedcornersmixin(20px);
.gradient(navy,lightblue);
}
例如,如果您将Less文件重命名为less/gradient.less
,您还必须更改 HTML 文件中的引用为以下代码:
<link rel="stylesheet/less" type="text/css" href="less/gradient.less" />
如果您现在在浏览器中加载 HTML 文件,您的结果应该如下截图所示:
来自示例代码的标题,内容和页脚中的渐变
CSS 过渡,变换和动画
CSS3 中的另一个新功能是过渡,变换和动画的存在。这些功能可以替代现有或新网页中的动画图像,Flash 动画和 JavaScript。过渡,变换和动画之间的区别并不是微不足道的。动画是由一系列@keyframes
构建的,其中每个@keyframes
处理元素在时间上的不同状态。过渡也描述了元素在开始和结束之间的状态。过渡大多是由 CSS 更改触发的,例如鼠标悬停在元素上。
为了搞清楚事情,重要的是要记住即将按下的按钮。按钮将有两种状态:按下和未按下。没有过渡和动画,我们只能对这些状态进行样式设置。按钮的颜色是白色,当您将鼠标悬停在其上时,其颜色变为红色。(在 CSS 术语中,通过添加:hover
伪类,其状态变为悬停。)在这种情况下,过渡描述了悬停按钮如何变为红色。例如,从白色到红色的颜色变化在两秒内(使其在一半时变为粉红色)表明颜色变化的开始是缓慢的,并随着时间的推移变化更快。在这里使用动画使我们能够描述按钮在开始和结束之间的每个时间间隔的状态。例如,您不必将颜色从白色变为红色,而是变化涵盖了所有状态,从白色、蓝色、绿色,最终到红色。
转换改变元素的位置和外观。它们不依赖于元素的状态。一些可能的转换是缩放、平移(移动)和旋转。
在实践中,我们在大多数情况下都会使用动画、转换和/或过渡的组合。同样,在这种情况下,特定于供应商的规则将发挥重要作用。
现在,我们的示例将添加一个转换。
使用带有圆角和渐变的示例代码,将以下代码复制到less/transition.less
,或者打开less/transition.less
并将以下代码添加到文件的开头:
/* Mixin */
.transition (@prop: all, @time: 1s, @ease: linear) {
-webkit-transition: @prop @time @ease;
-moz-transition: @prop @time @ease;
-o-transition: @prop @time @ease;
-ms-transition: @prop @time @ease;
transition: @prop @time @ease;
}
这个mixin有三个变量;第一个是您将要更改的属性(@prop
)。这可以是height
、background-color
、visibility
等。默认值all
不应在生产代码中使用,因为这会对性能产生负面影响。@time
设置以毫秒或秒为单位的持续时间,并在其后附加s
。最后一个变量@ease
设置transition-timing-function 属性。此函数描述了属性的值,假设其某个百分比已经完成。transition-timing-function 属性描述了过渡的完成度随时间的函数。将其设置为linear
会显示从开始到结束相同速度的效果,而ease
会以较慢的速度开始和结束,并在中间速度更快。预定义的函数有ease
、linear
、ease-in
、ease-out
、ease-in-out
、step-start
和step-end
。
现在,您可以编辑less/transition.less
以使用此mixin。当您悬停在页面上时,您可以设置 body 的背景颜色。请注意,您不需要使用过渡来更改渐变颜色,而是更改background-color
属性。您使用background-color
是因为transition-duration
对渐变没有可见效果。background-color
过渡的代码如下:
#content{
background-color: white;
min-height: 300px;
.roundedcornersmixin(20px);
.transition(background-color,5s);
}
#content:hover{
background-color: red;
}
如果您将Less文件重命名为less/transition.less
,您还必须更改 HTML 文件中的引用为以下代码:
<link rel="stylesheet/less" type="text/css" href="less/transition.less" />
如果您在浏览器中加载 HTML 文件,您将能够在浏览器中看到结果。将鼠标悬停在内容上,您将看到它在 5 秒内从白色变为红色。
最后,可以添加一个旋转标题的第二个示例。在这个示例中,您将使用@keyframes
。使用@keyframes
会比较复杂。因此,在这种情况下,您可以定义一些特定于供应商的规则,并将这些动画属性添加到#header:
如下:
@-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
@-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
#header{
-webkit-animation:spin 4s linear infinite;
-moz-animation:spin 4s linear infinite;
animation:spin 4s linear infinite;
}
您可以将上述代码添加到我们的示例文件中,或者打开less/keyframes.less
。
如果您将Less文件重命名为less/keyframes.less
,您还必须更改 HTML 文件中的引用为以下代码:
<link rel="stylesheet/less" type="text/css" href="less/keyframes.less" />
现在,在浏览器中加载 HTML 文件并观看您的结果。很神奇,不是吗?通过一点创造性思维,您将看到只使用 CSS3 就可以创建旋转的风车或眨眼的猫头鹰的可能性。然而,首先应该更详细地解释这里使用的代码。如前所述,在许多情况下,您会组合动画和转换。在这个例子中,您还可以对转换效果进行动画处理。要理解发生了什么,代码可以分为三个部分。
第一部分是@keyframes
,如下面的代码所示,它描述了 CSS 属性(在这种情况下是转换)的值作为动画完成百分比的函数:
@keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
这些关键帧被赋予了名称引用spin
,这不是一个特殊效果,而只是一个选择的名称。在前面的例子中,描述了 100%完成的状态。在这种状态下,动画元素应该旋转 360 度。
这个旋转是需要我们关注的第二部分。转换描述了元素在空间中的位置或尺寸。在这个例子中,位置由围绕轴的旋转度数描述,100%时为 360 度,50%时为 180 度,25%时为 90 度,依此类推。
第三部分是动画本身,由animation:spin 4s linear infinite;
描述。这是动画属性的子属性的设置的简写表示法。实际上,您可以将其写成以下代码,不包括供应商特定的规则:
animation-name: spin;
animation-duration: 4s;
animation-timing-function:linear;
animation-iteration-count: infinite;
您可以使用这三个部分来构建完整的动画。完成后,您可以扩展它。例如,添加一个额外的关键帧,使时间曲线非线性,如下所示:
@keyframes spin {
50% { transform: rotate(10deg);}
100% {transform: rotate(360deg); }
}
您可以使用background-color
添加第二个属性。不要忘记删除渐变以查看其效果。如下面的代码所示:
@-moz-keyframes spin {
50% { transform: rotate(10deg); background-color:green;}
100% { transform: rotate(360deg); }
}
//.gradient(red,yellow);
您可能已经注意到,在这里并没有完全实现使用Less的利润。由于其可变动画名称,您将不得不重复编写@keyframes
定义。在第四章中,避免重复造轮子,将为您提供一个解决方案。
不幸的是,浏览器对过渡、转换和动画的支持并不理想,并且在各个浏览器之间存在差异。谷歌 Chrome 不支持 CSS 3D 转换,火狐缺乏对 CSS 滤镜的支持,IE9(以及更早的版本)根本不支持它们。为了解决这个问题,许多开发人员寻求 jQuery 来支持他们的动画。jQuery.animate()
函数允许我们使用 JavaScript 更改元素的 CSS 属性。您仍然可以使用Less来设置初始 CSS。一个替代方案是使用animate.css
(您可以在github.com/daneden/animate.css
上访问);这个跨浏览器的 CSS 动画库可以转换为Less代码,并带有 jQuery 回退。
盒模型
box-sizing属性是设置用于计算元素尺寸的 CSS 框模型的属性。实际上,box-sizing 在 CSS 中并不新鲜,但是将代码切换到box-sizing: border-box
将使您的工作变得更加容易。使用border-box
设置时,元素宽度的计算包括边框宽度和填充。因此,更改边框或填充不会破坏您的布局。您可以在下载文件中的boxsizing.html
中找到本节中使用的代码的副本。
如今,大多数网页设计都使用网格。网格将设计分成相等大小的列。这有助于使事情清晰,并构建响应式界面。根据可用的屏幕尺寸(或宽度),您可以以相同列的不同表示形式显示内容和导航。
为了处理不同的屏幕尺寸,网站的某些部分将具有流体宽度或高度。其他元素,如边框、装订线和空白处,应具有固定宽度。流体宽度作为屏幕宽度(或视口)的百分比与固定宽度的组合变得复杂。这种复杂性是因为浏览器对元素的填充和边距使用不同的计算。
为了让您看到这一点,请看以下示例。已创建了一个宽度为 500 像素的容器。在这个容器内,您可以添加两行,并将第二行分成两部分,宽度为 50%(或一半)。
<div class="wrapper" style="width:300px;">
<div style="background-color:red;width;100%;">1</div>
<div style="background-color:green;width:50%;float:left;">2</div>
<div style="background-color:blue;width:50%;float:right;">3</div>
</div>
现在看起来应该像以下的截图:
一个 HTML 包装器
当前的结构直到您添加一些填充时并不会出现问题,这些填充用于在第二行的两列之间构建一些空间或边框(在 HTML 包装器图像中的数字2和3)。填充和边框将破坏我们的布局,如下所示:
<div class="wrapper" style="width:300px;">
<div style="background-color:red;width:100%;">1</div>
<div style="background-color:green;width:50%;float:left;border:5px solid yellow;">2</div>
<div style="background-color:blue;width:50%;border:5px solid yellow;float:right;">3</div>
</div>
<br>
<div class="wrapper" style="width:300px;">
<div style="background-color:red;width;100%;">1</div>
<div style="background-color:green;float:left;width:50%;padding-right:5px;"><div style="background-color:yellow;">2</div></div>
<div style="background-color:blue;width:50%;padding-right:5px;float:right;">3</div>
</div>
最后,这段代码的输出应该看起来像以下的截图:
由于填充和边框而导致的破碎布局
可以执行类似的操作,只是包装器可以包装在额外的包装器内。然后,box-sizing: border-box;
声明可以应用于此。现在,结果应该看起来像以下的截图:
使用 box-sizing: border-box 的布局
如您所见,填充和边框被父元素减去了 50%。这将使计算变得更容易。当然,一旦父容器包装器具有固定宽度,您可以自行进行计算。如果父元素有 300 像素,那么这个 50%将是 150 像素。减去填充和边框的宽度将给出列的固定大小。当父元素具有流体宽度(视口的百分比)时,这种方法不起作用。流体布局随着屏幕宽度的变化而变化。如果您的屏幕变小,那么所有元素也会变小,百分比保持不变。通过为所有可能的屏幕尺寸进行计算,找到允许所有元素对齐的列的真实大小,您将很快发现这是一个漫长、具有挑战性和艰巨的过程。
因此,您应该在本书的所有示例中使用box-sizing: border-box;
。请注意,box-sizing 也必须按照供应商特定的规则进行定义,如下所示:
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
在这个例子中,Less代码将如下所示:
// Box sizing mixin
.box-sizing(@boxmodel) {
-webkit-box-sizing: @boxmodel;
-moz-box-sizing: @boxmodel;
box-sizing: @boxmodel;
}
// Reset the box-sizing
*,
*:before,
*:after {
.box-sizing(border-box);
}
提示
这段代码已经被添加到一个名为boxsizing.less
的单独文件中。从现在开始,我们的Less文件的基础将包含以下代码:
@import: "normalize.less";
@import: "boxsizing.less";
在接下来的章节中,您将学习更多关于如何将您的Less代码组织成文件。
服务器端编译
您已经迈出了Less开发的前几步。如前所述,已经使用了客户端编译。然而,客户端编译与less.js
不应该在真实的网站上使用。这是因为尽管使您的开发变得简单和快速,但为每个页面请求(或实际上,每个用户的初始页面加载)编译您的Less文件实际上会减慢您的网站速度。
对于生产环境,需要编译您的文件并将最终的 CSS 文件提供给浏览器。术语服务器端可能有些误导。在这种情况下,服务器端意味着编译后的 CSS 代码被发送到客户端浏览器,而不是Less代码,它必须在客户端浏览器中由 less.js 编译后显示。您应该预编译您的Less代码。通过将less.js的结果复制粘贴到一个文件中,并在 HTML 文件中包含这个文件作为 CSS 文件,您应该会得到相同的效果,只是您的 CSS 没有被最小化。
Less捆绑了一个命令行编译器。使用以下命令安装和使用它非常简单:
>> npm install -g less
>> lessc styles.less styles.css
Node JavaScript 平台的软件包管理器是 npm。Node 可以在没有浏览器的情况下运行 JavaScript 脚本。Node 和 npm 可在 Windows、Mac OS X 和其他 Unix/*nix 机器上运行。您可以通过访问 nodejs.org/download/
找到适用于您平台的 Node.js 源代码或预构建安装程序。要安装 npm,请阅读 README 文件中的说明,网址为 www.npmjs.org/doc/README.html
。
使用 –help
函数获取以下命令行编译器可用的选项列表:
>> lessc –help
lessc styles.less styles.css
将 styles.less
编译为 styles.css
。在成功编译后,HTML 中指向 styles.css
的链接将如下显示:
<link rel="stylesheet/css" type="text/css" href="styles.css">
压缩和最小化你的 CSS
编译后,CSS 代码是干净且可读的。在将此代码投入生产时,您必须压缩和最小化它以增加加载速度并节省带宽。压缩 和 最小化 CSS 代码的基本步骤是删除注释、空格和其他不必要的代码。结果可能不容易被人类阅读,但这并不重要,因为您可以使用 Less 文件来更新或修改 CSS。
Less 命令行编译器有两个选项用于压缩和最小化。第一个选项(-x 或 –yui-compress
)使用 YUI CSS 压缩器(可以在 yui.github.io/yuicompressor/css.html
访问),第二个选项(--clean-css
)使用 clean-css(可以在 github.com/GoalSmashers/clean-css
访问)。你不能同时使用这两个选项。Clean-css 声称更快,直到最近,你可能不会在压缩中发现太大的差异。通过编译前面示例中的 keyframes.less
,包括 normalize.less
和 boxsizing.less
,结果将为 4377 字节。使用 clean-css,这将减少到 3516 字节,而 YUI 则为 3538 字节。自 Less 版本 1.5.0 起,clean-css 是编译器的默认选项。
图形用户界面
有些人会更喜欢使用 图形用户界面(GUI)而不是命令行编译。有许多 GUI 可用于不同平台,以编辑和编译您的 Less 代码。这里无法提及所有 GUI。相反,以下是一些最显著的正面 GUI 的列表:
-
WinLess 是 Windows 上的 Less GUI。
-
SimpLESS 是一个跨平台的编辑器和编译器,具有许多功能,包括自动向您的代码添加供应商特定规则。
-
CodeKIT 是 Mac(OS X)的 GUI。它可以编译许多语言,包括 Less。它包括优化和浏览器预览。
-
最后提到的是 Crunch! Crunch! 也是一个跨平台的编译器和编辑器。
在选择 Less 开发的 GUI 时,始终检查它使用的 less.js
版本。一些 GUI 是建立在较旧版本的 less.js
上,并不支持最新的功能。
使用 Visual Studio 的 Web 开发人员应该查看 Web Essentials。Web Essentials 扩展了 Visual Studio 的许多新功能,包括 Less。此外,其他 IDE(如 PHPStorm)也内置了 Less 编译器。Eclipse 也有 Less 插件。
总结
在本章中,您刷新并扩展了关于 CSS3 的知识。您学会了如何在客户端上编译您的Less代码。此外,您已经编写了允许您在Less中拥有圆角、渐变和动画的代码,因此您现在可以见证使用Less的利润,并采取关键的初始步骤来组织和规划您的新项目。您了解了为什么要使用 CSS 重置,如何将其编译成Less代码,以及 box-sizing border-box 如何使您的工作更轻松。您还了解了 mixin 是什么,如何使用它,以及如何使用@import
指令导入Less文件。最后但同样重要的是,您已经学会了什么是服务器端编译以及如何使用 GUI。
在下一章中,您将学习如何在Less中使用变量以及如何构建和使用复杂的 mixin。
第二章:使用变量和混合
在本章中,你将更详细地学习Less,了解更多关于变量和混合的知识。Less中的变量可以在代码中的任何地方重复使用。虽然它们通常在一个地方定义,但也可以在代码的其他地方被覆盖。它们用于定义常用值,这些值只能在一个地方编辑一次。基于不要重复自己(DRY)原则,常用值将帮助你构建更易于维护的网站。混合用于设置类的属性。它们将任务捆绑在一行代码中,并且可重复使用。你将学习如何在项目中创建、使用和重复使用它们,并且编写更好的 CSS 而不重复代码。
本章将涵盖以下主题:
-
对你的代码进行注释
-
使用变量
-
值的转义
-
使用混合
注释
注释使你的代码清晰易读。重要的是你能够清楚地理解它们。这就是为什么本章以一些注释的注解和示例开始的原因。
提示
在考虑文件大小、下载时间和性能时,不要吝啬你的注释。在编译和最小化最终的 CSS 代码过程中,注释和其他布局结构将被有效地移除。你可以在需要的地方添加注释以便理解和可读性。
在Less中,你可以像编写 CSS 代码时一样添加注释。注释行放在/* */
之间。Less还允许以//
开头的单行注释。
使用Less,你将会在最终样式表中保留这些注释,除了单行注释,它们不会被打印出来。最小化器会在你的最终编译样式表中移除这些注释。以下代码中可以看到一个例子:
/* comments by Bass
.mixins() { ~"this mixin is commented out"; }
*/
嵌套注释
虽然Less,像 PHP 或 JavaScript 一样,不允许嵌套注释,但以//
开头的单行注释是允许的,并且可以与正常的注释语法混合使用。以下代码片段中展示了这一点:
/*
//commented out
*/
特殊注释
最小化器定义了一种特殊的注释语法,有时允许将重要注释(如许可通知)包含在最小化的输出中。你可以使用这种语法在样式表的顶部写一些版权声明。使用干净的 CSS 和Less的clean-css
命令行编译器的默认最小化器,你应该在/*! !*/
之间放置这个重要的命令,如下例所示:
/*!
very important comment!
!*/
变量
Less中的变量帮助你保持文件的组织和易于维护。它们允许你在一个地方指定广泛使用的值,然后在整个Less代码中重复使用它们。最终样式表的属性可以通过变量设置。所以,想象一下,你不再需要在样式表中搜索特定颜色或值的每个声明了。所有这些是如何工作的呢?变量将以@
开头并具有一个名称。这样的变量示例包括@color
、@size
和@tree
。在写名称时,你可以使用任何字母数字字符、下划线和破折号。这意味着@this-is-variable-name-with-35-chars
是一个有效的变量名。
提示
尽管本书中的变量名使用了字母数字字符、下划线和破折号,但规范允许使用任何字符,有一些例外。这些规范源自 CSS 语法(你可以在www.w3.org/TR/CSS21/grammar.html
查看)。以破折号开头的名称保留给供应商特定规则,而空格已经用于将类名相互分隔。使用转义是可能且允许的,这在(编程)语言中非常罕见。然而,空格的转义是不可能的。NULL
也是不允许的。
不幸的是,在Less中使用@
是有歧义的。正如您在第一章中所见,混合使用的参数也以@
开头。这还不是全部。由于有效的 CSS 代码也是有效的Less代码,因此还会有以@
开头的 CSS 媒体查询声明。上下文将清楚地表明@
用于声明变量。如果上下文不够清晰,本书中将明确提到@
的含义。
您可以为变量赋值,这将被称为声明。值可以包含任何对 CSS 属性有效的值。
您可以使用冒号(:
)为变量赋值。声明以分号(;
)结束。以下示例将说明这一点:
@width: 10px;
@color: blue;
@list: a b c d;
@csv-list: a, b, c, d;
@escaped-value: ~"dark@{color}";
在变量声明之后,您可以在代码中的任何位置使用该变量来引用其值。这使得变量在编程Less代码时非常强大。查看本书的可下载代码中的本章示例代码,以更好地理解。
组织您的文件
正如您所见,您只需声明一次变量,就可以在代码中的任何地方使用它。因此,要对变量进行更改,您也只需更改一次。示例代码在名为less/variables.less
的单独文件中定义了变量。组织文件是一个很好的做法。如果您想要进行更改,现在您知道该去哪里查找了。
回想一下第一章中的CSS 重置和边框盒模型,您的主Less文件现在将如下代码片段所示:
@import "less/normalize.less";
@import "less/boxsizing.less";
@import "less/mixins.less";
@import "less/variables.less";
在这里,@import
语句从文件中导入代码到主Less文件中。文件名用引号括起来,后面跟着一个分号。除了Less文件,您还可以导入普通的 CSS 文件,这些文件不会被处理为Less指令;这将在第五章中详细解释,将 Less 集成到您自己的项目中。
现在您应该在浏览器中打开http://localhost/index.html
。您将看到一个简单的网站布局,其中包含标题、内容块、侧边菜单和三列页脚,如下面的屏幕截图所示。所有布局项都有蓝色的装饰。之后,打开您喜欢的文本编辑器中的less/variables.less
。
使用Less构建的布局
您很好奇,我敢打赌您也打开了其他文件。不要被其中的代码复杂性吓到。这些代码和布局用于展示在单个位置定义的广泛使用的变量的强大功能。这可以通过比几行代码更现实和复杂的示例更好地展示出来。请放心,所有其他代码很快就会向您解释这一点。在您知晓之前,所有这些代码对您来说都将非常熟悉。
首先,在您之前打开的less/variables.less
文件中的@darkcolor: darkgreen;
行中,将darkblue
更改为darkgreen
。之后,观察浏览器中的结果。如果您还没有使用#!watch
功能,请重新加载浏览器。
布局现在将显示为绿色。如果您之前还不确定,现在应该明白了。在实践中,您不会使用一行代码来更改整个网站,但这个示例展示了Less可以如何使您的工作更轻松。
想象一下,您已经完成了您的深绿色网站的工作,并向老板展示了它。"干得好!"他说,但他也告诉您:"我知道我要求绿色,但如果您不介意,我更喜欢红色的网站"。现在,您微笑着,只需在less/variables.less
文件中的@darkcolor: darkgreen;
行中将darkgreen
更改为darkred
。
正如您所见,您的 HTML 是干净和直接的,没有内联 CSS 甚至类名。现在有一个新的问题;您将不得不以聪明和适当的方式命名、声明和保存您的变量。在这样做时,保持一致和清晰是非常重要的。在组织您的变量时,始终遵循相同的策略,使用命名约定和在上下文不够清晰的地方添加注释。请记住,任何人都应该能够在任何时候接管您的工作而无需进一步的说明。为了实现这一点,您将不得不深入了解变量。
命名您的变量
您应该始终给您的变量起有意义和描述性的名称。像@a1
和@a2
这样的变量名称会被编译,但选择得不好。当变量数量增加或者您需要在代码中做一些深层次的更改时,您将不知道或者记得@a2
被用于什么。您将不得不查找它的上下文,以找到它在您的Less文件中的使用,或者更糟糕的是,检查您的 HTML 元素,以找到哪些 CSS 规则被应用在它上面,以便找到Less上下文。在这种不幸的情况下,您将回到原点。
好的命名示例包括@nav-tabs-active-link-hover-border-color
和@dark-color
。这些变量是有意义和描述性的,因为它们的名称试图描述它们的功能或用途,而不是它们的值。这种命名过程也被称为语义命名。因此,在这种情况下,@dark-color
比@red
更好,而在某些情况下,您可以更具体地使用@brand-color
。这可以描述网站的一些品牌颜色,就像前面的例子一样。如果品牌颜色从深红色变为浅绿色,那么@brand-color: lightgreen;
仍然是有意义的。然而,@dark-color: lightgreen;
或@red: lightgreen;
就不太合适了。
如您所见,变量名中使用连字符来分隔单词。这些名称被称为连字符名称。您应该使用小写字母。使用连字符名称并没有严格的规则;所谓的驼峰命名法也被使用,并且被许多程序员认为是可接受的替代方式。在驼峰命名法中,您将使用类似@navTabsActiveLinkHoverBorderColor
和@darkColor
的命名。无论是连字符名称还是驼峰名称都可以提高可读性。
提示
在编写 CSS 和 HTML 代码时,您会使用连字符连接的双词术语和小写的类名、ID 和字体名称,以及其他内容。这些规则并不总是严格的,也不是按照惯例遵循的。本书在编写Less代码时遵循这种约定,因此使用了连字符名称。
无论您喜欢驼峰命名法还是连字符名称都不是很重要。当您选择了驼峰命名法或连字符名称之后,保持一致并在整个Less文件中使用相同的命名方式是很重要的。
提示
当进行计算时,连字符名称可能会引起一些麻烦。您将需要一些额外的空格来解决这个问题。当您声明@value
减一时,@value-1
将被读作一个单独的变量,而不是@value -1
。
使用变量
如果您的项目不断增长,将为每个 CSS 属性值添加一个变量将变得不可能,因此您将不得不选择哪些值应该是变量,哪些不应该是。在这个过程中并没有严格的规则。在接下来的章节中,您将找到一些明确的指导来做出这些选择。
首先,您应该尝试找到在您的代码中多次使用的属性值。在创建变量时,重复使用是合适的。示例代码中的@dark-color
变量就是这种属性值的一个很好的例子。
其次,您可以创建用于自定义设置的属性的变量。示例代码中的@basic-width
变量就是这种属性的一个例子。
最后,你应该考虑为可重用的组件创建变量。看看我们的示例,你可以在其他项目中重用页眉。为了实现这一点,你应该创建一个新的less/header.less
文件,并使用以下代码将其导入到你的主文件中:
@import "less/header.less";
组织变量
为了使组件可重用,你可以为每个组件或函数创建Less文件,并安排变量以适应这些文件。为了演示这一点,将示例代码拆分为less/header.less
,less/content.less
和less/footer.less
。
less/header.less
文件现在将包含以下代码:
header
{
background-color: @header-dark-color;
min-height: @header-height;
padding: 10px;
.center-content;
.border-radius(15px);
.box-shadow(0 0 10px, 70%);
h1 {color: @header-light-color;}
}
注意,@dark-color
已被重命名为@header-dark-color
。在浏览器中打开http://localhost/project.html
,并在文本编辑器中打开less/project.less
文件,以查看所有更改及其影响。
现在,在你的less/project.less
文件中使用@import "header.less";
包含less/header.less
文件,并在less/variablesproject.less
文件中创建一个页眉部分,如下所示:
/* header */
@header-dark-color: @dark-color;
@header-light-color: @light-color;
@header-height: 75px;
@header-dark-color: @dark-color;
语句将@dark-color;
的值赋给@header-dark-color
。之后,你将对less/content.less
和less/footer.less
做同样的操作。正如你所看到的,http://localhost/project.html
在你的更改后仍然看起来一样。
现在,在你的文本编辑器中打开less/variablesproject.less
文件,并将页脚部分更改为以下代码:
/* footer */
@footer-dark-color: darkgreen;
@footer-light-color: lightgreen;
@footer-height: 100px;
@footer-gutter: 10px;
在你的浏览器中,你现在将看到带有绿色页脚的布局。
最后声明获胜
在第一章中,你已经了解了CSS 层叠,最后一条规则指出,如果其他规则的输出相等,最后声明的值将获胜。Less使用相同的策略,变量的最后声明将在所有前面的代码中使用。在下面的代码中,你将看到属性值设置为2
,符合最后声明获胜的规则:
@value: 1;
.class{
property: @value;
}
@value: 2;
Compiles into:
.class{
property: 2;
}
事实上,Less首先读取你的所有代码。当变量的值被使用时,实际上只使用最后分配或最后读取的值。最后声明获胜的事实只会影响在相同作用域中定义的声明。
在大多数编程语言中,作用域由编译器可以独立运行的代码部分定义。函数和类可以有自己的作用域。在Less中,mixin 有自己的作用域。混合将在本章后面更详细地讨论。
以下代码向你展示了,根据在 mixin 作用域内声明的值,属性值设置为3
:
@value: 1;
.mixin(){
@value: 3;
property: @value;
}
.class{
.mixin;
}
@value: 2;Compiles to:
.class{
property: 3;
}
上述代码意味着你不能在编译过程中更改变量。这使得这些变量成为理论上的常量。将这与你代码中数学值 pi 的定义进行比较,它始终是相同的。你只需定义PI
一次,PI = 3.14
将在你的代码中,并且在运行代码时保持不变。因此,变量应该只声明一次。
变量的重声明和最后声明获胜的规则将在许多Less项目和代码的定制中使用。
为了演示重声明,创建一个新的less/customized.less
文件,并将以下代码写入其中:
@import "styles.less";
@dark-color: black;
@basic-width: 940px;
在customized.html
文件中引用customized.less
文件,如下所示:
<link rel="stylesheet/less" type="text/css" href="less/customized.less" />
现在在浏览器中加载customized.html
文件。正如你所看到的,你只用了三行代码就创建了一个定制版本的布局!
变量声明不是静态的
尽管变量的行为类似于常量,但它们的声明不一定是不可改变的或静态的。首先,你可以将一个变量的值赋给另一个变量,如下面的代码所示:
@var2 : 1;
@var1 : @var2;
@var2 : 3;
@var1
的值现在是3
而不是1
。请理解,你不需要创建某种引用,因为最后声明获胜的规则在这里适用。@var1
变量将获得最后声明的@var2
变量的值。
在示例代码中,您还会发现@light-color: lighten(@dark-color,40%);
的声明。lighten()
函数是Less的所谓内置函数。第三章,嵌套规则、操作和内置函数,将介绍内置函数。使用lighten()
函数将@light-color
设置为基于@dark-color
计算的颜色值。您还应该注意@dark-color
的最后一个声明,因为这用于颜色计算。
动态声明变量值可以提供灵活性,但请记住,您只能在声明后声明一次值,并且不能在声明后更改它。
懒加载
在从变量切换到混合器之前,您应该首先了解懒加载。在计算机编程中,这意味着推迟对象的初始化,直到需要它为止。懒加载是急切加载的相反。对于Less来说,这意味着变量是懒加载的,不必在实际使用之前声明。
试图理解理论方面固然很好,但现在是时候通过以下示例了解它们在实践中是如何工作的:
.class {
property: @var;
}
@var: 2;
上述代码编译为以下代码:
.class {
property: 2;
}
转义值
Less是 CSS 的扩展。这意味着Less在遇到无效的 CSS 或在编译期间评估有效的 CSS 时会出错。一些浏览器使用无效的 CSS 定义属性。众所周知的例子包括property: ms:somefunction()
之类的东西。其中一些规则可以被供应商特定的规则替换。重要的是要注意,Less中无效的属性值不会被编译。
CSS3 中的新函数calc()
是 CSS 中进行简单数学运算的一种本地 CSS 方式,可以替代任意长度的值。
在这两种情况下,Less在编译或导入时都无法给我们正确的值。
@aside-width: 80px;
.content {
width: calc(100% - @aside-width)
}
上述代码编译为以下代码:
.content {
width: calc(20%);
}
从上述代码中,@aside-width: 80px;
是声明一个名为aside-width
的变量。这个变量得到了 80 像素的值。关于变量的更多信息将在接下来的章节中介绍。然而,更重要的是,现在上述结果是错误的(或者至少不如预期),因为calc()
函数应该在渲染时进行评估。在渲染时,calc()
函数有能力混合单位,比如百分比和像素。在上述代码中,.content
被分配了100%
的可用空间的宽度(换句话说,所有可用空间)减去80px
(像素)。
转义这些值将防止这些问题。在Less中,您可以通过将值放在用波浪号(~)前面的引号(
"")之间来转义值。因此,在这个例子中,您应该写
width: ~"calc(100% - @{aside-width})"`。
请注意,大括号放在aside-width
的变量名中,这被称为字符串插值。在转义的值中,任何在引号之间的内容都会被原样使用,几乎没有变化。唯一的例外是插值变量。
字符串是字符序列。在Less和 CSS 中,引号之间的值是字符串。没有转义,Less会将其字符串编译成 CSS 字符串。
例如,width: "calc(100 – 80px)"
在 CSS 中没有意义,width: calc(100% - @aside-width)
也是如此,因为@aside-width
没有意义。
因此,通过转义和字符串插值,您可以从以下代码片段开始:
@aside-width: 80px;
.content{
width: ~"calc(100% - @{aside-width});"
}
上述代码将编译为以下代码:
.content {
width: calc(100% - 80px);
}
提示
在使用calc()
函数的特定情况下,Less编译器具有strict-math选项(自 1.4 版本以来使用)。这与命令行中的–strict-math=on
或在 JavaScript 中使用strictMath: true
一起使用。当打开 strict-math 选项时,calc(100% - @aside-width);
的宽度将被编译为width: calc(100% - 80px);
。请注意,在 1.6、1.7 和 2.0 版本的开发过程中,对这个strict-math选项进行了许多更改。
混合
混合在Less中扮演着重要角色。在第一章中讨论圆角示例时,您已经看到了混合。混合从面向对象编程中获取其命名。它们看起来像函数式编程中的函数,但实际上像 C 宏一样起作用。Less中的混合允许您通过简单地将类名包含为其属性之一,将一个类的所有属性嵌入到另一个类中,如下面的代码所示:
.mixin(){
color: red;
width: 300px;
padding: 0 5px 10px 5px;
}
p{
.mixin();
}
前面的代码将被编译为以下代码:
p{
color: red;
width: 300px;
padding: 0 5px 10px 5px;
}
在网站上使用的最终 CSS 代码中,每个<p>
段落标记都将使用mixin()
函数中定义的属性进行样式设置。优点是您可以在不同的类上应用相同的混合。正如在圆角示例中所看到的,您只需要声明一次属性。
尝试打开本章可下载文件中的less/mixins.less
。在本书的示例中,所有混合都保存在一个文件中。在这个文件中,您可以根据它们的功能来安排您的混合。将它们分组到一个文件中可以防止我们在删除或替换其他功能Less文件时破坏代码。您的项目中包含了sidebar.less
和content.less
的示例,这两个文件都使用了 border-radius 混合。如果我们现在替换sidebar.less
,您不会破坏content.less
。当然,您也不希望在代码中两次使用相同类型的混合。
less/boxsizing.less
中的 box-sizing 混合将被视为一个特例。box-sizing 混合影响所有元素,您希望能够完全替换 box-sizing 模型。
less/mixins.less
文件包含四个混合,将在以下部分中讨论。box-shadow 和 clearfix 混合也具有嵌套等复杂结构,但这些混合将在下一章中进一步详细解释。
基本混合
您已经看到了圆角混合。基本混合看起来像 CSS 中的类定义。混合在类内部调用并赋予这些类其属性。
在less/mixins.less
文件中的示例代码中,您将找到.center-content
混合,它将margin
属性的值设置为0 auto
。这个混合用于居中对齐标题、内容包装器和页脚。
提示
请注意,这些居中内容混合并不是唯一的解决方案。一个通用的包装器可以一次性居中对齐标题、内容包装器和页脚,也适用于这个示例布局。这个混合的名称也可以讨论。当您决定不再居中内容时,这个混合的名称将不再有任何意义。
删除margin: 0 auto;
属性,实际上是从混合中使内容居中。然后应该重新加载浏览器中的index.html
以查看效果。
参数化混合
如前所述,混合在函数式编程中扮演函数的角色,因此,作为函数,它们可以被参数化。参数是与混合结合使用的值,参数的名称在混合内部用作其值的引用。以下代码向您展示了一个使用参数化混合的示例:
.mixin(@parameter){
property: @parameter;
}
.class1 {.mixin(10);}
.class2 {.mixin(20);}
前面的代码被编译为以下代码:
.class1 {
property: 10;
}
.class2 {
property: 20;
}
前面的示例显示了参数化如何使混合非常强大。它们可以根据输入值设置属性。
默认值
参数具有可选的默认值,可以使用.mixins(@parameter:defaultvalue);
来定义。要了解这是如何工作的,您应该考虑less/mixins.less
文件中的border-radius
混合,如下面的代码所示:
.border-radius(@radius: 10px)
{
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
请注意,这里的默认值是10px
。
命名和调用
在本书中,混合物具有有意义和描述性的名称,就像变量名称一样,这些名称是用连字符分隔的。为混合物使用有意义和描述性的名称使您的代码对其他人更易读,更易于维护。参数和变量都以@
符号开头。上下文应该清楚地表明正在讨论的是变量还是混合参数。
为了更好地理解,请考虑以下代码:
@defaulvalue-parameter1 :10;
.mixin(@parameter1: @defaulvalue-parameter1)
{
property: @parameter1;
}
.class {
.mixin
}
这段代码可以编译成以下代码:
.class{
property: 10;
}
请注意,这里的@defaulvalue-parameter1
是一个变量。
以下代码还说明了混合的范围:
@defaulvalue-parameter1 :10;
.mixin(@parameter1: @defaulvalue-parameter1){
property: @parameter1;
}
.class {
.mixin
}
@parameter1 : 20;
这段代码可以编译成以下代码:
.class{
property: 10;
}
在这里,@parameter1
的最后一个声明在混合的范围之外,所以属性仍然设置为10
。
多个参数
混合物的多个参数可以用逗号或分号分隔。函数式程序员通常使用逗号作为分隔符。在Less中,分号更受青睐。逗号在这里实际上有一个模棱两可的作用,因为它们不仅用于分隔参数,还用于分隔csv 列表中的列表项。
.mixin(a,b,c,d)
调用使用四个参数调用混合物,同样.mixin(a;b;c;d)
调用也是一样。现在,考虑一下您使用.mixin(a,b,c;d)
调用混合物的情况。这里只使用了两个参数,第一个参数是一个包含三个项目的列表。如果参数列表中至少有一个分号,则唯一的分隔符将是分号。下面的代码向您展示了在参数列表中添加额外分号的效果:
.mixin(@list){
property: @list;
}
.class{ mixin(a,b,c,d;);}//see the extra semi-colon!
这段代码可以编译成以下代码:
.class{
property: a, b, c, d;
}
没有这个额外的分号,你调用一个带有四个参数的混合物。在这种情况下,编译器会抛出一个错误:RuntimeError: No matching definition was found for .mixin(a, b, c, d)。实际上,你需要的是一个包含.mixin(@a,@b,@c,@d)
的混合物。
在前面的例子中,已经明确表示Less中允许具有相同名称的混合物。当找到具有相同名称的不同混合物时,编译器仅使用具有正确数量参数的混合物,或者在找不到匹配的混合物时抛出错误。这种形式的参数匹配可以与各种编程语言中的方法重载进行比较。
如果一个混合调用匹配多个混合,如下面的代码所示,那么编译器将使用所有匹配的混合:
.mixin(@a){
property-a: @a;
}
.mixin(@b){
property-b: @b;
}
class{
.mixin(value);
}
这段代码编译成以下代码:
class {
property-a: value;
property-b: value;
}
更复杂的线性渐变背景混合
现在您已经有足够的理论知识来构建更复杂的混合物。在这个例子中,您将为我们布局的页脚列添加三种颜色的背景渐变指令。
最终结果应该如下截图所示:
使用Less构建的线性渐变背景
这些渐变背景被选择是因为它们的复杂性和随时间变化的充分记录。最终结果将是一个复杂的混合,肯定不完美,但可以显著改善结果。您可以肯定,您将不得不不时更改您的渐变混合,因为旧浏览器的支持下降,新浏览器,规范的变化和新的见解。请参考developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_gradients
获取更多示例。
你无法阻止这些必要的更改,但你可以最小化花在保持你的混合器最新的时间。Less保证了你所有的背景渐变都是基于同一个混合器定义在一个地方。
在基本层面上,CSS 中的背景渐变被定义为图像。因此,它们被应用在background-image 属性上。
在本书中,渐变是在background-image
属性上设置的。其他示例(其他地方和其他书中)可能会在background
属性上设置它们。它们的定义没有区别。CSS 为背景定义了不同的属性,如background-image
、background-color
、background-size
和background-position
。background
属性是它们所有的缩写。当你将background
属性的第一个值定义为图像,或者在这种情况下是渐变时,所有其他属性值都设置为它们的默认值。
你开始你的混合器,列出以下要求:
-
你需要一个参数来设置你的渐变的方向,你将使用角度。
-
你的渐变将由三种颜色组成
-
之后,你定义一个浏览器列表和你需要支持的浏览器版本
现在,你可以定义你的混合器的前几行如下:
.backgroundgradient(@deg: 0deg; @start-color: green; @between-color:yellow; @end-color: red; @between:50%)
{
background-image: linear-gradient(@deg, @start-color, @between-color @between, @end-color);
}
展示 45 度渐变线如何工作的一种方法。这是从dev.w3.org/csswg/css-images-3/
中获取的,版权所有 2013 W3C,2013 年 9 月 11 日
背景混合器有五个参数,如下:
-
第一个参数描述了以度为单位的方向。度数的数量给出了垂直和渐变方向之间的角度。方向的描述从底部开始。在底部,角度为 0 度,描述了从底部到顶部的渐变。然后角度顺时针转到 90 度点,描述了从左到右的渐变,依此类推。
-
接下来的三个参数是你的渐变的三种颜色,这是为它设置的默认值。
-
第五个也是最后一个参数定义了中间颜色的真实值。这里的百分比是应用渐变的元素宽度的百分比。第一个和最后一个颜色默认为 0 和 100。
现代浏览器,如 IE 11 版本,Firefox 16+版本,Opera 12.10+版本,Safari 7+版本和 Chrome 26+版本,支持这些背景图像属性。对于较旧的浏览器,必须添加特定于供应商的规则。这里的第一个问题是特定于供应商的规则使用了不同的方式来定义角度。为了补偿这一点,你可以使用以下代码对 90 度进行校正:
.backgroundgradient(@deg: 0deg; @start-color: green; @between-color:yellow; @end-color: red; @between:50%){
@old-angel: @deg – 90deg;
-ms-background-image: linear-gradient(@old-angel , @start-color, @between-color @between, @end-color);
background-image: linear-gradient(@deg, @start-color, @between-color @between, @end-color);
}
-ms background-image
属性被 IE10 使用,因为较旧版本的 IE 无法支持背景图像。或者,你可以添加一个滤镜来支持双色渐变。在使用这个滤镜时,不支持与回退图像的组合,所以你必须选择基于 webkit 的浏览器,比如 Chrome 和 Safari,它们使用-webkit-linear-gradient
;然而,如果你必须支持这些浏览器的旧版本,你将不得不使用-webkit-gradient
。请注意,-webkit-gradient
有一个不寻常的语法。例如,你的最终混合器可能看起来像以下代码:
.backgroundgradient(@degrees: 0deg; @start-color: green; @between-color:yellow; @end-color: red; @between:50%){
background-image: -moz-linear-gradient(@degrees, @start-color 0%, @between-color @between, @end-color 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, @start-color), color-stop(@between,@between-color), color-stop(100%,@end-color));
background-image : -webkit-linear-gradient(@degrees, @start-color 0%, @between-color @between, @end-color 100%);
background-image: -o-linear-gradient(@degrees, @start-color 0%, @between-color @between, @end-color 100%);
background-image: -ms-linear-gradient(@degrees, @start-color 0%, @between-color @between, @end-color 100%);
background-image: linear-gradient((@degrees - 90deg), @start-color 0%, @between-color @between, @end-color 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='@startcolor', endColorstr='@endcolor',GradientType=0 );
}
前面的代码表明,即使使用Less,我们的代码仍然可能很复杂。除非这种复杂性可以支持不同的浏览器,你可以看到使用Less的优势,它允许你只在一个地方处理这段代码。
前面示例中的代码可以在directivebackgrounds.html
和less/directivebackgrounds.less
中找到。如果你想知道在经历了这一切之后为什么还要使用 CSS 背景渐变,那么请看一下lea.verou.me/css3patterns/
,看看有什么可能性。
特殊变量-@arguments 和@rest
Less定义了两个特殊变量。@arguments
变量是第一个,包含传递的所有参数的列表。@arguments
变量存在于 mixin 内部。在Less中,列表是用空格分隔的,所以你可以用@arguments
来设置可以由值列表设置的属性。像margin
和padding
这样的属性在它们的简写表示法中接受列表,如下面的代码所示:
.setmargin(@top:10px; @right:10px; @bottom: 10px; @left 10px;){
margin: @arguments;
}
p{
.setmargin();
}
这段代码可以编译成以下代码:
p {
margin: 10px 10px 10px 10px;
}
第二个特殊变量是@rest
。@rest...
将调用者的前面参数后的所有奇数参数绑定到一个列表中。通过这样做,@rest...
可以让 mixin 使用无限的参数列表。请注意,这三个结束点是语法的一部分。下面的代码显示了@rest...
将@a
变量后的所有奇数参数绑定到property2
属性:
.mixin(@a,@rest...) {
property1: @a;
property 2: @rest;
}
element {
.mixin(1;2;3;4);
}
这段代码将被编译成以下代码:
element {
property1: 1;
property2: 2 3 4;
}
你还应该考虑使用@rest...
作为 csv 列表。为此,你可以将less/mixinswithdirectivebackgrounds.less
中的.backgroundgradient
mixin 重写为以下代码:
.backgroundgradient(@deg: 0; @colors...) {
background-repeat: repeat-x;
background-image: -webkit-linear-gradient(@deg, @colors);
background-image: -moz-linear-gradient(@deg, @colors);
background-image: linear-gradient(@deg, @colors);
}
现在,这个 mixin 将接受一个无限的颜色列表,你可以用以下代码来使用它:
div#content { .backgroundgradient(0;blue,white,black,pink,purple,yellow,green,orange);
}
以下图显示了使用这个背景 mixin 的代码的结果:
返回值
如果你习惯于函数式编程,甚至了解数学函数,你会期望 mixin 有一个返回值。这只是意味着把x
放进去,得到y
。Mixin 没有返回值,但你可以使用它们的作用域模仿这种行为。在 mixin 中定义的变量将被复制到调用者的作用域,除非变量已经在调用者的作用域中定义。下面的例子将说明这一点:
.returnmixin(){
@par1: 5;
@par2: 10;
}
.mixin(){
@par2: 5; // protected for overwriting
property1: @par1; // copied from returnmixin's scope
property2: @par2;
.returnmixin();
}
element{
.mixin();
}
这段代码将被编译成以下代码:
element {
property1: 5;
property2: 5;
}
如果你看前面的例子,你可以将property2: @par2;
与一个函数比较,比如property2 = returnmixin();
。
提示
使用作用域来模仿返回值也可以应用在 mixin 上。在另一个 mixin 中定义的 mixin 可以在调用者的作用域中使用。然而,这些不像变量那样受作用域的保护!这个过程被称为解锁。目前,解锁不在本书的范围之内。
改变 mixin 的行为
为了使 mixin 更加灵活,影响它们的输出基于它们的输入参数将是有用的。Less提供了不同的机制来实现这一点。
开关
假设你有一个 mixin,color();
应该根据上下文将颜色属性设置为白色或黑色。使用@context: light;
声明设置上下文,并声明两个具有相同名称的 mixin,如下面的代码所示:
.color(light)
{
color: white;
}
.color(dark)
{
color: black;
}
现在你可以在你的代码中使用.color(@context);
mixin,它将把你的类的color
属性设置为白色或黑色,取决于声明给@context
的值。现在这可能看起来没什么用,但在你不断发展的项目中会很有用。看一下 Bootflat 项目www.flathemes.com/
。这个项目提供了 Twitter 的 Bootstrap 的颜色变体。Twitter 的 Bootstrap是基于Less的CSS 框架。Bootflat 定义了两种样式,其中一种样式基于改进的 Bootstrap 3.0 样式,另一种样式是一个去掉了圆角的 Square UI 样式。这个项目使用一个开关来编译两种不同的样式。
参数匹配
Less允许具有相同名称的不同 mixin。如果有这样的 mixin,那么与调用者的参数列表匹配的每个 mixin 都将被使用。参考以下颜色 mixin:
.color(@color)
{
color: @color;
}
.color(@color1,@color2)
{
color: gray;
}
在前面的代码中定义的颜色混合,.color(white)
编译成color: white;
,而.color(white,black)
将给出color: gray;
。请注意,.color(white);
调用不匹配.color(@color1,@color2)
混合,因为它需要两个参数,所以编译器没有使用它。
守卫混合
Less中也可以有相同名称和相同参数数量的混合。在这种情况下,所有匹配项都会被使用,如下例所示:
.color(@color){
color: @color;
display: block;
}
.color(@color) {
color: blue;
}
.class{
.color(white)
}
这段代码将被编译成以下代码:
.class{
color: #ffffff;
display: block;
color: blue;
}
提示
还要注意Less将命名颜色white
转换为#ffffff;
。
在这种情况下,两个color
声明是没有意义的。Less不会过滤掉重复声明,除非它们以完全相同的方式使用。
守卫可以用来防止重复定义的混合带来的麻烦。守卫是在关键字后面跟着一个条件定义的。当条件为真时,使用混合。以下示例清楚地说明了这一点:
mixin(@a) when (@<1){
color: white;
}
mixin(@a) when (@>=1){
color: black;
}
.class {
mixin(0);
}
.class2 {
mixin(1);
}
这段代码将被编译成以下代码:
.class {
color: white;
}
.class2 {
color: black;
}
守卫可以像编程中的if语句一样使用。比较运算符如>
、>=
、=
, =<
和<
可以使用。一个或多个条件可以用逗号分隔的方式组合在一起,如果其中一个为真,则为真。
关键字and
可以用来在两个条件都为真时评估为真,例如,when @a>1
and
@<5
。最后,条件可以用关键字not
否定,例如,when (not a = red)
。
提示
如果您之前使用过 CSS 媒体查询,那么您一定会意识到守卫的作用方式与 CSS 中的媒体查询相同。
最后,守卫条件也可以包含内置函数。这些函数将在下一章中讨论,并在它们不是参数列表的一部分时作用于所有定义的变量。守卫条件的内置函数可以在以下代码中看到:
@style: light;
.mixin(@color) when is_color(@color) and (@style = light) {
color: pink;
}
.class() {
mixin(red);
}
这段代码可以编译成以下代码:
.class {
color: pink;
}
在@style: dark;
或mixin(1);
的情况下,没有匹配项。
使用守卫和参数匹配来构建循环
当Less找不到匹配的混合时,它会继续到下一个评估并不会中断。这可以与守卫和参数匹配结合使用来构建循环。举个例子,想象有 10 个类,每个类都包含一个编号的背景图片。.class1
类的background-image
属性值设置为background-1.png
,.class2
类将background-image
属性的值设置为background-2.png
,依此类推,如下代码所示:
.setbackground(@number) when (@number>0){
.setbackground( @number - 1 );
.class@{number} { background-image: ~"url(backgroundimage-@{number}.png)"; }
}
.setbackground(10);
这段代码可以编译成以下代码:
.class1 {
background-image: url(backgroundimage-1.png);
}
.class2 {
background-image: url(backgroundimage-2.png);
}
...
.class10 {
background-image: url(backgroundimage-10.png);
}
当您第一次看到最后一个混合时,它可能看起来很复杂,但如果您尝试自己评估混合,您会发现它实际上包含了您之前学到的很多东西。
在前面的代码中,setbackground
混合调用了自身。程序员会称这为递归。这里发生了什么?
.setbackground(10);
调用匹配了.setbackground(@number)
混合,当@number>0
时,请利用这一点。.setbackground( @number - 1 );
的第一次评估也匹配了混合。这意味着编译器再次运行混合。这将重复直到@number -1
为0
;再也找不到匹配项。现在编译器将读取停止位置之后的内容,以使用混合。
最后一次停在@number = 1
,所以它会评估@numer = 1
条件下的.class@{number} { background-image: ~"url(backgroundimage-@{number}.png)"; }
声明。当它之前停止时,是在@number = 2
。所以,它会评估@numer = 2
条件下的.class@{number} { background-image: ~"url(backgroundimage-@{number}.png)"; }
声明,依此类推。当我们回到@numer = 10
时,所有代码都已经编译完成。所以,编译器停止了。
除了保护和参数匹配,上面的示例还包含了.class@{number}
类声明中的插值属性,以及在声明~"url(backgroundimage-@{number}.png)";
时进行转义的字符串插值示例。混合还显示了在执行计算时需要使用额外的空格。因此,@number - 1
不会被计算为一个@number-1
变量。
!important
关键字
本章以关于Less中!important
关键字的说明结束。在声明中使用!important
会使该声明在两个或更多选择器匹配同一元素时具有最高的优先级。!important
关键字会覆盖内联样式,如下面的代码所示:
<style>
p{color:green !important;}
</style>
<p style="color:red;">green</p>
上述代码将显示为绿色文本。正如示例所示,您可以使用!important
来更改内联 CSS 源的样式,这是您无法编辑的。它还可以用于确保样式始终被应用。然而,请谨慎使用!important
,因为覆盖!important
的唯一方法是使用另一个!important
。在Less中不正确或不必要地使用!important
将使您的代码混乱且难以维护。
在Less中,您不仅可以在属性中使用!important
,还可以在混合中使用它。当为某个混合设置!important
时,该混合的所有属性都将使用!important
关键字声明。这可以在以下代码中看到:
.mixin(){property1: 1;property2: 2;
}
.class{
.mixin() !important;
}
此代码将编译为以下代码:
.class{
property1: 1 !important;
property2: 2 !important;
}
总结
在本章中,您学习了关于变量和混合的知识。您已经看到了在一个地方定义变量和混合将减少您的代码并使其易于维护。
在下一章中,您将学习更多关于混合和如何嵌套和扩展它们的知识。您还将了解Less的内置函数。内置函数可用于操纵混合和代码其他部分中的值。
第三章:嵌套规则,操作和内置函数
在本章中,你将学习Less如何帮助你更直观地组织你的 CSS 选择器,使继承清晰,并使你的样式表更短。你还将学习操作和内置函数。操作让你能够添加、减去、除以和乘以属性值和颜色。它们还让你有能力在属性之间创建复杂的关系。你还将学习如何在你的Less代码中使用内置函数来设置变量或保护。
本章将涵盖以下主题:
-
嵌套 CSS 规则
-
使用操作
-
在你的代码中使用内置函数
-
使用混合中的内置函数
导航结构
通过本章的示例,你将逐步扩展第二章中的布局,使用变量和混合,并使用导航结构。你将通过使用Less来为 HTML 列表设置样式来构建这个导航结构。这个导航结构形成了布局侧边栏中的菜单。
最终结果将如下截图所示:
使用Less构建的最终导航菜单
嵌套规则
你将使用第二章中的布局示例,使用变量和混合,来更详细地研究规则的嵌套。
为了做到这一点,你首先必须在浏览器中打开http://localhost/index.html
,然后在你的文本编辑器中打开less/sidebar.less
。
锚点被添加到菜单项中。这意味着侧边栏的 HTML 代码现在看起来像以下代码:
<aside id="sidemenu">
<h2>Side menu</h2>
<ul>
<li><a href="page1.html">item 1</a></li>
<li><a href="page2.html">item 1</a></li>
</ul>
</aside>
你需要为 CSS 中的不同元素设置每个规则的选择器,如下面的代码所示:
#sidebar h2{
color: black;
font-size: 16px;
}
#sidebar ul li a{
text-decoration: none;
color: green;
}
正如你所看到的,ul
(包括li
元素和a
锚点)元素和h2
元素都是具有#sidemenu
ID 的aside
元素的子元素。CSS 并没有反映这种关系,因为它目前的格式如前面的代码所示。Less将帮助你在你的代码中反映这种关系。在Less中,你可以写下以下代码:
#sidebar{
h2{
color: black;
font-size: 16px;
}
ul{
li{
a{
text-decoration: none;
color: green;
}
}
}
}
前面的代码将直接编译成以下 CSS 语法:
#sidebar h2 {
color: black;
font-size: 16px;
}
#sidebar ul li a {
text-decoration: none;
color: green;
}
你编译后的Less代码的结果 CSS 与你原始的 CSS 代码完全相同。在Less中,你只需一次引用#sidemenu
ID,由于h2
和ul
嵌套在#sidemenu
中,你的代码结构是直观的,并且反映了你的 HTML 代码的DOM 结构。
为了保持你的代码整洁,一个新的less/sidebar.less
文件已经被创建。它包含了前面的Less代码。当然,这个文件也应该被导入到less/styles.less
中,使用以下代码行:
@import "sidebar.less";
请注意,侧边栏被包裹在语义化的 HTML5 aside
元素中,而不是div
元素中。虽然这更语义化,但你会发现在你做出这些改变后,你的侧边栏已经浮动到了左侧。要解决这个问题,打开你的文本编辑器中的less/content.less
。通过研究Less代码中 CSS 选择器的嵌套,你会发现.wrapper
容器中嵌套了aside float:right;
。如果你将这个aside
规则移到#content
容器中,语法应该如下所示:
#content {
//two third of @basic-width
width:(@basic-width * 2 / 3);
float:left;
min-height:200px;
aside {
float:right;
}
}
在less/content.less
文件中,你还会发现一行h2 { color: @content-dark-color; }
,这与你在aside
元素中看到的是相反的。h2
规则仍然会被#sidebar h2{ color: black; }
覆盖。最终的规则包含了一个#sidebar
选择器,因此它具有更高的CSS 特异性,正如第一章所解释的那样。
检查Less文件,例如less/header.less
,再次牢记关于 CSS 选择器嵌套的全新见解。你会发现嵌套已经经常被使用。例如,在less/header.less
中,h1
元素的属性是通过嵌套设置的。
对这些文件进行适当的检查还将向您展示混合可以嵌套在类和其他混合中的方式。
混合和类
混合的名称应该总是以括号结尾;否则,它就是一个普通的类。Less中的混合和类都可以嵌套。考虑以下示例Less代码的区别:
.class-1{
property-1: a;
}
.class-2{
.class-1;
property-2: b;
}
这段代码将被编译成以下代码:
.class-1 {
property-1: a;
}
.class-2 {
property-1: a;
property-2: b;
}
您可以看到.class-1
的属性如何被复制到编译后的 CSS 中的.class-2
中。当您在Less中在.class-1
后面添加括号并将其变成混合时,现在您应该考虑以下代码:
.mixin(){
property-1: a;
}
.class-2{
.mixin;
property-2: b;
}
这段代码将被编译成以下 CSS 代码:
.class-2 {
property-1: a;
property-2: b;
}
让我们回到侧边导航菜单的示例。当您的菜单准备好时,您会发现h2
标题元素内的“导航”文本毫无意义。除非您视力受损并使用屏幕阅读器,否则您可以轻松地看到侧边菜单是网站的导航。因此,您可以隐藏此标题,但应该保持对屏幕阅读器可见。设置display:none
将使元素对屏幕阅读器不可见,而visibility:hidden
也会隐藏元素,但仍会占用空间,因此可能会搞乱我们的设计。设置clip
属性将有助于解决这种情况。您可以通过访问a11yproject.com/posts/how-to-hide-content/
了解更多详情。
根据优先规则,您可以使用Less编写以下类:
.screenreaders-only {
clip: rect(1px, 1px, 1px, 1px);
position: absolute;
border:0;
}
将前述类添加到less/boxsizing.less
中,并将此文件重命名为less/basics.less
。还请不要忘记重命名less/styles.less
中的导入语句。现在,您可以使用以下Less代码来隐藏侧边栏菜单中的h2
标题元素:
#sidebar{
h2{
color: black;
font-size: 16px;
.screenreaders-only;
}
}
执行这些步骤并将Less代码编译为 CSS 代码后,侧边导航现在将如下截图所示:
带有隐藏标题文本的样式化导航菜单
由于.screenreaders-only
是一个类而不是混合,并且类被编译到最终的 CSS 中,因此不仅可以使用.screenreaders-only
类将其属性添加到Less中的其他类中,还可以直接在 HTML 中使用该类,如下面的代码行所示:
<div class="screenreaders-only">Only readable for screen readers</div>
在使用Less时,您经常需要根据项目的 HTML 结构选择特定编译的Less类和更通用的解决方案,该解决方案将应用于 HTML 代码中的一个类。不幸的是,在这些情况下,没有单一的解决方案。一般来说,特定于 DOM 的代码将生成更多的 CSS 代码,但也会保持 HTML 的清晰,并为您提供生成更多语义 HTML 代码的机会。对于这个选项,重用您的Less代码并不总是简单的。
将您的Less语法编译为类,并在 HTML 中使用它们将使您的代码更具可重用性。另一方面,它会由于这些类而搞乱您的 HTML。此外,CSS 效果与 HTML 结构之间的关系变得不那么严格。这使得维护或更改变得更加困难。
变量
在less/variables.less
中,您应该定义一个侧边栏的部分,如下面的代码所示:
/* side bar */
@header-color: black;
@header-font-size: 16px;
/* menu */
@menu-background-color: white;
@menu-font-color: green;
@menu-hover-background-color: darkgreen;
@menu-hover-font-color: white;
@menu-active-background-color: lightgreen;
@menu-active-font-color: white;
使用前面的变量,less/sidebar.less
中的Less代码现在将如下所示:
#sidebar{
h2{
color: @header-color;
font-size: @header-font-size;
.screenreaders-only;
}
ul{
li{
a{
text-decoration: none;
color: @menu-font-color;
background-color: @menu-background-color;
}
}
}
}
类和命名空间
在完成菜单之前,用于样式化菜单的Less代码将首先更改为类。这里已经讨论了需要考虑的要点。导航是一个通用结构,可以在许多项目中使用。在类结构中,它可以用来为任何 HTML 列表设置样式。
请为less/nav.less
创建一个新文件,并将以下代码写入其中:
.nav{
li{
a{
text-decoration: none;
color: @menu-font-color;
background-color: @menu-background-color;
}
}
}
现在,您可以通过将.nav
类添加到每个 HTML 列表(ul
或ol
)中,将我们 HTML 文档中的每个 HTML 列表转换为导航结构。可以使用以下代码行来实现:
<ul class="nav">
请注意,使用这个Less代码,列表不能嵌套,列表中的项目应包含锚点(链接)。这些要求使得这段代码在您的其他项目中可以轻松地被(重新)使用。Less还提供了定义命名空间的可能性。命名空间可以使您的代码更具可移植性,并且与 CSS ID 选择器的定义方式相同。命名空间以#
开头,如下面的代码所示:
#lessnamespace {
.nav {
//code from less/nav.less here
}
}
#lessnamespace
命名空间现在可以作为示例使用,如下面的代码所示:
#sidebar {
ul{
#lessnamespace > .nav;
}
}
实际上,命名空间与 ID 选择器没有区别。#lessnamespace
命名空间也可以直接在您的 HTML 代码中使用,尽管在大多数情况下这并没有什么用,如下面的代码所示:
<div id="lessnamespace">
<ul class="nav">
...
</ul>
</div>
HTML 要求每个 ID 只能定义一次,因此除非将 ID 附加到 body,否则不能在 HTML 文档中多次使用前面的 HTML 代码。然而,前面的代码表明,即使为自定义 HTML DOM 结构专门编写了Less代码,也可以在其他项目中重用。
在之前定义的#lessnamespace
命名空间中,.nav
是一个使直接使用成为可能的类。当.nav
被更改为 mixin 时,它只能在Less中被重用,如下面的代码所示:
#namespace {
.nav(){
li{
width:100%;
}
}
}
#sidebar {
ul{
#namespace > .nav;
}
}
这段代码将直接编译成以下代码:
#sidebar ul li {
width: 100%;
}
操作数字、颜色和变量
Less支持基本算术运算:加法(+
)、减法(-
)、乘法(*
)和除法(/
)。在 strict-math 模式下,操作应放在括号之间。您可以对变量、值和数字进行操作。这些将帮助您建立变量之间的关系。
打开less/footer.less
立即看到您使用的操作,如下面的代码所示,以及它的好处:
footer {
div {
float: left;
width: ((@basic-width / 3 ) - @footer-gutter);
}
}
在前面的代码中,/
符号(除法)被用来使页脚列占可用宽度的三分之一(由@basic-width
设置)。在代码中使用操作感觉如此自然,以至于您可能甚至没有意识到您一直在使用它们。Less使用正常的顺序优先级,您可以添加额外的括号来明确设置优先级并避免混淆。例如,在Less中,3 + 3 * 3得到12。因此,(3 + 3) * 3等于18,如下面的代码所示:
.mixin(){
property1: (3 + 3 * 3);
property2: ((3 + 3) * 3);
}
.class {
.mixin;
}
这段代码将编译成以下代码:
.class {
property1: 12;
property2: 18;
}
Less操作也可以用于颜色处理,可以对不同单位的值和颜色进行操作,如下面的代码所示:
@color: yellow;
.mixin(){
property1: (100px * 4);
property2: (6% * 1px);
property3: (#ffffff - #111111);
property4: (@color / 10%)
}
.class {
.mixin;
}
这段代码将编译成以下代码:
.class {
property1: 400px;
property2: 6%;
property3: #eeeeee;
property4: #1a1a00;
}
&符号
&
符号在Less中扮演着特殊而重要的角色。它指的是当前选择器的父级,您可以使用它来颠倒嵌套顺序,扩展或合并类。您将看到下面的示例将告诉您比千言万语还要多的内容:
.class1
{
.class2{
property: 5;
}
}
.class1
{
.class2 & {
property: 5;
}
}
这段代码将编译成以下代码:
.class1 .class2 {
property: 5;
}
.class2 .class1 {
property: 5;
}
您可以看到当您在.class2
后使用&
符号时,它变成了.class1
的父级。&
符号也可以用来引用超出 mixin 范围的嵌套。
&
符号也可以用来嵌套和附加伪类到一个类。稍后,您将看到您还可以用它来附加类。一个简单的例子是为链接添加一个由鼠标悬停触发的:hover
伪类,如下面的代码所示:
.hyperlink{
color: blue;
&:hover {
color: red;
}
}
这段代码可以编译成以下代码:
.hyperlink {
color: blue;
}
.hyperlink:hover {
color: red;
}
现在,在文本编辑器中打开less/mixins.less
,找到clearfix mixin。clearfix mixin 使用&
符号将:hover
、:after
和:before
伪类附加到您的元素上,如下面的代码所示:
.clearfix() {
&:before,
&:after {
content: " "; /* 1 */
display: table; /* 2 */
}
&:after {
clear: both;
}
}
有了关于&
符号的这些新知识,您现在可以轻松理解如何通过:hover
和:active
(.active
)状态扩展示例导航菜单,下面的代码显示了您的扩展代码将是什么样子:
.nav {
li {
a {
text-decoration: none;
color: @menu-font-color;
&:hover {
color:@menu-hover-font-color;
background-color:@menu-hover-background-color;
}
width:100%;
display: block;
padding: 10px 0 10px 10px;
border: 1px solid @menu-border-color;
margin-top: -1px;// prevent double border
}
&.active {
a {
color:@menu-active-font-color;
background-color:@menu-active-background-color;
}
}
&:first-child a {
border-radius: 15px 15px 0 0;
}
&:last-child a{
border-radius: 0 0 15px 15px;
}
}
list-style: none outside none;
padding:0;
}
在浏览器中打开http://localhost/indexnav.html
以检查前面语法的结果。
extend
伪类是Less伪类,使用与 CSS 伪类相同的语法。extend
伪类将选择器添加到扩展选择器列表中。将选择器添加到不同类的选择器列表中,使选择器具有与扩展类相同的属性。还记得之前示例中的.hyperlink
类吗?如果您扩展此类,那么两个类将具有相同的属性:
.hyperlink{
color: blue;
&:hover {
color: red;
}
}
.other-hyperlink:extend(.hyperlink){};
此代码将编译为以下代码:
.hyperlink,
.other-hyperlink {
color: blue;
}
.hyperlink:hover {
color: red;
}
请注意,嵌套的:hover
伪类未在.other-hyperlink
中涵盖。要扩展包括扩展样式的嵌套元素的类,必须在选择器末尾添加all
关键字,如下面的代码所示:
.other-hyperlink:extend(.hyperlink all){};
现在,此代码将编译为以下代码:
.hyperlink,
.other-hyperlink {
color: blue;
}
.hyperlink:hover,
.other-hyperlink:hover {
color: red;
}
在嵌套:extend
语句的情况下,您必须使用&
符号作为引用,如下面的代码所示:
.other-hyperlink{
&:extend(.hyperlink);
};
尽管extend
语法模仿伪类的语法,但只要在选择器末尾添加:extend
,两者就可以结合使用,如下面的代码所示:
.other-hyperlink:hover:extend(.hyperlink){};
属性合并
属性合并在属性接受逗号分隔值(CSV)时非常有用。您将在 CSS3 中大多数情况下找到这种类型的属性,其中边框、背景和过渡接受 CSV 列表。但是,您还会发现老式的font-family
参数接受由逗号分隔的字体名称列表。通过在名称后添加加号(+
)来合并属性,如下面的代码所示:
.alternative-font()
{
font-family+: Georgia,Serif;
}
.font()
{
font-family+: Arial;
.alternative-font;
}
body {
.font;
}
此代码将编译为以下代码:
body {
font-family: Arial, Georgia,Serif;
}
内置函数
Less支持许多方便的内置函数。内置函数可用于在混合中操作Less值并设置变量的值。最后但同样重要的是,它们还可以用于守卫表达式。您可以通过访问lesscss.org/functions/
找到完整的函数列表。
在本章中,您不会找到所有这些函数,但您将学习如何使用来自所有不同组的函数。函数可以根据其输入和输出类型进行分组,其中这些类型是数学函数、颜色函数、列表函数、字符串函数和类型函数。还有一小部分函数无法使用前述分类进行分组。
JavaScript
Less函数首先映射本机JavaScript 函数和代码,因为Less是用 JavaScript 编写的。目前,JavaScript 表达式仍然可以在Less代码中作为值进行评估,但这种能力可能会在将来的版本中被移除。在您的Less代码中使用 JavaScript 代码时,应该将 JavaScript 代码包装在反引号之间,如下面的代码所示:
@max: ~"`Math.max(10,100)+'px'`";
p {
width: @max;
}
包含 JavaScript 代码的Less代码将编译为以下 CSS 代码:
p {
width: 100px;
}
尽管可能,但尽量避免在代码中使用 JavaScript。用其他语言编写的Less 编译器无法评估此代码,因此您的代码不具备可移植性,并且更难以维护。
如果您的目的没有内置的Less函数可用,尝试用Less代码编写您需要的等效代码。自 1.6 版本以来,有一个max()
函数,以前可以使用以下代码:
.max(@a,@b) when (@a>=@b){@max:@a;}
.max(@a,@b) when (@b>@a){@max:@b;}
特别是在使用 JavaScript 环境时要小心在您的Less代码中。此外,诸如document.body.height
之类的值在您编译的无状态 CSS 中毫无意义。
列表函数
Extract()
和length()
是用于获取 CSV 列表的值和长度的函数。这些函数可以一起用于作为数组在 CSV 列表上进行迭代。
还记得在第二章中用于设置侧边栏导航中的链接前景图像的循环吗?在这里,您将使用相同的技术在链接之前添加图标。
此示例使用了来自 Font Awesome 的图标。Font Awesome 是一种使用可缩放矢量图标的图标字体,可以通过 CSS 进行操作。图标可以很容易地通过 CSS 进行缩放或着色;此外,加载字体只需要一个 HTTP 请求来获取所有图标。请参阅fontawesome.io/
获取更多信息。
要使用 Font Awesome,首先通过将以下代码添加到 HTML 文档的头部来引用其源:
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
注意
Font Awesome 和其他图标字体也可以使用Less集成和编译到您的项目中。您将在第四章中学习如何做到这一点,避免重复造轮子。
在您的 HTML 中,现在可以使用以下代码行:
<i class="fa fa-camera-retro"></i> fa-camera-retro
图标是使用 CSS 的:before
伪类添加的,因此前面的 HTML 代码也可以通过以下Less代码进行样式设置,而无需使用类:
i:before {
font-family:'FontAwesome';
content:"\f083";
}
提示
可以通过访问astronautweb.co/snippet/font-awesome/
找到 Font Awesome 图标及其 CSS 内容值的列表。
有了关于图标字体的这些信息,您可以构建一个循环,将图标添加到导航的列表项中,如下面的代码所示:
@icons: "\f007","\f004","\f108","\f112","\f072","\f17c";
.add-icons-to-list(@i) when (@i > 0) {
.add-icons-to-list((@i - 1));
@icon_: e(extract(@icons, @i));
li:nth-child(@{i}):before {
font-family:'FontAwesome';
content: "@{icon_}\00a0";
}
}
.add-icons-to-list(length(@icons));
在@icon_: e(extract(@icons, @i));
行中,e()
是一个字符串函数,这个函数相当于使用~""
进行转义。还请注意,在content: "@{icon_}\00a0";
语句中,\00a0
只是添加了一个额外的空格,用于将图标与链接分隔开。
@icons
CSV 列表中的图标是随机选择的。add-icons-to-list()
mixin 的递归调用从.add-icons-to-list(length(@icons));
调用开始,其中length(@icons)
返回@icons
中的项目数。
将添加图标到列表项的循环的Less代码应该添加到less/navicons.less
中。在添加代码后,打开http://localhost/indexnavicons.html
查看结果,结果应该如下屏幕截图所示:
使用 Less 和 Font Awesome 构建的图标化超链接
在前面的屏幕截图中,图标列表仅用于演示目的,在实际情况下,这些图标甚至与超链接没有关联。这种关系的缺失使得很难找到任何用例。但是,凭借你们的创造力,我敢打赌你们能找到一个。请记住,CSS 仅用于演示,不能修改 HTML,因此无法使用Less设置链接本身。但是,可以创建超链接和已存在的图标之间的关系,如下面的代码所示:
#content a[href*="linux"]:before {
font-family:'FontAwesome';
content: "\f17c\00a0";
}
在这里,a[href*="linux"]
是一个选择器,用于选择所有href
属性中包含linux
单词的锚点。在将上述代码添加到less/styles.less
后,可以在http://localhost/index.html
上查看结果。
使用颜色函数
Less颜色函数可以分为颜色定义、混合、操作和通道操作的函数。
颜色是在颜色通道中定义的。RGB 颜色有三个通道:红色、绿色和蓝色。CSS2 使用这个 RGB 定义来声明颜色,CSS3 为颜色声明添加了新的定义。这些新的定义,如 HSL 和 HSV,实际上只是 RGB 值的转换。CSS3 颜色设置方法应该更直观和用户友好。例如,HSL 在这种情况下定义了三个通道的颜色,即色调、饱和度和亮度。Less具有用于不同类型颜色定义的通道操作的内置函数。Less还支持不同类型的颜色定义。自 CSS3 以来,您可以将颜色值声明为十六进制颜色、RGB 颜色、RGBA 颜色(带有额外 alpha 通道的 RGB 颜色,用于设置不透明度)、HSL 颜色和 HSLA 颜色(带有额外 alpha 通道的 HSL 颜色,也用于设置不透明度)。当然,您可以使用预定义的跨浏览器颜色名称。
Less颜色定义的编译颜色值并不总是在 CSS 代码中定义为十六进制颜色;如果可能的话,颜色定义的输出与 CSS 值匹配,如下面的代码所示:
.selector {
color1: rgb(32,143,60);
color2: rgba(32,143,60,50%);
color3: hsl(90, 100%, 50%);
}
编译后,上述Less代码变为以下 CSS 代码:
.selector {
color1: #208f3c;
color2: rgba(32, 143, 60, 0.5);
color3: #80ff00;
}
颜色是网站设计和样式的基本部分。颜色函数可以帮助您设计您的调色板并使其具有动态性。例如,它们将用于为元素赋予比背景颜色更深的边框颜色,或者为元素赋予基于单个输入颜色的对比颜色。
darken()
和lighten()
函数
darken()
和lighten()
函数是两个颜色函数,可用于获得输入颜色的较暗或较亮的变体。您已经看到这些函数如何在第二章的示例布局中使用,使用变量和混合。现在,您可以在先前构建的网站导航菜单上应用这些函数。
请在文本编辑器中打开less/variablesnav.less
,并根据以下方式定义依赖于主@menucolor
参数的菜单变量:
@menucolor: green;
@menu-background-color: white;
@menu-font-color: @menucolor;
@menu-border-color: darken(@menucolor,10%);
@menu-hover-background-color: darken(@menucolor,10%);
@menu-hover-font-color: white;
@menu-active-background-color: lighten(@menucolor,10%);
@menu-active-font-color: white;
完成后,通过在浏览器中打开http://localhost/indexnav.html
来检查您的更改。现在,您可以通过仅更改@menucolor
变量定义的颜色来修改导航的外观。您还会发现,将@menucolor
设置为浅色,如粉红色或黄色,会使您的字体由于背景颜色和字体颜色之间的对比度不够高而无法阅读。高对比度在网页设计中起着重要作用。高对比度的设计有助于满足可访问性标准。高对比度不仅有助于视觉障碍或色盲人士,也影响正常视力的人,因为人类天生喜欢高对比度的颜色设计。这种偏好在您网站的第一印象中起着作用。
计算正确的对比度并不总是容易的。此外,在这种情况下,您不希望在更改基本颜色后不得不更改所有字体颜色。Less的contrast()
函数将帮助您选择一种颜色,可以在有色背景下轻松看到。根据 WCAG 2.0(www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
),此函数比较亮度值而不是颜色的明亮度。luma()
函数本身也是一个内置的颜色函数。
contrast()
函数接受四个参数。第一个参数定义要与之比较的颜色;在这种特殊情况下,这是背景颜色。第二和第三个参数定义暗色和亮色,默认为黑色和白色。第四个和最后一个参数设置一个阈值。默认情况下,此阈值设置为 43%,并定义了亮度(感知亮度)。超过阈值的颜色被视为亮色,contrast()
返回已在第二个参数中定义的暗色。
现在,重新打开less/variablesnav.less
,并根据以下代码更改导航字体颜色:
@menucolor: green;
@menu-background-color: white;
@menu-font-color: contrast(@menucolor);
@menu-border-color: darken(@menucolor,10%);
@menu-hover-background-color: darken(@menucolor,10%);
@menu-hover-font-color: contrast(@menu-hover-background-color);
@menu-active-background-color: lighten(@menucolor,10%);
@menu-active-font-color: contrast(@menu-active-background-color);
要查看更多效果,请将@menucolor
变量更改为不同的颜色,如yellow
、pink
、darkgreen
或black
,并通过打开http://localhost/indexnav.html
来观察变化。请记住,最浅的颜色是白色,最深的是黑色,因此darken(black,10%);
或lighten(white,10%);
不会产生任何效果。
颜色操作
如前所述,Less为您提供了许多操作颜色的功能。本书不涉及色彩理论,因此只处理了一些颜色操作的示例。您可以通过访问www.packtpub.com/article/introduction-color-theory-lighting-basics-blender
获取更多关于色彩理论的信息。
颜色操作
通过darken()
、lighten()
和contrast()
函数,您已经了解了一些颜色操作。其他操作包括saturate()
、desaturate()
、fadein()
、fadeout()
、fade()
、spin()
、mix()
和grayscale()
。
前面提到的函数接受一个或多个颜色值,以百分比作为输入参数,并返回一个颜色。请注意,颜色范围从白色到黑色,不会环绕。因此,无法像前面提到的那样使黑色变暗,使其变成白色。
如果颜色定义包含百分比,则操作会将其转换为输入参数的绝对百分比。因此,darken(hsl(90, 80%, 50%), 20%)
变为#4d8a0f
;相当于hsl(90, 80%,30%)
而不是hsl(90, 80%,10%)
。当然,您会看到相同的效果,因为您操作了定义饱和度的第二通道。例如,desaturate(hsl(45, 65%, 40%), 50%)
编译为#756e57;
,相当于hsl(45, 15%, 40%)
。
mix()
函数是颜色操作的最后一个示例。其他函数留作练习。
@color: mix(blue, yellow, 50%);
.class {
color: @color;
}
这将再次变成以下内容:
.class {
color: #808080;
}
这种混合也将显示在以下图像中:
如何使用mix(blue, yellow, 50%)
来呈现蓝色和黄色的混合
使用 Less 进行颜色混合
颜色混合函数根据两个输入颜色计算新的颜色,其中函数对输入颜色的颜色通道应用基本操作,如减法。可用的函数,也称为混合模式,包括multiply()
、screen()
、overlay()
、softlight()
、hardlight()
、difference()
、exclusion()
、average()
和negation()
。使用图层图像编辑器(如 Photoshop 或 GIMP)的用户将会认识到这些函数。
difference()
函数按通道逐个通道地从第一个颜色中减去第二个颜色,如下所示:
@color: difference(orange, red, 50%);
.class {
color: @color;
}
前面的代码将变成以下代码:
.class {
color: #00a500;
}
以下图显示了橙色和红色混合的效果:
使用difference(orange, red, 50%)
来呈现橙色和红色的混合
类型函数
类型函数评估输入值的类型,并在类型匹配函数时返回true
。可用的函数包括isnumber()
、isstring()
、iscolor()
、iskeyword()
、isurl()
、ispixel()
、isem()
、ispercentage()
和isunit()
。以下代码显示了一些示例函数:
isnumber("string"); // false
isnumber(1234); // true
isnumber(56px); // true
iscolor(#ff0); // true
iscolor(blue); // true
iscolor("string"); // false
ispixel(1234); // false
ispixel(56px); // true
类型函数在定义守卫时非常有用。请考虑以下语法:
.mixin() when isprecentage(@value) {
width: 25%;
}
.mixin() when ispixel(@value) {
width: (@value / 4 );
}
default()
函数是另一个内置函数,不属于函数类。default()
函数可以在守卫内使用,并在没有其他 mixin 与调用者匹配时返回true
。您可以将默认 mixin 添加到前面的 mixin 中,如下所示:
.mixin() when ispercentage(@value) {
width: 25%;
}
.mixin() when ispixel(@value) {
width: (@value / 4 );
}
.mixin() when (default()) {
display: none;
}
box-shadow mixin
通过学习Less,您现在可以理解、构建和评估任何复杂的Less代码。为了证明这一点,请打开less/mixins.less
,看一下 box-shadow mixin(最初发布在lesscss.org上),代码如下:
.box-shadow(@style, @c) when (iscolor(@c)) {
-webkit-box-shadow: @style @c;
-moz-box-shadow: @style @c;
box-shadow: @style @c;
}
.box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) {
.box-shadow(@style, rgba(0, 0, 0, @alpha));
}
要完全理解这些混合,您将需要了解 CSS3 中box-shadow的基础知识。box-shadow 属性接受阴影的 CSV 列表。阴影由两到四个长度值和一个颜色组成。前两个长度值描述与框的中心相关的垂直和水平偏移量。这些值是必需的,但可以设置为0
以获得围绕框的等大小阴影。最后的值是可选的,并设置模糊半径和扩展半径。默认情况下,模糊和扩展半径都为0
,并产生一个锐利的阴影,其中扩展半径等于模糊半径。
现在您应该能够评估这个混合。您将看到这些混合形成了一个保护。两个混合都接受两个参数。第一个参数是长度向量,如前所述;第二个是颜色或百分比。如果您回忆一下isnumber(40%)
的调用会评估为true
,尽管最后有百分号。调用rgba(0, 0, 0, @alpha)
将根据@alpha
的值给出灰色的阴影。如果您将第二个参数定义为颜色,比如blue
或#0000ff
,iscolor(@c)
保护将评估为true
,并且第一个混合将使用您定义的颜色进行编译。
摘要
在本章中,您使用Less构建了一个导航菜单。导航包含了悬停、对比颜色和图标等内容,所有这些都可以通过几个基本设置来设置。您已经学会了如何在Less中使用嵌套规则、混合和内置函数。在本章的结尾,您已经理解并使用了复杂的Less代码。所有这些新获得的知识将在下一章中非常有用。在下一章中,您将学习如何查找和构建可重用的Less代码。这将帮助您更快地工作并获得更好的结果。
第四章:避免重复造轮子
在前几章中,你学会了如何使用Less来编译你的 CSS。Less帮助你创建可重用和可维护的 CSS 代码。你已经学会了如何组织你的文件,前一章还向你展示了命名空间的作用,使你的代码具有可移植性。Less帮助你编写高效的代码来处理浏览器的不兼容性。Less不能单独解决浏览器的不兼容性问题,但可以使你的解决方案可重用,尽管由于这个原因,可重用的混合仍然可能很复杂。在本章中,你将学会你不必自己编写所有这些复杂的代码。有一些预构建混合的库可以帮助你更快地工作并创建更稳定的代码。
本章将涵盖以下主题:
-
背景渐变
-
防止未使用的代码
-
测试你的代码
-
预构建混合的标志性字体
-
Retina.js
重新审视背景渐变
还记得第二章中讨论的 CSS3 背景渐变吗,使用变量和混合?为了在不同的浏览器上显示更好或相同的渐变,你必须使用特定于供应商的规则。不同的规则集会使你的混合更加复杂。在这种情况下,更复杂也意味着更难以维护。
在实践中,你的混合会随着过时的代码或不再受支持的代码而增长,另一方面,你必须更新你的混合以适应更新的浏览器。当然,我们只能希望新的浏览器版本支持 CSS3 规范,而不需要对代码进行进一步的更改。
Can I use...网站(caniuse.com/
)提供了 HTML5、CSS3 和 SVG 支持的兼容性表,还有桌面和移动浏览器的兼容性表。它会告诉你,大多数当前浏览器在其当前版本中都支持 CSS 渐变。在撰写本书时,移动设备的 Android 浏览器仍然依赖于-webkit
供应商规则,而 Opera Mini 根本不支持它。
如果放弃对旧版浏览器的支持,你的混合可以简化为以下代码片段:
.verticalgradient(@start-color: black; @end-color: white; @start-percent: 0%; @end-percent: 100%) {
background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);
background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent);
background-repeat: repeat-x;
}
前面的代码还放弃了对 IE8 和 IE9 的支持。如果你选择支持这些浏览器,你必须添加额外的 IE 特定规则。Can I use…网站还向你展示了最常见浏览器的市场份额。在某些情况下,只为旧版浏览器提供功能支持而不指望所有浏览器看起来完全一样也是有用的。例如,一个没有高级动画的导航结构仍然可以帮助用户浏览你的网站。使用旧版浏览器的人并不总是期望最新的技术。这些技术也并不总是有附加值。旧版浏览器大多不运行在最新的硬件上;在这些浏览器上,对渐变等功能的支持只会减慢你的网站速度,而不会增加任何价值。
未使用代码
即使在长期运行和不断增长的项目中使用Less,也几乎不可能在你的代码中找不到一些未使用的代码。浏览器工具可以帮助检测最终 CSS 中的未使用代码。
Chrome 的开发者工具
谷歌 Chrome 的开发者工具有一个选项可以找到未使用的 CSS。在谷歌 Chrome 中,导航到工具 | 开发者工具,选择审核选项卡,然后点击运行。
现在使用这个工具来测试前几章的演示代码。
首先,在浏览器中打开http://localhost/index.html
并运行测试。你会看到以下截图:
Chrome 的开发者工具显示的未使用代码
未使用代码列表以less/normalize.less
中定义的一长串样式开始,如第一章中所示,使用 Less 改进 Web 开发;这些是CSS 重置的样式。
在大多数项目中,每个页面都使用相同的 CSS 代码基础(相同的文件)。因此,您不能总是保证页面只包含真正使用的代码。其中一些代码不会在每个页面上使用,但将必须在其他或未来的页面上使用。Web 浏览器能够缓存 CSS 文件,因此最好使用相同的 CSS 文件来为网站的不同页面设置样式。某些页面将不使用所有缓存的样式规则,这将显示为该页面上未使用的代码。缓存的代码只加载一次并在每个页面上使用。CSS 重置似乎对所有页面都有用,因此您不应更改或删除它。
正如您所看到的,.centercontent
和.screen-readeronly
是未使用的。请记住,类被编译到您的 CSS 中,而 mixin 则不是。现在,.centercontent
和.screen-readeronly
被定义为类。拥有.screen-readeronly
类似乎是有用的,但.centercontent
可以更改为 mixin。
Firebug CSS 使用附加组件
对于 Firefox,可以使用 Firebug 的附加组件。这将帮助您找到未使用的代码。您可以在addons.mozilla.org/en-US/firefox/addon/css-usage/
下载此插件。
测试您的代码
您不必自己编写所有的 Less 代码,因为它是可重用和可移植的。在 Web 上可以找到 Less 代码的 mixin 和片段,并在您的项目中(重新)使用。搜索Less mixin 背景渐变,您将得到许多有用的结果。尝试找到支持浏览器并满足您要求的代码。如果对 mixin 的浏览器支持有任何疑问,请考虑在 Stackoverflow.com 上提问。始终展示您的代码和您所做的事情;不要只是寻求解决方案。此外,关于Less的其他问题也可以在 Stackoverflow.com 上提问。
集成代码片段甚至完整的命名空间将使您的代码测试更加重要。
了解 TDD
测试驱动开发(TDD)是软件开发的一种经过验证的方法。在 TDD 中,您为项目中的每一段代码编写测试。在添加或改进功能或重构代码时,更改代码后,所有测试都应该通过。所有测试应该自动运行。虽然可以自动测试 Less 和 CSS 代码,但您需要手动查看不同浏览器和设备上页面的确切外观,尽管其他方面,如正确性和性能可以自动测试。例如,您可以使用 CSS Lint 等工具自动测试您的代码。CSS Lint 验证和测试您的代码,包括性能、可维护性和可访问性等方面。这些工具测试编译后的 CSS 而不是您的 Less 代码。Less Lint Grunt 插件编译您的 Less 文件,通过 CSS Lint 运行生成的 CSS,并输出任何发现的 CSS Lint 错误的冒犯的 Less 行。可以通过访问www.npmjs.org/package/grunt-lesslint
获取更多信息。
关于样式指南的一切
样式指南提供了网站元素的概述,如按钮、导航结构、标题和字体。它展示了正确的呈现和颜色。为您的项目和网站创建样式指南可以帮助您测试您的 Less 代码。样式指南还将帮助项目的其他开发人员和内容发布者。
您现在可能会认为样式指南确实很有用,但也很耗时;因此,接下来将讨论两种工具。这些工具根据您的 Less(或编译后的 CSS)代码自动生成样式指南。这两种工具仍然需要一些额外的代码和努力,但不会花费太多时间。几乎总是值得测试您的代码。还要意识到这里的重大收益:您只需测试样式的效果。Less 保证您的 CSS 已经有效,并且 Less 编译器处理了它的优化。正如承诺的那样,这为您的真正设计任务提供了更多时间。
使用 StyleDocco 构建样式指南
StyleDocco 从样式表中生成文档和样式指南文档。StyleDocco 也非常适用于 Less 文件。要使用 StyleDocco 创建样式指南,您需要在 Less 文件中添加注释。注释应该解释样式的作用,并包含 HTML 示例代码。注释需要用 Markdown 编写。Markdown 是一种纯文本格式,可以轻松转换为 HTML。StackOverflow.com 使用 Markdown 发表和评论。您可以使用其帮助指南了解更多信息;您可以通过访问 www.stackoverflow.com/editing-help/
找到它。
可以使用以下命令使用 npm 安装 StyleDocco:
npm install -g styledocco
您已经在 第一章 中了解了 npm,使用 Less 改进 Web 开发。安装 StyleDocco 后,您需要在 Less 文件中添加 Markdown 注释。
要查看使用 StyleDocco 生成的样式指南示例,请在文本编辑器中打开 less/nav.less
,并按照下面的代码片段添加 Markdown 描述,然后是 HTML 测试代码:
/* Construct a navigation structure.
<ul class="nav">
<li><a href="#">item 1</a></li>
<li><a href="#">item 2</a></li>
<li class="active"><a href="#">item 3</a></li>
</ul>
*/
要构建样式指南,请在终端中导航到您的 Less 文件夹(lessc
)并运行以下命令:
styledocco -n "Less Web Development Essentials Styleguide" --preprocessor "/usr/local/bin/lessc" --verbose [file path]
在上面的示例中,使用 -n
设置了样式指南的名称。通常情况下,如果您的文件路径只包含 Less 文件,则不必设置 –preprocessor
选项。要为您的 Less 文件构建样式指南,命令应该如下所示:
styledocco -n "Less Web Development Essentials Styleguide" less/*
styledocco
命令会生成一个名为 docs/
的新文件夹。这个文件夹包含一个 index.html
文件,可以在浏览器中打开。最终结果应该看起来像下面的截图:
使用 StyleDocco 构建的样式指南示例
使用 tdcss.js 测试您的代码
tdcss.js
框架是另一个与 Less 配合良好并促进测试驱动开发的样式指南工具。tdcss.js
框架可以从 GitHub 免费下载,网址为 github.com/jakobloekke/tdcss.js
。另请参阅 jakobloekke.github.io/tdcss.js/
以获取更多信息。与 StyleDocco 不同,使用 tdcss.js
不会更改您的 Less 文件。您可以使用项目中相关源代码的片段生成样式指南。例如,您可以使用 HTML 注释样式编码,如 <!-- : 导航 -->
,将它们分隔开。然后将片段复制并粘贴到一个 HTML 文档中,形成您的样式指南,并包含来自您的 Less 代码和 tdcss.js
的样式。示例导航的 HTML 文档的 head
部分应具有以下结构:
<!-- Your Less code -->
<link rel="stylesheet/less" type="text/css" href="less/styles.less" />
<script type="text/javascript">less = { env: 'development' };</script>
<script src="img/less.js" type="text/javascript"></script>
<!-- TDCSS -->
<link rel="stylesheet" href="tdcss/tdcss.css" type="text/css" media="screen">
<script src="img/jquery-1.11.0.min.js"></script>
<script src="img/jquery-migrate-1.2.1.min.js"></script>
<script type="text/javascript" src="img/tdcss.js"></script>
<script type="text/javascript">
$(function(){
$("#tdcss").tdcss();
})
</script>
body 中的标记如下:
<div id="tdcss">
<!-- # Navigation -->
<!-- & Style lists used for navigation. -->
<!-- : Basic navigation -->
<ul class="nav">
<li><a href="#">item 1</a></li>
<li><a href="#">item 2</a></li>
<li class="active"><a href="#">item 3</a></li>
</ul>
</div>
通过在浏览器中打开 http://localhost/tdcss.html
查看上述代码的结果。最终结果应该看起来像下面的截图:
使用 tdcss.js 构建的样式指南示例
预构建的混合
您已经了解了在网络上搜索和找到 mixin。然而,使用和重用经过充分测试的 mixin 将比那更容易。其他开发人员已经构建了完整的库和预构建的 mixin,您可以在项目中使用。这些预构建的 mixin 帮助您编写Less代码,而无需考虑使 CSS3 复杂的供应商特定规则。在接下来的章节中,您将了解到五个最常用的库。这些库如下:
-
Less Elements (
lesselements.com
) -
Less Hat (
lesshat.madebysource.com/
) -
ClearLess (
clearleft.github.com/clearless/
) -
Preboot (
markdotto.com/bootstrap/
)
还可以在lesscss.org/usage/#frameworks-using-less
找到更全面的 mixin 库列表。
请理解,您不必选择;没有限制您只能使用这些库中的一个。所有这些库都有优缺点;您必须选择最适合您项目需求的库。
全局上,所有库都为您提供一个Less文件,其中包含您可以在项目中导入的 mixin。虽然一些库也有一些设置,在所有情况下,@import "{library-name}";
就足以使其 mixin 可用于您的项目。Less没有限制包含多个库,但这样做会导致 mixin 名称冲突的问题。所有具有相同名称的 mixin 将被编译为 CSS(如果它们的参数也匹配)。因此,一些库还具有这些 mixin 的带前缀版本。
与带前缀版本不同,使用命名空间,如第三章中所解释的,嵌套规则、操作和内置函数,在大多数情况下提供了更稳定的解决方案,如下面的代码片段所示:
// create a namespace for {library-name}
#{library-name}{@import "{library-name}";}
使用#{library-name} > mixin()
使 mixin 可用。
使用 Less Elements 为供应商特定规则提供单行声明
Less Elements 可能是本章讨论的库中最紧凑的一个。紧凑并不意味着它没有用处。这个库的重点是将跨浏览器前缀合并为单一简洁的声明。
还记得本章开头的垂直背景渐变吗?您已经看到,当您支持现代浏览器时,您将需要至少三个声明,包括供应商特定规则。
使用 Less Elements,您可以使用三个参数的单行声明来完成相同的操作,如下面的代码片段所示:
element {
.gradient(#F5F5F5, #EEE, #FFF);
}
第一个参数定义了在不支持渐变的浏览器中使用的回退颜色。渐变从底部到顶部,第二个参数设置底部颜色,第三个参数设置顶部颜色。
前面的Less代码最终将编译为以下 CSS:
element {
background: #f5f5f5;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #eeeeee), color-stop(1, #ffffff));
background: -ms-linear-gradient(bottom, #eeeeee, #ffffff);
background: -moz-linear-gradient(center bottom, #eeeeee 0%, #ffffff 100%);
background: -o-linear-gradient(#ffffff, #eeeeee);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0);
}
在其简单性中,Less Elements 提供了许多有用的 mixin,用于使用CSS3 技术构建您的项目。它为所有 CSS3 属性提供了供应商特定规则的单行声明,并通过布局声明扩展了这一点。
.columns()
mixin 将元素分成列,包括列之间的边框和间隙。.columns()
mixin 的变量顺序为列宽、列数、列间隙、列边框颜色、列边框样式和列边框宽度。
这个 mixin 可以应用于非替换的块级元素(除表元素外)、表单元格和内联块元素,如body
或div
元素。
要将div
元素分成宽度为 150 像素的三列,您现在可以在Less中编写以下代码:
div.threecolumns {
.columns(40px, 3, 20px, #EEE, solid, 1px);
}
前面的代码编译成 CSS,并如下所示:
div.threecolumns {
-moz-column-width: 150px;
-moz-column-count: 3;
-moz-column-gap: 20px;
-moz-column-rule-color: #eeeeee;
-moz-column-rule-style: solid;
-moz-column-rule-width: 1px;
-webkit-column-width: 150px;
-webkit-column-count: 3;
-webkit-column-gap: 20px;
-webkit-column-rule-color: #eeeeee;
-webkit-column-rule-style: solid;
-webkit-column-rule-width: 1px;
column-width: 150px;
column-count: 3;
column-gap: 20px;
column-rule-color: #eeeeee;
column-rule-style: solid;
column-rule-width: 1px;
}
您还可以通过在浏览器中加载 http://localhost/columns.html
来测试这一点。还请将浏览器窗口从小屏幕调整到全屏幕,以查看这些列默认情况下是响应式的。编译后的 .div.threecolumns
类可以与以下 HTML 代码一起使用:
<div class="threecolumns" role="content">Vestibulum at dolor aliquam, viverra ipsum et, faucibus nunc. Nulla hendrerit tellus eu sapien molestie adipiscing. Cras ac tellus sed neque interdum egestas sit amet vel diam. Aenean congue dolor et elit blandit commodo. Pellentesque dapibus tellus eu augue ullamcorper dignissim. Pellentesque pretium a dui a consequat. Curabitur eleifend lectus vel viverra mollis. Sed egestas bibendum tortor mattis fermentum. Suspendisse pellentesque facilisis blandit.</div>
前面的代码将产生以下截图:
使用 Less Elements 的 columns mixin 构建的多列布局示例
.columns()
mixin 使用了 CSS 多列布局模块。有关此模块的更多信息可以在 www.w3.org/TR/css3-multicol/
找到。不幸的是,大多数现代浏览器对该模块的支持还不够好。
Less Elements 不提供有关编译后的 CSS 的浏览器支持的任何信息。在使用 Less Elements 时,您必须已经意识到了这一点。如前所述,您可以在 caniuse.com 网站上检查浏览器支持情况。要找出哪些浏览器支持此多列布局模块,您将需要访问 caniuse.com/multicolumn
。始终检查前面的模块与您的项目的要求是否匹配。此外,此示例向您展示了为什么样式指南非常有用。
Less Hat – a comprehensive library of mixins
与 Less Elements 不同,Less Hat 非常全面。在撰写本书时,Less Hat 包含了 86 个预构建 mixin。Less Hat 还与 CSS Hat 有着密切的关系。CSS Hat 是一款商业许可的工具,可以将 Adobe Photoshop 图层转换为 CSS。
Less Hat mixin 提供了禁用一些特定于浏览器的前缀的可能性。除非您有非常充分的理由这样做,否则不应该使用这个功能。默认情况下,Less Hat 通过将 Less 变量设置为 true
来使用所有浏览器前缀,如下面的代码所示:
@webkit: true;
@moz: true;
@opera: true;
@ms: true;
@w3c: true;
在前面的代码中,@w3c
指的是定义了 W3C 规范 描述的标准属性名称的非前缀规则。Less Hat 宣传自己具有可以创建无限数量的阴影、渐变和动画的 mixin。Box-shadow 就是一个例子。使用 Less Hat,box-shadow mixin 可以写成 .box-shadow(<offset-x> <offset-y> spread blur-radius color inset, …)
。
要尝试前面的 .box-shadow
mixin,您可以使用 Less Hat 在 Less 中编写如下:
div {
.box-shadow(30px 30px 5px green inset,-30px -30px 5px blue inset);
}
前面的代码编译成以下代码片段:
div {
-webkit-box-shadow: 30px 30px 5px #008000 inset, -30px -30px 5px #0000ff inset;
-moz-box-shadow: 30px 30px 5px #008000 inset, -30px -30px 5px #0000ff inset;
box-shadow: 30px 30px 5px #008000 inset, -30px -30px 5px #0000ff inset;
}
要检查这一点,请在浏览器中打开 http://localhost/boxshadow.html
,您将看到 .box-shadow
mixin 的结果,如下截图所示:
Less Hat 的 box-shadow mixin 的效果示例
实际上,Less Elements 的 .box-shadow()
mixin 不接受多个阴影,但在下一节讨论的 3L 的 mixin 可以处理用逗号分隔的多个阴影。
使用预构建 mixin 的 3L 库
3L (Lots of Love for Less) 是另一个预构建 mixin 集合。除了标准的单行声明,3L 还提供了额外的功能。3L 提供了用于 CSS 重置或规范化的 mixin,如 第一章 中所讨论的 使用 Less 改进 Web 开发。您可以在不将它们放在选择器块内的情况下调用这些 mixin,如下所示:
.normalize();
/* OR */
.reset();
/* OR */
.h5bp();
在前面的.h5bp()
重置中,您的 CSS 基于HTML5 Boilerplate。HTML5 Boilerplate 是一个专业的前端模板,用于构建快速、健壮和适应性强的 Web 应用程序或站点。您可以通过访问html5boilerplate.com/
获取有关 Boilerplate 的更多信息。3L 不仅提供了用于 HTML5 Boilerplate 重置的 mixin,还包含了用于 HTML5 Boilerplate 辅助类的 mixin。这些 mixin 包含了清除浮动和用于隐藏内容的 mixin,适用于浏览器或屏幕阅读器。
例如,.visuallyhidden()
可以用于隐藏浏览器中的内容,但对于屏幕阅读器来说,这些内容是可用的。
SEO 和 HTML 调试
SEO(搜索引擎优化)在现代网页设计中扮演着重要角色。正确和有效的 HTML5 是 SEO 的要求。此外,设置适当的标题,使用关键字的 meta 标签和描述以及图像的 alt 属性将有助于您的网站排名更高。
3L 的.seo-helper()
mixin 将快速了解网页缺少的元素和属性。
要使用这个 mixin - 在导入 3L 后,您可以在Less中编写如下:
html {
.seo-helper();
}
使用.seo-helper()
mixin 后,您的 HTML 页面将包含有关缺少标题或 meta 标签的警告,并在缺少 alt 属性的图像周围显示红色边框,如下面的屏幕截图所示:
3L 的辅助类使缺少的 alt 属性可见
此外,访问http://localhost/indexseo.html
以获取有关此类如何工作的更多见解。之后,您可以自行判断这个类是否有用。独立于您的判断,.seo-helper()
mixin 向您展示了Less如何可以应用于网站样式之外的功能。
ClearLess - 另一个预构建 mixin 库
ClearLess 还与 HTML5 Boilerplate 有关。与 3L 一样,ClearLess 提供了用于 HTML5 Boilerplate 和辅助类的 mixin。除此之外,ClearLess 还使用Modernizr。Modernizr 是一个 JavaScript 库,用于检测用户浏览器中的 HTML5 和 CSS3 功能。Modernizr 会为检测到的功能在您的 HTML 的html
元素中添加额外的类。使用 Modernizr,您的html
元素将如下面的代码片段所示:
<html id="modernizrcom" class="js no-touch postmessage history multiplebgs boxshadow opacity cssanimations csscolumns cssgradients csstransforms csstransitions fontface localstorage sessionstorage svg inlinesvg no-blobbuilder blob bloburls download formdata wf-proximanova1proximanova2-n4-active wf-proximanova1proximanova2-i4-active wf-proximanova1proximanova2-n7-active wf-proximanova1proximanova2-i7-active wf-proximanovacondensed1proximanovacondensed2-n6-active wf-athelas1athelas2-n4-active wf-active" lang="en" dir="ltr">
这个类名列表告诉您一个功能是否可用。因此,用于生成前面代码的浏览器支持 box-shadow、opacity 等。使用 Modernizr,您将拥有可以在Less代码中使用的条件类。此外,ClearLess 还使用这些类。
除了 Modernizr mixin 外,ClearLess 还有用于图标和CSS 精灵图像的 mixin。
CSS 精灵图像是一种至少可以追溯到七年前的技术。网站的图像被添加到单个图像中,即精灵。如果浏览器请求图像,精灵将作为背景图像加载。SpriteMe (spriteme.org/
)可以帮助您为您的项目创建精灵。CSS 用于显示包含精灵部分的请求图像。加载一个大的精灵,可以被缓存,而不是几个小图像,将减少浏览器显示页面所需的 HTTP 请求的数量。HTTP 请求越少,页面加载速度就越快。
为了演示这一点,请使用本章的代码包中的Less图像的简单精灵(less-sprite.png
),如下面的屏幕截图所示:
简单精灵图像的示例
要使用精灵图像,您可以在Less中编写如下:
#clearless {
@import "clearleft-clearless-63e2363/mixins/all.less";
@sprite-image: "../images/less-sprite.png";
@sprite-grid: 80px; //image height
}
.logo {
#clearless > .sprite-sized(0,0,200px,80px);
&:hover {
#clearless > .sprite-sized(0,1,200px,80px);
}
}
这段代码也可以在less/sprite.less
中找到。请注意,#clearless
命名空间有自己的作用域,因此@sprite-grid
和@sprite-grid
应该在命名空间内定义。变量通过重新声明进行设置。
前面代码的编译 CSS 将如下所示:
.logo {
background-image: url("../images/less-sprite.png");
background-repeat: no-repeat;
background-position: 0px 0px;
width: 200px;
height: 80px;
}
.logo:hover {
background-image: url("../images/less-sprite.png");
background-repeat: no-repeat;
background-position: 0px -80px;
width: 200px;
height: 80px;
}
加载http://localhost/index.html
以查看前面代码的效果。
最后,应该提到 ClearLess 定义了一些混合来构建网格。这些混合将在下一节中向您解释,因为它们是从Preboot中采用的。
使用 Preboot 的预构建混合来构建您的项目
Preboot 最初是由 Mark Otto (@mdo
)编写的,是一个全面灵活的Less实用工具集。Preboot 是 Twitter 的Bootstrap的前身。Bootstrap 是用于在 Web 上开发响应式、移动优先项目的前端框架。您将在第六章中了解更多关于 Bootstrap 的内容,Bootstrap 3、WordPress 和其他应用。Bootstrap 改进了原始的 Preboot 代码。最后,Bootstrap 中的许多Less变量和混合改进被带回到了 Preboot 2 中。
Preboot 带有混合来构建网格系统,因为它与 Bootstrap 有关。这个网格系统创建一个包含 12 列的行。在浏览器中打开从下载的代码包中的http://localhost/prebootgrid.html
,以查看一个包含两行的示例。第一行网格包含三列,第二行包含两列。这个网格默认是响应式的;您可以通过使用示例网格使浏览器窗口变小来看到这一点。如果屏幕宽度小于 768 像素,网格中的列将堆叠在彼此下面,而不是水平排列。以下代码示例只显示了编译后的 CSS,没有响应式类。
使用 Preboot,您可以在Less中编写以下代码:
.col-a-half {
.make-column(6);
}
前面的代码编译成 CSS 如下(它是非响应式的):
.col-a-half {
min-height: 1px;
padding-left: 15px;
padding-right: 15px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
float: left;
width: 50%;
}
在第五章中,将 Less 集成到您自己的项目中,您将找到另一个示例,该示例使用了 Preboot 的网格,并更详细地讨论了其响应性特性。
Preboot 设置了一些变量来定义网格,如下面的代码片段所示:
// Grid
// Used with the grid mixins below
@grid-columns: 12;
@grid-column-padding: 15px; // Left and right inner padding
@grid-float-breakpoint: 768px;
此外,其他值,如基本颜色,已预先定义如下:
// Brand colors
@brand-primary: #428bca;
@brand-success: #5cb85c;
@brand-warning: #f0ad4e;
@brand-danger: #d9534f;
@brand-info: #5bc0de;
事实上,Preboot 不是一个完整的 CSS 框架;另一方面,它不仅仅是一个预构建混合的库。
使用 Less 将其他技术集成到您的项目中
除了预构建的混合,还有一些其他技术可以轻松集成到您的项目中使用Less。
使用图标字体
顾名思义,图标字体是作为字体定义的一组图标。图标字体可以替换项目中的图像图标。使用图标字体而不是图像的主要原因,以及它们在这里讨论的原因是,就像任何普通字体一样,图标字体可以完全通过 CSS 进行操作。在您的项目中,您可以使用Less设置所使用的图标字体的大小、颜色和阴影。使用图标字体的主要原因是为了提高网站的加载时间;只需要一个 HTTP 请求就可以加载它们。图标字体在不同的分辨率和显示器上看起来也很好。
在本书中,图标字体已经在第三章中使用过,嵌套规则、操作和内置函数。这些示例中使用了 CDN 加载 Font Awesome。Font Awesome 还在 GitHub 上提供了一组Less文件,网址为github.com/FortAwesome/Font-Awesome/tree/master/less
。您可以通过以下步骤使用这些文件在项目中集成 Font Awesome:
-
将
font-awesome/
目录复制到您的项目中。 -
打开项目的
font-awesome/less/variables.less
文件,并编辑@fa-font-path
变量,将其指向字体目录,@fa-font-path: "../font";
。 -
在您的主Less文件中导入 Font Awesome 的Less文件,
@import "font-awesome-4.0.3/less/font-awesome.less";
。
执行前面的步骤后,您可以在 HTML 文档中使用以下代码片段:
<ul class="fa-ul">
<li><i class="fa-li fa fa-check-square"></i>List icons (like these)</li>
<li><i class="fa-li fa fa-check-square"></i>can be used</li>
<li><i class="fa-li fa fa-spinner fa-spin"></i>to replace</li>
<li><i class="fa-li fa fa-square"></i>default bullets in lists</li>
</ul>
在您的网络浏览器中打开前面的代码将得到以下截图:
具有 Font Awesome 项目的 HTML 列表
您将在可下载文件的less/font-awsome.less
中找到前面 HTML 列表的Less代码。请检查此文件。您将看到您无需更改 Font Awesome 的原始文件来设置@fa-font-path
。@fa-font-path
变量将通过重新声明进行设置,并使用上一次声明获胜的规则,如前面在第二章中所解释的,使用变量和 mixin。
您可以通过访问fontawesome.io/examples/
找到更多 Font Awesome 用法的例子。
此外,其他图标字体,如 Bootstrap 的 Glyphicons,也可以与Less一起使用(请参阅github.com/twbs/bootstrap/blob/master/less/glyphicons.less
)。但是,在找不到Less文件的图标字体的情况下,您现在已经有足够的知识来自己创建所需的Less代码。
尝试编写所需的Less代码,将 Meteocons (www.alessioatzeni.com/meteocons/
)集成到您的项目中作为练习,或执行以下步骤:
-
首先从
www.alessioatzeni.com/meteocons/res/download/meteocons-font.zip
下载字体。 -
在这个压缩文件中,您将找到四个文件:
meteocons-webfont.eot
,meteocons-webfont.svg
,meteocons-webfont.ttf
和meteocons-webfont.woff
。这些是在不同浏览器中显示 Meteocons 所需的不同格式。 -
将这些文件复制到您项目的
fonts/
文件夹中。您还将找到包含这些字体文件的stylesheet.css
。此文件包含 Meteocons 的@fontface
样式。如果您检查 Font Awesome 的Less文件,您将找到相同类型的样式。在您的项目中使用字体,需要@fontface
声明。
现在,您应该记住 Less Hat 预构建的 mixin。Less Hat 具有 fontface mixin,.font-face(@fontname, @fontfile, @fontweight:normal, @fontstyle:normal)
。
使用此 fontface mixin,您可以将以下代码添加到您的Less代码中:
#lesshat {@import "lesshat/lesshat.less";}
@font-face {
#lesshat > .font-face("Meteocons", "../fonts/meteocons-webfont");
}
[data-icon]:before {
font-family: 'Meteocons';
content: attr(data-icon);
}
前面的代码将编译为以下 CSS:
@font-face {
font-family: "Meteocons";
src: url("../fonts/meteocons-webfont.eot");
src: url("../fonts/meteocons-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/meteocons-webfont.woff") format("woff"), url("../fonts/meteocons-webfont.ttf") format("truetype"), url("../fonts/meteocons-webfont.svg#Meteocons") format("svg");
font-weight: normal;
font-style: normal;
}
[data-icon]:before {
font-family: 'Meteocons';
content: attr(data-icon);
}
前面的 CSS 代码使您可以使用以下 HTML 代码:
<a href="" data-icon="A">Link</a>
在 HTML 中的前面代码将如下截图所示:
使用 Meteocon 的超链接
之前,您已经看到了如何通过类名添加 Font Awesome 图标。要将此功能添加到 Meteocons,您将需要编写一些Less代码。以下图表显示了该字体的每个图标的字母:
气象字体
现在,根据以下方式为每个图标在您的Less代码中添加一个类声明:
. meteocons-sun { &:before { content: "\2a"; } }
在前面的示例中,.meteocons-sun
是您的类名,\2a
表示类似字符的十六进制值。 2A 十六进制是 42 十进制,*
(星号)的 ASCII 值为 42。您还可以使用八进制或十进制(对于前 128 个可打印字符)。有时,unicode 的\u
会被添加,例如在前面的代码中的\u002a
。
如果您添加这些类声明,您的列表将如下代码片段所示:
.mc-light-sunrise:before {
content: "\0041";
}
.mc-light-sunshine:before {
content: "\0042";
}
.mc-light-moon:before {
content: "\0043";
}
.mc-light-eclipse:before {
content: "\0044";
}
and so on
现在,您已经掌握了图标字体的基础知识,并且可以扩展您的代码。例如,添加以下代码以设置字体的大小:
.mc-2x { font-size: 2em; }
.mc-3x { font-size: 3em; }
.mc-4x { font-size: 4em; }
.mc-5x { font-size: 5em; }
在本章的下载部分,您将找到完整的Less代码,以便像 Font Awesome 一样在less/meteocons
中使用 Meteocons。正如您所看到的,大部分 Font Awesome 的代码可以被重用。请访问http://localhost/indexmeteo.html
以了解如何使用此代码。
Retina.js
高密度设备的每英寸或每厘米像素比普通显示屏多。苹果为其双倍密度显示屏引入了Retina一词。如果您放大图像(或将其放大),它将变得模糊。这是网页设计师在为高密度设备设计时必须解决的问题。您可能想知道这与Less有什么关系。 CSS 结合媒体查询(您将在第五章中了解更多关于媒体查询的信息,将 Less 集成到您自己的项目中),可以防止您的图像在高密度显示屏上变得模糊。
要理解发生了什么,您必须意识到 CSS 像素实际上是设备独立的。CSS 像素用于在浏览器中给元素赋予物理尺寸。在普通屏幕上,一个 CSS 像素匹配一个设备像素。高密度显示屏比 CSS 像素有更多的设备像素;在 Retina 的情况下,它们的像素数量是 CSS 像素的四倍。更多和更小的像素使人眼无法看到单个像素,并且应该提供更好的用户体验。
Retina 显示屏上的图像宽度为 300 个 CSS 像素,需要 600 个设备像素才能保持相同的物理尺寸。现在,您可以通过使用更高分辨率(CSS 像素)的位图,并通过 HTML 或 CSS 进行缩小,来防止图像模糊。
在普通显示屏上,您的 HTML 将如下所示:
<img src="img/photo300x300.png" width="300px" height="300px">
在 Retina 显示屏上,您将使用以下代码片段显示相同的图像:
<img src="img/photo600x600.png" width="300px" height="300px">
目前,有一个惯例,即在高密度图像的名称中添加@2x
,例如example@2x.png
。
您现在应该明白,您可以使用Less编写高效的代码,为这些不同的图像提供正确的 CSS 尺寸。retina.js
库(github.com/imulus/retinajs
)帮助您处理高密度图像和显示屏;它结合了 JavaScript 和Less来编写您的 Retina 代码。
对于普通图像,您必须使用以下代码片段:
<img src="img/my_image.png" data-at2x="http://example.com/my_image@2x.png" />
前面的代码将由 JavaScript 处理,但您将需要使用Less来设置背景图像。这里,背景不仅指页面背景,还指由 CSS 设置的每个背景。大多数现代设计都使用背景图像进行布局;此外,辅助功能规则要求由 CSS 设置装饰性图像。
使用retina.js
,您可以在Less中编写以下代码:
.logo {
.at2x('/images/my_image.png', 200px, 100px);
}
前面的代码将编译为以下 CSS:
.logo {
background-image: url('/images/my_image.png');
}
@media all and (-webkit-min-device-pixel-ratio: 1.5) {
.logo {
background-image: url('/images/my_image@2x.png');
background-size: 200px 100px;
}
}
此外,之前提到的其他预构建 mixin 库将具有用于设置 Retina 背景的 mixin。
总结
在本章中,您已经学会了如何保持代码清晰,并使用样式指南进行测试。您已经学会了如何使用具有预构建 mixin 的库,这有助于更快、更安全地开发您的Less代码。最后但同样重要的是,您已经学会了如何使用Less和图标字体,并使您的项目准备好 Retina。
在下一章中,您将学习如何在您的项目中集成Less,或者如何从头开始使用Less开始一个项目。您还将学习如何组织项目文件并重用旧的 CSS 代码。最后,您将使用媒体查询构建一个响应式网格。
第五章:将 Less 集成到你自己的项目中
现在是时候将Less集成到你的工作流程和项目中了。在本章中,你将学会迁移你当前的项目或从头开始使用Less。将讨论将你的 CSS 代码转换为Less代码的技术和工具,最后,你将学会使用Less构建和使用响应式网格。
本章将涵盖以下主题:
-
将 CSS 导入到Less中
-
将你的项目迁移到Less
-
从头开始一个项目
-
媒体查询和响应式设计
-
在你的项目和设计中使用网格
在使用Less并看到它如何解决重复代码和无法重用 CSS 的问题时,你可能会想知道何时开始在项目中使用Less。尽管这可能是本书中最重要的问题,答案却很简单。你将不得不立刻开始!CSS 的问题可能是你设计过程中的一些缺陷。一旦检测到缺陷,就没有理由不立即解决它们。如果你现在不开始,你可能永远不会开始,最终你将花费太多时间调试你的 CSS 代码,而不是在真正的设计任务上工作。
将 CSS 导入到 Less 中
正如你现在已经知道的那样,有效的 CSS 也是有效的Less代码。CSS 代码可以被导入到Less中。有不同的方法来做到这一点。在导入你的 CSS 之后,你可以通过编译器运行结果。这为你提供了一个在当前项目中开始使用Less的简单方法。
在开始导入你的 CSS 代码之前,考虑创建一个样式指南。样式指南有助于测试你的代码,如第四章中所述,避免重复造轮子。还要记住,Less是一个CSS 预处理器。这意味着你必须在将Less代码投入生产之前将其编译成 CSS。客户端编译只应用于测试目的!只是导入你的 CSS 并将其重新编译成 CSS 是没有意义的。导入 CSS 还提供了将现有 CSS 与新编写的Less代码结合以及逐步进行Less转换的机会。
使用@import 规则
之前,你已经看到Less中的@import
规则用于将Less文件导入到你的项目中。Less中的这个规则是 CSS 中相同规则的扩展版本。
在之前章节的示例中,@import
规则只用于导入Less文件。默认情况下,每个文件只被导入一次。完整的语法如下:
@import (keyword) "filename";
有六个关键字可以与这个规则一起使用:reference
,inline
,less
,css
,once
和multiple
。例如,@import (reference) "file.less"
中的reference
关键字将使file.less
中的 mixin 和类可用,而不会将它们编译到生成的 CSS 中。
这可以很容易地通过一个例子来展示。你可以从 Packt 网站(www.packtpub.com)下载本书所有章节的示例代码。之前章节的示例布局将在这里再次使用。请记住,这个项目的主文件styles.less
导入了其他项目文件。现在你可以使用它来重用导航栏。首先创建一个新文件,并将以下代码写入其中:
@import (reference) "styles";
.nav:extend(.nav all){};
这两行将编译成以下代码:
.nav {
list-style: none outside none;
padding: 0;
}
.nav li a {
text-decoration: none;
color: #000000;
width: 100%;
display: block;
padding: 10px 0 10px 10px;
border: 1px solid #004d00;
margin-top: -1px;
}
.nav li a:hover {
color: #ffffff;
background-color: #004d00;
}
.nav li.active a {
color: #000000;
background-color: #00b300;
}
.nav li:first-child a {
border-radius: 15px 15px 0 0;
}
.nav li:last-child a {
border-radius: 0 0 15px 15px;
}
还要注意,前面的结果包含了原始项目中variables.less
中定义的值。
inline
关键字用于导入与Less不兼容的代码。虽然Less接受标准 CSS,但有时注释和 hack 不会被编译。使用inline
关键字将 CSS 按原样导入输出。如下面的代码所示,inline
关键字与css
关键字有很大的不同。less
关键字强制导入的代码被编译。使用@import (less) "styles.css"
时,所有代码将像往常一样被编译。与此同时,css
关键字强制@import
作为普通的 CSS 导入。下面的代码显示了inline
和css
之间的区别:
@import (css) "styles.css";
上述代码的输出如下:
@import "styles.css";
在编译的 CSS 代码中,使用@import
导入的样式表在所有其他规则之前声明。这些样式表可以在CSS 优先级中发挥作用,这在第一章中有所讨论,使用 Less 改进 Web 开发。因此,您不能应用高级技术,如命名空间,应该在开始时导入未使用Less创建的文件。
CSS 2.1 用户代理必须忽略任何出现在块内或在任何非忽略语句之后的@import
规则,除了@charset
或@import
(www.w3.org/TR/CSS21/syndata.html#at-rules
)。如果导入具有相同名称的文件两次,默认只会编译一个。如果使用once
关键字,也会发生相同的情况;另一方面,如果使用multiple
关键字,文件将在输出中被编译两次。下面的代码将为您演示使用multiple
关键字时的多重输出的示例:
如果styles.less
文件包含以下代码:
p {
color: red;
}
您的Less代码如下:
@import (multiple) "style";
@import (multiple) "style";
上述代码将输出以下 CSS 代码:
p {
color: red;
}
p {
color: red;
}
迁移您的项目
使用不同的导入规则,您可以在项目中开始使用 Less 而无需更改代码。导入 CSS 后,您可以逐步开始定义变量和使用混合。在开始将其用于生产之前,始终检查新代码的输出。
提示
请记住,样式指南可以帮助您管理项目的迁移,也不要忘记在生产环境中使用Less之前,在服务器端将其编译为 CSS 代码。
组织您的文件
尝试以与前面示例相同的方式组织您的文件。为项目的变量和混合创建单独的文件。如果您的项目之前在project.css
中定义了样式表,您的主Less文件可能如下所示:
@import "reset.less";
@import "variables.less";
@import "mixins.less";
@import (less) "project.css";
在上述代码中,您将导入原始的project.css
;或者,您可以将其重命名为project.less
。还要注意,您最终将编译一个新的 CSS 文件,该文件将用于您的项目。可以使用相同的名称来命名此文件;确保不要覆盖原始的 CSS 文件。虽然新的 CSS 文件应用相同的样式,但这些文件更有组织性,Less保证它们只包含有效的 CSS。编译器还将压缩 CSS 文件。
将 CSS 代码转换为 Less 代码
在迁移过程中,您可能更喜欢不必一步一步地转换代码。有一些可用的工具可以将 CSS 代码转换为Less代码。这些工具应该谨慎使用。Lessify可以帮助您将 CSS 代码组织成Less代码。Lessify 将相同元素或类的规则放在一起。您可以通过访问leafo.net/lessphp/lessify/
来使用 Lessify。
考虑以下 CSS 代码:
p {
color: blue;
}
p a {
font-size:2em;
}
p a:hover {
text-decoration: none;
}
使用 Lessify 后,前面的 CSS 代码编译成以下Less代码:
p {
color:blue;
a {
font-size:2em;
}
a:hover {
text-decoration:none;
}
}
你可以在css2less.cc/
找到另一个工具叫做 CSS2Less。此外,这个工具只会分组类和元素规则。Lessify 和 Css2Less 在组织你的样式时可能会有所帮助。这两个工具都不支持媒体查询。
从迄今为止学到的所有知识来看,通过开发你的Less代码来开始项目似乎是一个不错的做法。因此,通过使用Less构建样式指南来开始你的项目。
你的project.less
文件可能如下所示:
@import "reset.less";
@import "variables.less";
@import "mixins.less";
将project.less
文件与客户端less.js
编译器集成到你的样式指南中。之后,开始添加你的设计元素,或者在你的代码中添加注释。
当你完成了你的样式指南,你可以开始构建最终的 HTML 代码。如果你要构建一个响应式网站,你应该首先确定你将需要哪些屏幕尺寸。例如,移动设备、平板和台式机可能是一个不错的选择。
为了更好地理解在流程的这个阶段如何使用Less,以下两个部分描述了CSS 媒体查询在响应式设计中的作用,并教你如何使用网格。
媒体查询和响应式设计
媒体查询是 CSS3 模块,自 2012 年 6 月以来一直是 W3C 的候选推荐。媒体查询增加了在媒体查询评估为 true 时仅将样式表应用于 CSS 的可能性。媒体查询评估设备的类型和设备的特性。设备的类型有屏幕、语音和打印等,特性有宽度、设备宽度和分辨率等。
如今,屏幕类型和设备宽度在响应式网页设计中扮演着重要的角色。通过使用媒体查询,可以将 CSS 规则限制在指定的屏幕宽度上,从而根据不同的屏幕分辨率改变网站的呈现方式。
一个典型的媒体查询看起来像下面的代码行:
@media { ... }
例如,以下媒体查询在视口宽度大于 767 像素时将字体颜色设置为黑色:
@media screen and (min-width: 768px) {
color:black;
//add other style rules here
}
在上述代码中,我们可以看到花括号之间的所有样式规则只有在屏幕宽度大于 768 像素时才会应用。这些样式规则将遵循正常的级联规则。
使你的布局流动
到目前为止,你的布局一直由@basic-width
定义的固定宽度。流动设计将其宽度定义为视口或浏览器窗口宽度的百分比。
为了使你的布局流动,定义@basic-width: 900px;
在less/responsive/project.less
中。这个设定值不再定义你设计的宽度,而是在你的改变后只设置max-width
变量。
之后,打开.center-content()
mixin 中的less/responsive/mixinsresponsive.less
,将width:@basic-width;
改为max-width:@basic-width;
。
页眉现在是流动的,无需进一步更改。页脚列也是基于@basic-width
的,所以你也需要对它们进行更改。
页脚列的宽度由以下代码设置:
width: ((@basic-width/3)-@footer-gutter);
请使用以下代码在less/responsive/footer.less
中更改页脚列的宽度:
width: ~"calc((1/3 * 100%) - @{footer-gutter})";
可以通过访问caniuse.com/#feat=calc
来检查calc()
函数的浏览器支持情况。还要记住第一章中关于calc()
和字符串插值的说明,使用 Less 改进 Web 开发。Less代码是无状态的,因此这些宽度计算应该由浏览器中的 CSS 完成。一旦 CSS 加载完成,浏览器就有了真实的像素宽度,因此浏览器可以计算并呈现列的宽度。
最后,你将需要改变less/contentresponsive.less
并在其中添加媒体查询。如果屏幕宽度小于 500 像素,导航和内容应该在你的布局中堆叠。
首先,通过将宽度设置为width: 2 / 3 * 100%;
和width: 1/ 3 * 100%;
,使#content
和#sidebar
变为流体。现在,宽度是流体的,您可以添加媒体查询。对于#content
,您应该将代码更改为以下代码:
width: 2 / 3 * 100%;
float:left;
@media (max-width:500px) {
width:100%;
float:none;
}
前面的代码如果屏幕宽度小于 500 像素,则将#content
的宽度设置为100%
。它还会删除元素的浮动。您应该对#sidebar
做同样的操作。
进行这些更改后,屏幕宽度为 500 像素时,导航将堆叠在内容下方。
如何在屏幕宽度小于 500 像素的屏幕上交换导航和内容的位置,可以在http://localhost/indexresponsivechange.html
中看到。您可以通过两个步骤完成这个过程。首先,在 HTML 文档中交换#content
和#sidebar
的内容。打开http://localhost/indexresponsivechange.html
,并将源代码与http://localhost/indexresponsive.html
进行比较。进行这些更改后,侧边栏将显示在屏幕的左侧。要将侧边栏移动到右侧,您应该将其浮动设置为right
而不是left
,如下面的代码所示:
//one third of @basic-width
#sidebar {
width: 1 / 3 * 100%;
float:right;
@media (max-width:500px) {
width:100%;
float:none;
}
}
在小屏幕上,布局现在看起来像以下的截图:
在手机上您的布局可能会是这样的一个例子
在手机上测试您的布局
您肯定也会在手机上检查响应式布局。确保在 HTML 文档的头部添加以下额外的代码行:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
前面的代码强制移动浏览器在视口中加载您的网站,该视口等于设备的屏幕宽度。默认情况下,移动浏览器会在比屏幕尺寸更大的视口中加载网站。这样做可以让非移动网站在大屏幕上按预期加载。加载网站后,用户可以滚动和放大结果。如果您优化的移动布局在宽度大于 500 像素的视口中加载,媒体查询将无法工作,强制视口调整为设备的屏幕尺寸,从而防止媒体查询不被应用。请注意,这也意味着您将不得不使用屏幕宽度不超过 500 像素的手机测试此示例。您还可以在www.responsinator.com/
等网站上测试您的设计。
首先为移动设备编码
如今,先为移动设备编写样式,然后使用媒体查询来调整它们以适应更大的屏幕是很常见的。您可以在示例布局的文件header.less
和content.less
中找到编码的移动设备优先原则的示例。还可以打开less/responsive/footer.less
,看看媒体查询如何添加浮动:
@media (min-width:501px) {
float: left;
width: ((@basic-width/3)-@footer-gutter);
}
这个例子展示了一种移动设备优先的编码方式。元素默认堆叠,并在屏幕尺寸增大时变为水平。请注意,诸如 Internet Explorer 8 之类的旧版浏览器不支持媒体查询,并且始终会显示堆叠版本。
在您的设计和工作流程中使用网格
前面的媒体查询示例没有使用网格。您可能想知道什么是网格,以及为什么应该使用它。基于网格的布局将设计分成一系列大小相等的列和行。内容和图形元素可以根据此布局进行组织。网格有助于为设计创建逻辑和正式的结构。它可以防止原始设计与 HTML 中最终实现之间的不一致,因为设计师和开发人员使用相同的网格。
网格在响应式设计中也很有帮助,因为网格的列可以轻松重新排列以适应不同的屏幕宽度。
在本书的初步章节中,您已经了解了定义布局结构的 CSS 模块。Flex boxes 和 columns 可以用来定义 CSS 布局和网格。尽管这些布局默认情况下是响应式的,或者可以很容易地定义为响应式,但它们还不是定义 CSS 布局的常用方式。如前所述,大多数现代浏览器尚未准备支持这些模块。幸运的是,有其他方法可以使用 CSS 定义网格。
网格的列宽可以定义为网格的百分比或固定宽度。流体网格将其宽度定义为视口的百分比。在流体网格中,列宽随屏幕宽度变化。流体布局可以重新排列内容以占用可用的屏幕宽度,因此用户需要滚动的次数更少。另一方面,设计师对设计的精确表示没有太多控制。因此,大多数响应式网格是流体和固定网格的混合体。
网格中 CSS 浮动的作用
CSS 的float
属性是 CSS 中的一个位置属性;浮动将元素推到屏幕的左侧(或右侧),并允许其他元素围绕它包裹。因此,CSS 的float
在大多数CSS 网格中起着重要作用。
一个示例将帮助您了解这是如何工作的。您将创建一个具有两列的网格。开始编写固定网格的Less代码。示例如下:
@grid-container-width: 940px;
@column-number: 2;
.container {
width: @grid-container-width;
.row {
.col {
float: left;
width: (@grid-container-width/@column-number);
}
.col2{
width: 100%;
}
}
}
您可以使用上述代码的编译 CSS 和以下 HTML 代码:
<div class="container">
<div class="row">
<div class="col">Column 1</div>
<div class="col">Column 2</div>
</div>
<div class="row">
<div class="col2">Column 3</div>
</div>
</div>
您可以通过访问本书可下载示例代码中的http://localhost/grid.html
来检查上述代码的结果。
现在,您有一个固定网格的示例。通过使用以下Less代码更改固定宽度,可以使此网格成为流体网格:
@grid-container-width: 100%;
在这个网格中,.container
类包含网格。此容器包含了使用.row
类定义的行。您只需要定义两个额外的类,因为此网格有两列。第一个类.col
定义了单列,第二个类.col2
定义了双列。
使您的网格具有响应性
要使网格具有响应性,您必须定义一个或多个断点。断点定义了网站响应以提供合适布局的屏幕宽度;在断点以下或以上,网格可以提供不同的布局。在示例网格中,您可以描述两种情况。在第一种情况下,在断点以下(例如 768 像素),屏幕很小。在小屏幕上(记住手机屏幕),网格的列应该堆叠。在断点以上,对于平板电脑和台式机屏幕,网格应该变为水平,网格行的列将浮动在一起。
在Less中,您可以使用以下代码为小屏幕编写第一种情况:
.container {
width: @grid-container-width;
.row {
.col, .col2 {
width: 100%;
}
}
}
所有列都占视口的100%
宽度,没有一个浮动。从最小的屏幕开始编写代码将生成“移动优先”网格。移动优先设计从小屏幕(和移动浏览器)开始,为大屏幕重新排列和添加内容。您已经看到网格在较大屏幕上变为水平。其他示例可能是导航,它有另一种表示,或者图像滑块,它只对桌面用户可见。
现在尝试通过添加媒体查询并在Less中定义断点来使您的网格具有响应性,如下所示:
@break-point: 768px;
.container {
width: @grid-container-width;
.row {
.col, .col2 {
width: 100%;
}
@media(min-width: @break-point) {
.col {
float: left;
width: (@grid-container-width/@column-number);
}
}
}
}
编译为 CSS 代码的上述代码将如下所示:
.container {
width: 100%;
}
.container .row .col,
.container .row .col2 {
width: 100%;
}
@media (min-width: 768px) {
.container .row .col {
float: left;
width: 50%;
}
}
很容易看到现在.row
类只在宽度大于 768 像素的屏幕上浮动。如果屏幕尺寸小于 786 像素,宽度列将堆叠。
清除浮动的作用
在上面的示例中,列通过应用float:left
而变为水平。clearfix()
混合在元素渲染后清除元素的浮动,无需额外的标记,因此可以用于网格的.row
类。使用这些清除可以保证您的元素只在自己的行中浮动。
使用更具语义性的策略
在前一节中,您使用div
元素和 CSS 类构建了一个网格。许多 CSS 框架,如Twitter 的 Bootstrap和ZURB Foundation,都是以这种方式构建它们的网格。批评者声称这种方法破坏了 HTML5 的语义性质。因此,他们有时甚至将其与使用 HTML 表定义布局的老式方法进行比较。HTML5 引入了语义标签,不仅描述结构,还描述文档的含义。例如,header
标签是语义的;每个人都知道头部是什么,浏览器知道如何显示它们。
使用混合而不是类可以帮助您使您的网格更具语义。
这样的混合示例是以下Less代码:
.make-columns(@number) {
width: 100%;
@media(min-width: @break-point) {
float: left;
width: (@grid-container-width* ( @number / @grid-columns ));
}
}
上述代码可以使用以下Less代码进行编译:
/* variables */
@grid-columns: 12;
@grid-container-width: 800px;
@break-point: 768px;
header,footer,nav{.make-columns(12);}
main{.make-columns(8);}
aside{.make-columns(4);}
上述 CSS 代码的 HTML 将如下所示:
<header role="banner"></header>
<nav role="navigation"></nav>
<main role="main">
<section></section>
</main>
<aside role="complementary"></aside>
<footer role="contentinfo"></footer>
请注意,在上述代码中,@number
设置总宽度为@number
乘以列宽度,并且上述网格中的列总数将固定为12
。
使用网格类构建您的布局
.make-columns()
混合也可以用于创建您的网格类,如下面的代码所示:
.make-grid-classes(@number) when (@number>0) {
.make-grid-classes(@number - 1);
.col-@{number} {
.make-columns(@number);
}
}
.make-grid-classes(12);
上述代码将编译为以下 CSS 代码:
.col-1 {
width: 100%;
}
@media (min-width: 768px) {
.col-1 {
float: left;
width: 66.66666666666666px;
}
}
.col-2 {
width: 100%;
}
@media (min-width: 768px) {
.col-2 {
float: left;
width: 133.33333333333331px;
}
}
…
.col-12 {
width: 100%;
}
@media (min-width: 768px) {
.col-12 {
float: left;
width: 800px;
}
}
在上述代码中,使用混合来构建网格类是递归调用的。请回顾第三章中已经看到如何使用保护和递归构建循环。
构建嵌套网格
如果将@grid-container-width
设置为100%
并使您的网格流动,.make-columns()
混合也可以用于构建嵌套网格。
访问http://localhost/nestedgrid.html
以查看此类嵌套网格的示例。
在 HTML 中,您可以编写以下代码来创建一个带有标题、内容部分、侧边栏和页脚的页面:
<div class="container">
<header role="banner">header</header>
<section id="content" role="content">
<div class="content-column">Column 1</div>
<div class="content-column">Column 2</div>
<div class="content-column">Column 3</div>
</section>
<aside role="complementary">sidebar</aside>
<footer role="contentinfo">footer</footer>
</div>
内容部分将分为三个相等大小的列。要实现上述代码,您可以在Less中编写以下代码:
.make-columns(@number) {
width: 100%;
@media(min-width: @break-point) {
float: left;
width: (@grid-container-width* ( @number / @grid-columns ));
}
}
/* variables */
@grid-columns: 12;
@grid-container-width: 100%;
@break-point: 768px;
header,footer{.make-columns(12);}
section#content {
.make-columns(8);
div.content-column {
.make-columns(4);
}
}
#sidebar{.make-columns(4);}
在这里,对于div.content-column
的.make-columns(4);
语句将创建33.3%
的宽度(4 / 12 * 100%)。33.3%将根据直接父元素进行计算。在这个例子中,div.content-column
的直接父元素是section#content
。section#content
HTML 元素本身将占视口的66.6%
的宽度(*8 / 12 100%)。
提示
请注意,如果您在项目中使用上述网格,应将代码分成不同的文件。如果为变量和混合创建不同的文件,您的代码将清晰而干净。
替代网格
在前面的示例中,您已经看到了随着屏幕尺寸增加而变为水平的列定义的网格。这些网格使用 CSS 浮动来将列对齐在一起。在某些情况下,主要是对于旧版本的浏览器,这可能会导致像素计算方面的一些问题。这个问题有时被描述为“亚像素舍入”问题。尽管box-sizing: border-box;
可以解决相关问题,如第一章中所述,使用 Less 改进 Web 开发,但可以选择使用不同的网格定义。
CSS 隔离提供了一个解决方案。CSS 隔离并不容易理解。Susy (susydocs.oddbird.net/
)将其描述如下:
每个浮动都相对于其容器定位,而不是前面的浮动。这有点像一个黑客,会将内容从流中移除,所以我不建议在孤立的浮动上构建整个布局,但在舍入错误真的让你头疼时,它可能非常有用。
CSS 隔离最初是 Zen Grids (zengrids.com/
)的一部分。Zen Grid 的实现是用 SCSS/SASS 编写的。将其重写为Less将相对容易;你可以尝试这个作为练习。如果你想尝试这个栅格系统,你也可以从github.com/bassjobsen/LESS-Zen-Grid
下载一些示例Less代码。
使用响应式栅格构建你的项目
在前面的示例中,只定义了栅格列。这应该给你一个很好和现实的印象,栅格是如何工作以及如何使用它们的。完整的栅格代码还定义了响应式容器和行类。大多数栅格还会在列之间有所谓的间距。间距(通常是固定的)是分隔列的空间。这也意味着跨越两列的宽度包括一个间距。
在第四章避免重复造轮子中,你已经学会了重用Less和预构建的 mixin;你也可以对栅格做同样的事情。你不需要自己编写完整的代码。Twitter 的 Bootstrap、Golden Grid System (goldengridsystem.com/
)或 Less Framework 4 (lessframework.com/
)等框架将为你提供所需的所有Less代码和 mixin。这些框架中的一些将在第六章Bootstrap3、WordPress 和其他应用中进一步讨论。
以下示例将使用 Preboot 的栅格 mixin 来构建项目的栅格。最后,你将重新构建之前使用的布局示例。
使用 Preboot 的栅格系统
Preboot 的栅格系统使你能够使用少量变量和 mixin 构建移动优先的栅格布局。正如你之前看到的,你可以使用 Preboot 的 mixin 来创建语义化的栅格或定义更一般的栅格类。
Preboot 定义了栅格的变量,如下所示:
@grid-columns: 12;
@grid-column-padding: 15px;
@grid-float-breakpoint: 768px;
在前面的代码片段中,@grid-column-padding
定义了栅格的间距宽度,正如前面提到的。栅格列采用了移动优先的方法进行编码。这意味着默认情况下,它们在视口宽度等于或大于@grid-float-breakpoint
时会垂直堆叠并水平浮动。当然,不要忘记@grid-columns
设置了栅格列的数量。
Preboot 没有提供包含栅格行的容器。你可以自己定义这个变量,以定义你的栅格的最大宽度,如下面的代码所示:
@grid-width: 960px;
每个标准栅格系统的部分都有三个可用的 mixin,分别是:
-
.make-row()
: 为列提供一个包装器,通过负边距对齐它们的内容并清除浮动 -
grid.make-column(n)
: 用于生成n
个栅格列,作为可用栅格列的百分比(默认设置为12
) -
.make-column-offset(n)
: 通过边距将列向右推n
列
现在你可以使用前面的变量和 mixin 与 Preboot 一起制作栅格的可见表示。首先,在 HTML 中定义一些栅格行,如下所示:
<div class="container">
<div class="row">
<div class="col-12"></div>
</div>
<div class="row">
<div class="col-11"></div><div class="col-1"></div>
</div>
<div class="row">
<div class="col-10"></div><div class="col-2"></div>
</div>
<div class="row">
<div class="col-9"></div><div class="col-3"></div>
</div>
<div class="row">
<div class="col-6"></div><div class="col-6"></div>
</div>
<div class="row">
<div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div><div class="col-1"></div>
</div>
</div>
这里使用的栅格包含 12 列,你可以看到每行的列数应该总和为 12。
现在你可以编写前面栅格的Less代码,其中使用了 Preboot 的 mixin 和变量。同样,你可以将代码分成不同的文件,以保持清晰。
project.less
文件包含以下Less代码,将所有所需的文件导入项目:
@import "../normalize.less";
@import "../basics.less";
#preboot { @import (reference) "preboot-master/less/preboot.less"; }
@import "variables.less";
@import "mixins.less";
@import "grid.less";
@import "styles.less";
variables.less 文件包含以下Less代码,定义了项目的变量:
@grid-columns: 12;
@grid-column-padding: 30px;
@grid-float-breakpoint: 768px;
@grid-width: 1200px;
mixins.less
文件包含了项目的 mixin:
.make-grid-classes(@number) when (@number>0) {
.make-grid-classes(@number - 1);
.col-@{number} {
#preboot > .make-column(@number);
}
}
请注意这里使用了#preboot > .make-column(@number);
命名空间。现在循环结构应该对您来说很熟悉了。
grid.less
文件包含了定义网格类的Less代码:
.container {
max-width: @grid-width;
padding: 0 @grid-column-padding;
}
.row {
#preboot > .make-row()
}
& { .make-grid-classes(12); }
上述代码将创建用于您的网格的 CSS 类。请注意,.container
类将用于设置网格的最大宽度。它还设置了填充,这是需要纠正网格周围的槽口的。每行的填充为@grid-column-padding
大小的一半。在两行之间,.containter
类使槽口等于@grid-column-padding
,但现在,网格的左右两侧只有填充,大小为@grid-column-padding
的一半。.row
类通过添加大小为@grid-column-padding
一半的负边距来纠正这一点。最后,容器的填充防止了这个负边距使网格偏离屏幕。
还请注意& { .make-grid-classes(12); }
语句中的和符号。这个和符号(引用)保证了继承的.make-row
mixin 在需要时可见。命名空间 mixin 在全局范围内不可见。这个问题可能在以后的Less版本中得到解决。
最后,styles.less
文件包含了定义样式以使网格列可见的Less代码:
.row [class^="col-"]{
background-color: purple;
height: 40px;
border: 2px solid white;
}
从styles.less
编译的 CSS 只用于使网格列可见。如第一章中所述,使用 Less 改进 Web 开发,[class^="col-"]
是一个CSS 选择器,选择具有以col-
开头的类的网格列。每列都有高度(height
)、背景颜色(background-color
)和边框(border
)。此外,在这里,box-sizing: border-box;
语句确保边框宽度不影响列的宽度。
您可以通过在浏览器中访问http://localhost/prebootgridclasses.html
来查看最终结果。结果将如下图所示:
Preboot 的 12 列网格的表示
当您看到网格的前面的表示时,您可能会想知道槽口在哪里。如前所述,槽口将由列的填充构成。您可以通过在列中添加一些内容来使其可见。因此,请尝试将以下代码添加到您的 HTML 文件中:
<div class="row">
<div class="col-6"><p style="background-color:yellow;">make the gutter visible</p></div>
<div class="col-6"><p style="background-color:yellow;">make the gutter visible</p></div>
</div>
将上述代码添加到 HTML 文件后,结果将如下图所示:
Preboot 的 12 列网格;内容使槽口可见
在前面的图片中,您将看到网格的槽口。还请注意,.col-6
类只在两侧有槽口,因此.col-6
的总内容宽度将是 6 列,包括五个槽口。
使用网格 mixin 来构建语义布局
在前面的部分中,您使用了 Preboot 的网格 mixin 来构建网格类。在本章的最后一节中,您将使用这些 mixin 来构建语义布局。
您可以使用之前使用的相同示例。在开始之前,您应该撤消在媒体查询示例中所做的更改。您在这里不需要这些媒体查询,因为网格默认是响应式的。
注意
您可以通过访问http://localhost/semanticgrid.html
来观看结果,并且您将在/less/semanticgrid/
文件夹中找到此示例的 Less 文件。
在当前示例布局中,容器样式应用于 body 元素。现在似乎没有理由添加额外的div
容器(包装器)。所有现代浏览器都将 body 视为普通的块级元素。如果出于某种原因希望添加额外的包装器,请这样做。例如,出于某种原因添加版权信息到您的布局;当然,body 不允许您在其后添加内容。在这两种情况下,此容器保存网格的行。
打开/less/semanticgrid/project.less
,并将以下Less代码写入其中提到的容器:
body {
max-width: @basic-width;
padding: 0 @grid-column-padding;
margin: 0 auto;
}
请注意,在/less/semanticgrid/variables.less
中,@basic-width
设置为 900 像素,以明确表明网格在 768 像素处具有断点响应。
在此语义示例中,您将使用在/less/semanticgrid/variables.less
中定义的仅三列网格,使用以下代码:
/* grid */
@grid-columns: 3;
@grid-column-padding: 30px;
@grid-float-breakpoint: 768px;
在/less/semanticgrid/project.less
中,您可以看到此示例不使用 Preboot 的命名空间。在撰写本书时,最新版本的Less不支持在全局范围内使用命名空间的变量。在以后的版本中,您可以期望#namespace > @variable
起作用,但目前还不起作用。使用命名空间将使命名空间内的设置(例如@grid-columns
)从全局范围内变得复杂或不可能。
现在,打开/less/semanticgrid/header.less
。在此文件中,您可以删除旧的.centercontent
类。
使用 Preboot 的.make-row()
mixin 使header
标签像一行一样工作,并在其中使用.make-column(3)
mixin 调用h1
。现在,h1
元素将具有三列的宽度。
对/less/semanticgrid/content.less
执行相同操作,但在此处使用.make-column(2)
为内容和.make-column(1)
为侧边栏。
同样,您将看到在移动版本中,导航位于内容下面,就像之前解释的那样。您可以使用在媒体查询示例中看到的相同技巧来解决此问题。在第六章中,Bootstrap3,WordPress 和其他应用程序,您将学习解决此类问题的其他方法。目前,反转 HTML 代码中的侧边栏和内容,以便侧边栏在内容之前。之后,您应该给侧边栏一个float: right
调用,如以下代码所示:
@media (min-width: @grid-float-breakpoint) {
float:right;
}
最后,您需要更改页脚。请再次为footer
标签使用.make-row()
。页脚内的div
元素,即列,将使用.make-column(1)
进行样式设置。完成此操作后,您将看到页脚的列相互挨着,之间没有任何空白。请记住,网格的间距在列的内容之间,而不是在列本身之间。
为了解决前面提到的问题,请在div
元素内部的p
元素上应用background-color
,border-radius
和box-shadow
,如以下代码所示:
div {
.make-column(1);
p {
min-height: @footer-height;
background-color: @footer-dark-color;
//margin: @footer-gutter (@footer-gutter / 2);
.border-radius(15px);
.box-shadow(10px 10px 10px, 70%);
padding: 10px;
}
}
前面的代码将使栅格之间的间距可见,就像之前看到的那样。网格的间距在列之间添加了一些空白。左列的左侧和右列的右侧也会有间距。这将使页脚列的总可见宽度小于页眉。您可以通过在这些侧面将div
的填充设置为0
来去除此间距。再次更改中间列的填充,以再次使三列具有相同的宽度。可以使用以下代码来实现:
div {
&:first-child {
padding-left: 0;
}
&:nth-child(2) {
padding-left: 15px;
padding-right: 15px;
}
&:last-child {
padding-right: 0;
}
}
访问http://localhost/semanticgrid.html
,查看前面代码的最终结果。调整浏览器窗口大小,以确保它确实是响应式的。
扩展您的网格
在前面的例子中,您使用了一个带有一个断点的网格。在断点以下,您的行简单地堆叠。这在许多情况下似乎有效,但有时,也有必要为小屏幕创建一个网格。想象一下,您构建了一个照片库。在大屏幕上,一行中会有四张照片。对于较小的屏幕,照片不应该堆叠,而是一行中显示两张而不是四张。
同样,您可以使用网格类或 mixin 来解决这种情况,以获得更语义化的解决方案。
在这两种情况下,您还应该使您的照片具有响应性。您可以通过为您的图片添加样式来实现这一点。将max-width
设置为100%
,将height
设置为auto
在大多数情况下都可以奏效。max-width
变量可以防止图像显示宽于其原始尺寸,并确保它们在其他情况下获得其父元素宽度的 100%。在小屏幕上,这些图像将获得视口宽度的 100%。
要使您的图像默认具有响应性,您可以将以下代码添加到您项目的Less代码中:
img {
display: block;
height: auto;
max-width: 100%;
}
如果您喜欢通过为源中的每个图像添加一个类来明确地使您的图像具有响应性,您可以使用以下Less代码来创建这样一个类:
.responsive-image {
display: block;
height: auto;
max-width: 100%;
}
为小网格添加网格类
使用网格类时,您必须更改 Preboot 中的原始.make-column
mixin。这个.make-columns()
mixin 设置了列的样式并添加了一个媒体查询。.make-columns()
mixin 中的媒体查询让列在更宽的视口上水平浮动。对于新的小网格,您不需要媒体查询,因为列根本不应该堆叠。
为了实现这一点,您可以将 mixin 拆分为两个新的 mixin,如下面的代码所示:
.make-columns(@columns) {
// Prevent columns from collapsing when empty
min-height: 1px;
// Set inner padding as gutters instead of margin
padding-left: @grid-column-padding;
padding-right: @grid-column-padding;
// Proper box-model (padding doesn't add to width)
.box-sizing(border-box);
}
.float-columns(@columns) {
float: left;
// Calculate width based on number of columns available
width: percentage(@columns / @grid-columns);
}
编写了前面的 mixin 之后,您还应该创建两个 mixin,这两个 mixin 会循环创建您的网格类。
第一个 mixin 应该如下代码所示:
.make-grid-columns(@number) when (@number>0) {
.make-grid-columns(@number - 1);
.col-small-@{number},.col-large-@{number} {
.make-columns(@number)
}
}
前面的 mixin 将通过grid.less
中的.make-grid-columns(12);
语句调用。这些 mixin 将编译成以下代码:
.col-small-1,
.col-large-1 {
min-height: 1px;
padding-left: 30px;
padding-right: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.col-small-2,
.col-large-2 {
min-height: 1px;
padding-left: 30px;
padding-right: 30px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
在这之后,您可以很容易地看到前面的代码可以优化为以下代码:
div[class~="col"] {
// Prevent columns from collapsing when empty
min-height: 1px;
// Set inner padding as gutters instead of margin
padding-left: @grid-column-padding;
padding-right: @grid-column-padding;
// Proper box-model (padding doesn't add to width)
.box-sizing(border-box);
}
第二个 mixin 将如下代码所示:
.float-grid-columns(@number; @grid-size: large;) when (@number>0) {
.float-grid-columns(@number - 1,@grid-size);
.col-@{grid-size}-@{number} {
.float-columns(@number)
}
}
前面的 mixin 将通过以下代码在grid.less
中调用:
.float-grid-columns(12,small);
@media (min-width: @grid-float-breakpoint) {
.float-grid-columns(12);
}
前面的代码将创建两组网格类。大网格类只有在媒体查询为真时才会应用。您可能会想为什么不能在一个单独的循环中创建这些网格类。这是因为最后的声明获胜规则;您应该在小网格类之后定义所有的大网格类。例如,如果col-large-2
在col-small-3
之前定义,您就不能使用<div class="col-small-3 col-large-2">
,因为col-small-3
会覆盖col-large-2
的样式。
在创建了前面描述的 mixin 之后,您可以按照以下方式编写您的 HTML 代码:
<div class="row">
<div class="col-small-6 col-large-3"></div>
<div class="col-small-6 col-large-3"></div>
<div class="col-small-6 col-large-3"></div>
<div class="col-small-6 col-large-3"></div>
</div>
前面的代码将在您的屏幕上显示四列。这些列宽度大于 768 像素。该代码还将在较小的屏幕上显示两列。您可以通过访问http://localhost/prebootgridclassesextend.html
来查看这个例子。
在您的语义化代码中应用小网格
如果您选择了语义化的方式来构建您的网格,下面的例子将帮助您在之前构建的布局的页脚中添加一个小网格。您可以在这个例子中再次使用/less/semanticgrid/content.less
中的文件。
布局在 768 像素处有一个断点。在这个断点以下,即在小屏幕上,页脚应该有三列,在大屏幕上,页脚列应该堆叠。
您可以重用本章前面使用的 Preboot mixin 来构建一个响应式网格,以创建如前所述的页脚列。首先,将 mixin 拆分为两个新的 mixin:一个用于浮动,一个用于样式化列,如下面的代码所示:
.less-make-column(@columns) {
float: left;
// Calculate width based on number of columns available
width: percentage(@columns / @grid-columns);
}
.iscolumn()
{
// Prevent columns from collapsing when empty
min-height: 1px;
// Set inner padding as gutters instead of margin
padding-left: @grid-column-padding;
padding-right: @grid-column-padding;
// Proper box-model (padding doesn't add to width)
.box-sizing(border-box);
}
创建这些 mixin 之后,您可以将它们与媒体查询一起使用,如下所示:
footer {
.make-row();
div {
.iscolumn();
.less-make-column(1);
@media (min-width: @grid-float-breakpoint) {
.less-make-column(3);
}
}
}
总结
很遗憾,你已经到达了本章的结尾。希望你觉得自己已经能够用Less开始自己的项目了。在本章中,你学会了如何在项目中使用Less。你还学会了如何使用媒体查询和网格来构建响应式网站。现在你已经准备好在项目中开始使用Less了。最后,你将有更多时间来处理真正的设计任务。在下一章中,你将介绍其他使用Less的项目和框架。你还将学习如何在自己的项目中使用它们。
第六章:Bootstrap 3,WordPress 和其他应用程序
在阅读了前面的章节之后,你应该已经学会了如何使用Less构建自己的项目。你将在同样的时间内写出更好的 CSS 并取得更多的成就。你现在绝对已经准备好了最后一步。在本书的最后一章中,你将学习如何在其他知名框架、应用程序和工具中使用Less。你将了解到使用Less构建更好项目的工具,这些项目可以使用、定制和扩展Less。
本章将涵盖以下主题:
-
Bootstrap 3
-
语义化 UI
-
使用Less构建网格
-
WordPress 和Less
-
编译Less代码的替代编译器
Bootstrap 3
Bootstrap 3,以前被称为Twitter 的 Bootstrap,是用于构建应用程序前端的 CSS 和 JavaScript 框架。Bootstrap 3 中的三指的是这个框架的第三个版本;在本书中提到 Bootstrap 时,指的就是这个第三个版本。Bootstrap 3 与框架早期版本有重要的变化。Bootstrap 3 与早期版本不兼容。
Bootstrap 3 可以用来构建出色的前端。你可以下载完整的框架,包括 CSS 和 JavaScript,并立即开始使用。Bootstrap 还有一个网格。Bootstrap 的网格默认是移动优先的,有 12 列。事实上,Bootstrap 定义了四个网格:小于 768 像素的超小网格(手机),768 到 992 像素之间的小网格(平板电脑),992 到 1200 像素之间的中等网格(桌面),最后,大于 1200 像素的大桌面的大网格。在第五章中,将 Less 集成到您自己的项目中,你使用 Preboot 的 mixin 构建了一个网格;Bootstrap 的网格以类似的方式工作。
网格、所有其他 CSS 组件和 JavaScript 插件在getbootstrap.com/
上都有描述和文档。
Bootstrap 的默认主题如下截图所示:
使用 Bootstrap 3 构建的布局示例
过去所有的 Bootstrap 网站看起来都很相似的时代已经远去。Bootstrap 将给你创造创新设计所需的所有自由。
关于 Bootstrap 还有很多要讲,但现在让我们回到Less。
使用 Bootstrap 的 Less 文件
Bootstrap 的所有 CSS 代码都是用Less编写的。你可以下载 Bootstrap 的Less文件并重新编译自己的版本的 CSS。Less文件可以用于定制、扩展和重用 Bootstrap 的代码。在接下来的章节中,你将学习如何做到这一点。
要下载Less文件,请在getbootstrap.com/
上的 Bootstrap 的 GitHub 页面github.com/twbs/bootstrap
上选择下载 Zip在右侧栏。
使用 Grunt 构建 Bootstrap 项目
在下载了前面提到的文件之后,你可以使用Grunt构建一个 Bootstrap 项目。Grunt 是一个 JavaScript 任务运行器;它可以用于自动化你的流程。Grunt 在执行重复任务时会帮助你,比如代码的缩小、编译、单元测试和代码的 linting。
Grunt 在node.js上运行,并使用npm,你在安装Less编译器时看到了。Node.js 是一个独立的 JavaScript 解释器,建立在谷歌的 V8 JavaScript 运行时上,就像在 Chrome 中使用的那样。Node.js 可以用于轻松构建快速、可扩展的网络应用程序。
当你解压下载的文件时,你会在其中找到Gruntfile.js
和package.json
等文件。package.json
文件包含了作为 npm 模块发布的项目的元数据。Gruntfile.js
文件用于配置或定义任务和加载 Grunt 插件。Bootstrap Grunt 配置是一个很好的例子,可以向你展示如何为包含 HTML、Less(CSS)和 JavaScript 的项目设置自动化测试。这本书无法涵盖所有内容;关于 Grunt.js 的更多信息可以在www.packtpub.com/grunt-js-cookbook/book
上找到Grunt.js Cookbook。作为Less开发者,对你有趣的部分在下面的章节中提到。
在package.json
文件中,你会发现 Bootstrap 使用grunt-contrib-less
来编译它的Less文件。在撰写本书时,grunt-contrib-less
插件使用 less.js 版本 1.7 来编译Less。与 Recess(Bootstrap 先前使用的另一个 JavaScript 构建工具)相比,grunt-contrib-less
也支持源映射。
除了grunt-contrib-less
,Bootstrap 还使用grunt-contrib-csslint
来检查编译后的 CSS 是否存在语法错误。grunt-contrib-csslint
插件还有助于改善浏览器兼容性、性能、可维护性和可访问性。该插件的规则基于面向对象的 CSS 原则(www.slideshare.net/stubbornella/object-oriented-css
)。你可以通过访问github.com/stubbornella/csslint/wiki/Rules
来获取更多信息。
Bootstrap 大量使用Less变量,这些变量可以通过自定义器进行设置。
曾经研究过Gruntfile.js
源代码的人可能也会找到对BsLessdocParser
Grunt 任务的引用。这个 Grunt 任务用于基于 Bootstrap 使用的Less变量动态构建 Bootstrap 的自定义器。尽管解析Less变量来构建文档等过程非常有趣,但这个任务在这里不再讨论。你将在本章后面了解到自定义器。
本节以Gruntfile.js
中执行Less编译的部分结束。Gruntfile.js
中的以下代码应该让你对这段代码的外观有所了解:
less: {
compileCore: {
options: {
strictMath: true,
sourceMap: true,
outputSourceFiles: true,
sourceMapURL: '<%= pkg.name %>.css.map',
sourceMapFilename: 'dist/css/<%= pkg.name %>.css.map'
},
files: {
'dist/css/<%= pkg.name %>.css': 'less/bootstrap.less'
}
}
最后,让我们来看一下从命令行运行 Grunt 并构建 Bootstrap 的基本步骤。Grunt 将通过 npm 安装。Npm 会检查 Bootstrap 的package.json
文件,并自动安装列在那里的必要的本地依赖项。
要使用 Grunt 构建 Bootstrap,你需要在命令行上输入以下命令:
> npm install -g grunt-cli
> cd /path/to/extracted/files/bootstrap
之后,你可以通过运行以下命令来编译 CSS 和 JavaScript:
> grunt dist
这将把你的文件编译到/dist
目录中。> grunt test
命令也会运行内置的测试。
编译你的 Less 文件
虽然你可以使用 Grunt 构建 Bootstrap,但并不一定非要使用 Grunt。你会在根目录/bootstrap
内找到一个名为/less
的单独目录中的Less文件。主项目文件是bootstrap.less
;其他文件将在下一节中解释。你可以像在前面的章节中一样使用bootstrap.less
。
你可以将bootstrap.less
与 less.js 一起包含到你的 HTML 中进行测试。
<link rel="bootstrap/less/bootstrap.less" type="text/css" href="less/styles.less" />
<script type="text/javascript">less = { env: 'development' };</script>
<script src="img/less.js" type="text/javascript"></script>
当然,你也可以在服务器端编译这个文件,方法如下:
lessc bootstrap.less > bootstrap.css
深入了解 Bootstrap 的 Less 文件
现在是时候更详细地查看 Bootstrap 的Less文件了。/less
目录包含了一长串文件。您可以通过它们的名称来识别一些文件。您之前已经看到了一些文件,比如variables.less
、mixins.less
和normalize.less
。打开bootstrap.less
文件,看看其他文件是如何组织的。bootstrap.less
文件中的注释告诉您,Less文件按功能组织,如下面的代码片段所示:
// Core variables and mixins
// Reset
// Core CSS
// Components
尽管 Bootstrap 基本上是基于 CSS 的,但一些组件在没有相关的 JavaScript 插件的情况下无法工作。导航栏组件就是一个例子。Bootstrap 的插件需要jQuery。您不能使用最新的 2.x 版本的 jQuery,因为这个版本不支持 Internet Explorer 8。
要编译您自己的 Bootstrap 版本,您必须更改variables.less
中定义的变量。在前面的章节中,您已经学会了不必覆盖原始文件和变量。使用最后声明胜出和延迟加载规则时,重新声明一些变量将变得很容易。变量的重新声明在第二章中已经讨论过,使用变量和混合。
使用 Less 创建自定义按钮
默认情况下,Bootstrap 定义了七种不同的按钮,如下截图所示:
Bootstrap 3 的七种不同按钮样式
在开始编写Less代码之前,请查看 Bootstrap 按钮的以下 HTML 结构:
<!-- Standard button -->
<button type="button" class="btn btn-default">Default</button>
一个按钮有两个类。全局来看,第一个.btn
类只提供布局样式,第二个.btn-default
类添加颜色。在这个例子中,您只会改变颜色,按钮的布局将保持不变。
在文本编辑器中打开buttons.less
文件。在这个文件中,您会找到不同按钮的以下Less代码:
// Alternate buttons
// --------------------------------------------------
.btn-default {
.button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);
}
上述代码清楚地表明,您可以使用.button-variant()
混合来创建自定义按钮。例如,要定义一个自定义按钮,您可以使用以下Less代码:
// Customized colored button
// --------------------------------------------------
.btn-colored {
.button-variant(blue;red;green);
}
在上述情况下,如果您想要使用自定义按钮扩展 Bootstrap,可以将您的代码添加到一个新文件中,并将该文件命名为custom.less
。将@import custom.less
附加到bootstrap.less
中的组件列表中将起作用。这样做的缺点是,当更新 Bootstrap 时,您将不得不再次更改bootstrap.less
;或者,您可以创建一个名为custombootstrap.less
的文件,其中包含以下代码:
@import "bootstrap.less";
@import "custom.less";
前面的步骤使用自定义按钮扩展了 Bootstrap;或者,您还可以通过重新声明其变量来更改默认按钮的颜色。为此,再次创建一个名为custombootstrap.less
的文件,并将以下代码添加到其中:
@import "bootstrap.less";
//== Buttons
//
//## For each of Bootstrap's buttons, define text, background and border color.
@btn-default-color: blue;
@btn-default-bg: red;
@btn-default-border: green;
在某些情况下,例如,您需要使用 Bootstrap 的按钮样式,而不需要其他任何东西。在这种情况下,您可以在@import
指令中使用reference
关键字,如前面在第五章中讨论的那样,将 Less 集成到您自己的项目中。
您可以使用以下Less代码为您的项目创建一个 Bootstrap 按钮:
@import (reference) "bootstrap.less";
.btn:extend(.btn){};
.btn-colored {
.button-variant(blue;red;green);
}
您可以通过在浏览器中访问http://localhost/index.html
来查看上述代码的结果。
请注意,根据您使用的 less.js 版本,您可能会在编译输出中找到一些意外的类。媒体查询或扩展类有时会破坏旧版本的 less.js 中的引用。
使用 Less 自定义 Bootstrap 的导航栏
Bootstrap 的一个重要组件是导航栏。导航栏为网站添加了主要导航。它主要包含标志或品牌名称、搜索框和导航链接。在本书中,导航栏指的是导航栏。典型的 Bootstrap 导航栏将如下截图所示:
Bootstrap 导航栏的示例
Bootstrap 的导航栏默认是响应式的。在小屏幕尺寸上,上述导航栏将如下截图所示:
折叠和展开的 Bootstrap 导航栏
除了 CSS 之外,Bootstrap 的响应式导航栏还需要折叠 JavaScript 插件。这个插件应该包含在您的 Bootstrap 版本中。
现在,尝试更改默认导航栏的颜色作为示例。为此,您必须首先打开variables.less
,以找出哪些变量给导航栏上色,如下所示:
//== Navbar
//
//##
// Basics of a navbar
@navbar-height: 50px;
@navbar-margin-bottom: @line-height-computed;
@navbar-border-radius: @border-radius-base;
@navbar-padding-horizontal: floor((@grid-gutter-width / 2));
@navbar-padding-vertical: ((@navbar-height - @line-height-computed) / 2);
@navbar-collapse-max-height: 340px;
@navbar-default-color: #777;
@navbar-default-bg: #f8f8f8;
@navbar-default-border: darken(@navbar-default-bg, 6.5%);
// Navbar links
@navbar-default-link-color: #777;
@navbar-default-link-hover-color: #333;
@navbar-default-link-hover-bg: transparent;
@navbar-default-link-active-color: #555;
@navbar-default-link-active-bg: darken(@navbar-default-bg, 6.5%);
@navbar-default-link-disabled-color: #ccc;
@navbar-default-link-disabled-bg: transparent;
// Navbar brand label
@navbar-default-brand-color: @navbar-default-link-color;
@navbar-default-brand-hover-color: darken(@navbar-default-brand-color, 10%);
@navbar-default-brand-hover-bg: transparent;
// Navbar toggle
@navbar-default-toggle-hover-bg: #ddd;
@navbar-default-toggle-icon-bar-bg: #888;
@navbar-default-toggle-border-color: #ddd;
您已经看到找到这些变量很容易。文件中的注释是找到它们的方便指南。您还会看到变量的有意义和描述性名称是有意义的,就像在第二章中学到的那样,使用变量和 mixin。另一方面,您可能会想知道为什么导航栏只有这么多变量。导航栏有许多元素和不同的表现形式,需要用变量来定义。正如前面提到的,Bootstrap 的导航栏默认是响应式的;它会在较小的屏幕上折叠(或者从移动优先的角度来看,它会在较大的屏幕尺寸上变成水平的)。因此,必须为导航栏的折叠和水平版本定义样式。上述代码还设置了导航栏链接和折叠菜单切换按钮的颜色。
就像 Bootstrap 的按钮一样,Bootstrap 的导航栏也是用两个类构建的,如下面的代码片段所示:
<nav class="navbar navbar-default" role="navigation"></nav>
在这种情况下,.navbar
类提供布局样式,第二个.navbar-default
类添加了颜色和其他变化。.navbar
类还有一个设置其类型的第三个类。有四种类型的导航栏:默认、固定在顶部、固定在底部和静态顶部。
导航栏类可以在navbar.less
中找到。导航栏没有 mixin 来构建这些类。Less代码提供了两种备用导航栏样式的类:.navbar-default
和.navbar-inverse
。
由于没有 mixin 可用,重新声明一些导航栏的变量将是自定义其外观和感觉的最佳选择。或者,您可以复制完整的.navbar-default
类并用于自定义。Bootstrap 打算每页只使用一个导航栏,因此额外的样式类没有增加的价值。
例如,现在设置如下:
@navbar-default-color: red;
@navbar-default-bg: blue;
@navbar-default-border: yellow;
您可以将这些变量声明为customnavbar.less
,并在该文件中添加@import "bootstrap.less";
。现在,您可以编译customnavbar.less
。
您可以通过在浏览器中访问http://localhost/customnavbar.html
来查看上述代码的结果。
Bootstrap 的类和 mixin
浏览组件时,您会发现 Bootstrap 是一个非常完整的框架。在编译框架之后,您将拥有构建响应式网站所需的所有类。另一方面,Bootstrap 也可以作为一个库来使用。您已经看到如何只使用按钮。
在utilities.less
中,您可以找到以下代码:
.clearfix {
.clearfix();
}
上述代码使.clearfix
类可以直接在您的 HTML 中使用;另一方面,您仍然可以重用.clearfix()
mixin。您可以在mixins.less
中找到 Bootstrap 的 mixin。这种严格的 mixin 和类的分离允许您导入mixins.less
并将这些 mixin 应用到您自己的代码中,而不需要实际创建这些类的输出。
mixins.less
文件的前面导入将允许您在自己的项目中使用 Bootstrap 的渐变 mixin,如下面的代码片段所示:
@import "bootstrap/mixins.less";
header {
#gradient > .horizontal(red; blue);
}
上述代码将编译为以下 CSS 代码:
header {
background-image: -webkit-linear-gradient(left, color-stop(#ff0000 0%), color-stop(#0000ff 100%));
background-image: linear-gradient(to right, #ff0000 0%, #0000ff 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffff0000', endColorstr='#ff0000ff', GradientType=1);
}
如您所见,渐变混合是有命名空间的。还请访问http://localhost/gradient.html
,以查看前面示例中的背景渐变的外观。
使用 Less 主题化 Bootstrap
由于 Bootstrap 的样式是用Less构建的,因此很容易为 Bootstrap 的自定义版本设置主题。基本上有两种方法可以集成您的主题的Less代码。
第一种方法将所有代码编译为单个 CSS 文件。在大多数情况下,推荐使用此方法,因为加载只需要一个 HTTP 请求。
要使用此方法,使用@import
语句将您的主题文件导入到bootstrap.less
中,并重新编译 Bootstrap。或者,创建一个新的项目文件,例如bootstraptheme.less
,其中包括两者,如下面的代码片段所示:
@import "bootstrap.less";
@import "theme.less";
这种方法在Less级别上重写了 Bootstrap 的样式,而第二种方法在 CSS 级别上执行相同的操作。在第二种方法中,主题的Less代码将被编译成单独的 CSS 文件,这些文件将在 Bootstrap 的 CSS 之后加载。
您的客户端编译的 HTML 将如下所示:
<link rel="stylesheet/less" type="text/css" href="less/bootstrap/bootstrap.less" />
<link rel="stylesheet/less" type="text/css" href="less/yourtheme.less" />
<script type="text/javascript">less = { env: 'development' };</script>
<script src="img/less.js" type="text/javascript"></script>
服务器端编译后,您的 HTML 将如下所示:
<link type="text/css" rel="stylesheet" href="css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="css/yourtheme.min.css" />
这种第二种方法在加载页面时需要额外的 HTTP 请求,但另一方面,它提供了从 CDN 加载 Bootstrap 核心的机会,如下所示:
<link type="text/css" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="css/yourtheme.min.css" />
Bootstrap 的 a11y 主题
A11y是(网络)可访问性的常用缩写。可访问性在现代网页设计中起着重要作用;然而,许多网站对此关注较少。Bootstrap 的 a11y 主题提供了更好的可访问性与 Bootstrap。
a11y 主题可以从github.com/bassjobsen/bootstrap-a11y-theme
下载。您只需编译Less文件即可使用该主题。此外,在这种情况下,您可以选择将Less代码集成到您的Less代码库中,或者编译一个单独的主题 CSS 文件。要了解有关 Bootstrap 的更多无障碍改进,请访问github.com/paypal/bootstrap-accessibility-plugin/
。请注意,此插件不提供任何Less代码,只提供 CSS。
1pxdeep 的颜色方案
1pxdeep帮助您在项目中使用相对视觉权重和颜色方案。基于种子颜色,1pxdeep 的scheme.less
文件生成一个包含 16 种颜色的调色板。每种颜色也以变量的形式定义。这些变量,如@color1
或@color4c
,可用于自定义设计。每个颜色变量还定义了一个同名的类,因此您的Less代码中的@color1
和 HTML 中的.color1
指的是您颜色方案中的同一种颜色。
在项目中实现 1pxdeep 后,更改品牌或颜色方案将像更改种子颜色一样简单。
使用 1pxdeep 和 Bootstrap 的典型Less
项目文件将如下代码片段所示:
@import "scheme.less"; // color scheme
@import "bootstrap.less"; // bootstrap
@import "1pxdeep.less"; // 1pxdeep theme
@import "style.less"; // your own styles
前面的代码重新声明了 Bootstrap 的变量,例如@brand-primary: hsl(hue(#428bca),@sat,@l-factor);
,并使您能够在style.less
文件中使用 1pxdeep 的变量,如下面的代码片段所示:
header {
background-color: @color3;
h1 {
color: @color3a;
}
}
1pxdeep 的 CSS 类也可以直接在您的 HTML 代码中使用,如下所示:
<button class="btn btn-default color1">Color 1</button>
在 1pxdeep 的网站上,您可以测试不同的种子颜色,以了解它们的外观。请访问rriepe.github.io/1pxdeep/
并感到惊讶。
使用 Bootstrap 的自定义工具构建您自己的版本
想要从头开始使用定制版本的 Bootstrap 的人也可以使用 Bootstrap 的自定义工具。您可以通过访问getbootstrap.com/customize/
找到自定义工具。自定义工具允许您选择使用哪些Less文件。还可以设置所有 Bootstrap 的Less变量。该列表也可以用作在编译自己的版本时 Bootstrap 变量的参考。请注意,使用自定义工具时可以下载的文件不包含任何Less文件,因此 Bootstrap 自定义工具中的文件不适合进一步使用Less进行定制。
Semantic UI - 另一个 Less 框架
Semantic 也可以用于构建前端。就像 Bootstrap 一样,它包含 CSS 组件和模块。组件已分为元素、集合和视图。模块不仅需要 CSS,还需要 JavaScript。
Semantic 的名称已经清楚地表明它关注 HTML5 的语义。它还是标签不可知的,这意味着您可以在 UI 元素中使用任何 HTML 标签。
在以下代码中,您将找到一个简短的 HTML 示例,展示了 Semantic 的预期用法:
<main class="ui three column grid">
<aside class="column">1</aside>
<section class="column">2</section>
<section class="column">3</section>
</main>
此外,Semantic 也是使用Less构建的。完整的源代码,包括Less文件,可以从github.com/semantic-org/semantic-ui/
下载。
Semantic 处理Less的方式与 Bootstrap 和本书中早期看到的大多数示例不同。与之相反,Semantic 源代码也将使用 Grunt 构建,就像前面的 Bootstrap 部分描述的那样。然而,Semantic 不定义变量,也不定义导入和连接不同Less文件的主文件。Semantic 的Less代码分为不同的模块,其中大多数设置都是硬编码的。
Semantic 处理Less的不同方式也意味着,当您的项目完全使用框架时,您将始终需要在更改或扩展Less代码后运行完整的 Grunt 任务。另一方面,在您的项目中使用单个 Semantic 组件或模块将非常容易。这些组件和模块不依赖于彼此或全局变量。
请访问示例文件中的http://localhost/semanticui.html
以查看其工作原理。您会发现,您可以只包含Less文件来使用网格或按钮。还要注意,如果您的按钮使用图标(Semantic 包含由 Dave Gandy 设计的 Font Awesome 的完整端口作为其标准图标集),您还应该包含icon.less
文件。
自动添加供应商特定规则的前缀
在使用 Grunt 构建 Semantic 时,任务首先将Less文件编译为单个 CSS 文件。在此任务之后,下一个任务运行grunt-autoprefixer
。grunt-autoprefixer
插件使用Can I Use...数据库(caniuse.com/
)解析Less或 CSS,并添加带有供应商前缀的 CSS 属性。/build
目录中的Less文件也以这种方式添加前缀。您可以通过访问github.com/nDmitry/grunt-autoprefixer
了解有关grunt-autoprefixer
的更多信息。最终任务将捆绑 CSS 和 JavaScript 文件到单个文件中并对其进行缩小。
自动添加前缀对于您未来的项目将非常有趣,因为它使您可以仅使用单行声明编写您的Less代码。查看 Semantic 的Grunt.js
以了解其工作原理。目前,运行任务和自动添加前缀不在本书的范围内。请注意,如果您在项目中使用 Semantic 的单个Less文件,您将需要使用/build
目录中的文件,而不是/source
目录中的文件。/build
目录中的Less文件已添加前缀,而/source
目录中的文件没有。
使用 Less 构建网格的其他框架
在前面的部分中,您学习了如何使用 Bootstrap 和 Semantic UI 构建完整的前端。在实践中,对于许多项目,只需一个网格就足够了。您已经看到,语义的网格可以轻松编译为单个组件。同样,Bootstrap 的网格也可以使用以下代码片段编译为单个组件:
// Core variables and mixins
@import "variables.less";
@import "mixins.less";
// Reset
@import "normalize.less";
@import "grid.less";
或者,您也可以使用另一个网格系统。其中一些在以下部分中简要讨论。
使用黄金网格系统构建您的网格
黄金网格系统(GGS)将屏幕分成 18 个均匀的列。最左边和最右边的列用作网格的外边距;这为您的设计留下了 16 列。有关此网格系统的更多详细信息可以在goldengridsystem.com/
找到。
GGS 带有一个Less文件,用于编译所需的 CSS 以构建网格。
注意
Frameless网格系统逐列适应,而不是像素逐像素。
由构建 GGS 的同一作者构建的 Frameless 网格系统不是流体的;当达到断点时,网格会添加列。请注意,Bootstrap 的网格工作方式相同。Frameless 带有一个Less模板,可以编译以使用网格。此模板包含一个小的 CSS 重置,一些一致性修复,以及一些用于启动 Frameless 网格的基本可自定义变量和函数。有关 Frameless 网格的更多信息可以在framelessgrid.com/
找到。Frameless 的文档很少;但是,您可以在 GitHub 上找到 Frameless 主页的源代码。这将让您了解如何使用它与Less。
语义网格系统
语义网格系统非常基础和有效。设置列和间距宽度后,选择列数并在像素和百分比之间切换;您将在标记中没有任何.grid_x
类的布局。语义网格系统也是响应式的。它还支持嵌套和推拉,这使您可以对列应用左右缩进。
使用Less定义流体布局将像在以下代码片段中所示一样简单:
@import 'grid.less';
@columns: 12;
@column-width: 60;
@gutter-width: 20;
@total-width: 100%; // Switch from pixels to percentages
article {
.column(9);
}
section {
.column(3);
}
关于语义网格系统的更多信息可以在semantic.gs/
找到。
WordPress 和 Less
如今,WordPress 不仅用于博客;它也可以用作内容管理系统来构建网站。
用 PHP 编写的 WordPress 系统已分为核心系统、插件和主题。插件为系统添加了额外的功能,主题处理了使用 WordPress 构建的网站的外观和感觉。插件彼此独立工作。插件也独立于主题,主题大多也不依赖插件。WordPress 主题为网站定义全局 CSS,但每个插件也可以添加自己的 CSS 代码。
WordPress 主题开发人员可以使用Less来编译主题和插件的 CSS。
使用 Less 的 Roots 主题
Roots是一个 WordPress 起始主题。您可以使用 Roots 来构建自己的主题。Roots 基于 HTML5 Boilerplate (html5boilerplate.com/
)和 Bootstrap。还请访问 Roots 主题网站roots.io/
。此外,Roots 也可以完全使用 Grunt 构建。有关如何在 WordPress 开发中使用 Grunt 的更多信息,请访问roots.io/using-grunt-for-wordpress-theme-development/
。
下载 Roots 后,Less文件可以在assets/less/
目录中找到。这些文件包括 Bootstrap 的Less文件,如前所述。assets/less/app.less
文件导入了主要的 Bootstrap Less文件,bootstrap.less
。
现在,您可以编辑app.less
来自定义您的主题。更改后,您将需要重新构建 Roots。
Roots 的文档描述了编辑 Bootstrap 的variables.less
文件作为定制使用 Roots 构建的网站的最简单方法。更多信息请访问roots.io/modifying-bootstrap-in-roots/
。
JBST 内置 Less 编译器
JBST 也是一个 WordPress 入门主题。JBST 旨在与所谓的子主题一起使用。有关 WordPress 子主题的更多信息,请访问codex.wordpress.org/Child_Themes
。
安装 JBST 后,您将在仪表板的外观下找到一个Less编译器,如下截图所示:
JBST 在 WordPress 仪表板中内置的 Less 编译器
内置的Less编译器可用于完全定制您的网站与Less。Bootstrap 也构成了 JBST 的骨架,并且默认设置是从前面提到的 a11y bootstrap 主题中收集的。
JBST 的Less编译器可以以不同的方式使用。
首先,编译器接受任何自定义编写的Less(和 CSS)代码。例如,要更改h1
元素的颜色,只需编辑并重新编译代码如下:
h1 {color: red;}
其次,您可以编辑 Bootstrap 的变量并(重新)使用 Bootstrap 的混合器。因此,要设置导航栏的背景颜色并添加自定义按钮,可以在Less编译器中使用以下代码:
@navbar-default-bg: blue;
.btn-colored {
.button-variant(blue;red;green);
}
第三,您可以设置 JBST 内置的Less变量,例如:
@footer_bg_color: black;
第四,JBST 有自己的一套混合器。要设置自定义字体,可以编辑如下:
.include-custom-font(@family: arial,@font-path, @path: @custom-font-dir, @weight: normal, @style: normal);
在上述代码中,参数用于设置字体名称(@family
)和字体文件的路径(@path/@font-path
)。@weight
和@style
参数设置了字体的属性。更多信息,请访问github.com/bassjobsen/Boilerplate-JBST-Child-Theme
。
还可以在特殊文件(wpless2css/wpless2css.less
或less/custom.less
)中添加更多Less代码;这些文件还可以让您选择添加预构建的混合库,例如第四章中讨论的那些,避免重复造轮子。通过这个文件添加库后,混合器也可以与内置编译器一起使用。
Semantic UI WordPress 主题
如前所述,Semantic UI 提供了自己的 WordPress 插件。该插件可以在 GitHub 上找到github.com/ProjectCleverWeb/Semantic-UI-WordPress
。安装并激活此主题后,您可以直接使用 Semantic UI 进行网站。使用默认设置,您的网站将如下截图所示:
使用 Semantic UI WordPress 主题构建的网站
WordPress 插件和 Less
如前所述,WordPress 插件有自己的 CSS。此 CSS 将作为普通样式表添加到页面中,如下所示:
<link rel='stylesheet' id='plugin-name' href='//domain/wp-content/plugin-name/plugin-name.css?ver=2.1.2' type='text/css' media='all' />
除非插件为其 CSS 提供Less文件,否则将很难使用Less管理其样式。
带有 Less 的 WooCommerce 主题
WooCommerce是 WordPress 的一款热门电子商务插件。使用 WooCommerce,您可以很快地建立一个网店。您可以使用Less为 WooCommerce 网店设置主题,文档在docs.woothemes.com/document/css-structure/
中有记录。
WooCommerce 的Less文件应该编译成 CSS 并按照前面描述的方式使用。要为所有样式表创建单个 CSS 文件,您可以考虑将woocommerce.less
导入到项目的主Less文件中,并在主题的functions.php
文件中使用define('WOOCOMMERCE_USE_CSS', false);
禁用默认样式。
WP Less to CSS 插件
WP Less to CSS插件可以在wordpress.org/plugins/wp-less-to-css/
找到,它可以让您使用Less为 WordPress 网站设置样式。如前所述,您可以使用 JBST 的内置编译器输入Less代码。此代码将被编译成网站的 CSS。此插件使用 PHP Less 编译器Less.php
编译Less。
用于编译 Less 代码的替代编译器
随着Less的日益流行,Less编译器也被移植到其他语言。这些移植可以用于使用本地语言调用编译Less。请记住,这些移植通常会滞后于官方 JavaScript 实现,因此您可能会发现它们缺少最近的Less功能。您可能也会意识到,正如第三章中早些时候提到的,嵌套规则、操作和内置函数,这些编译器无法编译反引号内的本机 JavaScript 表达式。
Less.php 编译器
官方Less处理器的这个 PHP 移植版本可以在lessphp.gpeasy.com/
下载。您已经看到了它的用法示例;WP Less to CSS 插件就是用它构建的。Less.php
还实现了缓存以加快编译速度。
尽管Less.php
提供了动态创建 CSS 的可能性,但在大多数情况下,您仍应该为生产环境预编译您的 CSS。WordPress 也是用 PHP 编写的,因此在 WordPress 插件的情况下,可以使用Less进行编译,而无需使用系统调用。
在下面的代码中,您将找到一个简短的示例,它将向您展示如何在 PHP 编写的网站上编译、自定义和使用 Bootstrap:
<?php
require 'less.php/Cache.php';
Less_Cache::$cache_dir = '/var/www/mysite/writable_folder';
$files = array();
$files['/var/www/mysite/bootstrap/bootstrap.less'] = '/mysite/bootstrap/';
$files['/var/www/mysite/custom/my.less'] = '/mysite/custom/';
$css_file_name = Less_Cache::Get( $files );
echo '<link rel="stylesheet" type="text/css" href="/mysite/writable_folder/'.$css_file_name.'">';
leafo.net/lessphp/
提供的lessphp编译器是另一种 PHP Less 编译器。
.NET 应用程序的.less 编译器
.less
编译器是 JavaScript Less库在.NET 平台上的完整移植。如果您想要静态编译您的文件,可以使用附带的dotless.Compiler.exe
编译器。您可以通过向Web.Config
文件添加新的 HTTP 处理程序来使用.less
来制作您的网页,如下所示:
<add type="dotless.Core.LessCssHttpHandler,dotless.Core" validate="false" path="*.Less" verb="*" />
开发 Less 的工具列表
在Less网站(lesscss.org/usage/
)上,您将找到许多其他库、工具和框架来开发Less。
总结
在本章中,您学会了如何在 Bootstrap 和 Semantic UI 中使用Less,还介绍了其他使用Less构建的网格和框架。您已经了解了如何在 WordPress 中使用Less,最后,您了解了如何为项目使用替代编译器。
这也是本书的最后一章。在本书中,您学会了如何在项目中使用Less。您看到了变量、混合和内置函数如何帮助您重用代码。使用Less,您可以嵌套您的样式规则,这使得您的代码更直观和可读。阅读本书后,您知道自己不必亲自编写所有代码,而是可以使用他人编写的预构建混合。最后,您学会了如何从头开始使用Less启动项目,并将Less与 WordPress、Bootstrap 和其他工具集成。现在,您真的准备好开始开发Less了。恭喜!您已经使自己能够更好、更快地使用Less来开发项目,并为真正的设计任务节省更多时间。