在本文中 我将介绍使用 LESS Framework 动态生成 CSS 内容的 Web 开发
毫无疑问 CSS 代表一大飞跃 它有望将内容与网页显示完全分离 而且在很大程度上实现了这一点 尽管 CSS 属于(或应该属于?)设计人员关注的范畴 它率先提出了关注点分离原则 几乎每个开发人员都对此非常敏感 因此 CSS 很快获得采用 它在 Web 开发过程中如此根深蒂固 以致于有时难于满足最新网站的需求
问题并不是 CSS 不足以满足样式最新 图形丰富并且外观吸引人的网站需求 而是纯粹的声明语言并非始终适合表现复杂的互联样式声明 好在只要编写正确 CSS 对于浏览器仍然合理 但对人来说也是如此吗?
Web 开发中一个相对较新的方向是围绕 CSS 构建基础结构 使开发人员和设计人员能够以可持续性更高的方式生成相同的 CSS 最终的浏览器样式表并无变化 但其生成方式应有所不同 更易读也更容易管理
这一 Web 开发领域出现于几年前 现在日渐成熟 有几个可用的框架可以帮助您进行动态 CSS 内容生成 我将提供其中一个框架 也就是 LESS Framework 的执行概要 并演示它如何与 ASP NET MVC 解决方案集成
为何采用 LESS?
开发人员借助 LESS 解决的最大问题之一 是信息的重复 作为软件开发人员 您可能了解 切勿重复 (DRY) 原则并且每天都在应用 DRY 的主要优点在于 它减少了相同信息的存储位置 因而减少了应更新该信息的位置的数量
对于普通 CSS 您根本不会遇到 DRY 问题 例如 在某些其他情况下 如果多个类中使用某种颜色 而您需要对其进行更改 可能除了逐一更新之外没有更好的办法了 使用 CSS 类可以定义特定元素的外观 并针对样式相关的元素以相同的方式跨页面重复使用 尽管 CSS 类确实可以减少重复 但有时在其他方面显得不足
CSS 类的一个问题是它们在语义 HTML 元素的级别运行 在构建各种 CSS 类时 经常需要重复颜色或宽度等细节信息 对这些可重复细节中的每一个使用同一个类并不方便 即使设法用一个 CSS 类表示几乎所有可重复样式 如颜色和宽度 当开始对语义元素(如容器)应用样式时 还是应该连用多个 CSS 类以便实现所需的效果
如果您曾用 Bootstrap 等框架设计过网页 就会明白我的意思 例如
<a class= btn btn primary />
首先将锚点设置为一个按钮(类 btn) 然后设置为特定风格的按钮(类 btn primary) 这种方法有效 但可能需要进行大量工作提前计划所需的类 这会增加 Web 项目的工作量 而项目往往时间紧迫
LESS 这样的动态样式表语言表示一种横向思维 您不必花时间尝试使普通 CSS 变得更加智能 只需使用不同的工具(一般是语言)进行生成即可 因此 LESS 是一种框架 它向 CSS 编码添加了编程人员友好的概念 如变量 块和函数
与动态 CSS 生成严格相关的 是将其处理为普通 CSS 供浏览器使用的问题 客户端可以通过临时 JavaScript 代码处理 LESS 代码 也可以在服务器上对其进行预处理 使浏览器只接收最终的 CSS
在 ASP NET MVC 中设置 LESS我将演示从 ASP NET MVC 应用程序中使用 LESS 所需的 *** 作 首先 我将重点介绍 LESS 代码的客户端处理 在布局文件的 HEAD 部分添加以下内容
<link rel= stylesheet/less type= text/css href= @Url Content( ~/content/less/mysite less ) /><script type= text/javascript src= @Url Content( ~/content/scripts/less min js ) ></script>
这里假设您已在项目中创建了 Content/Less 文件夹以包含所有 LESS 文件 您需要一个 JavaScript 文件 以便在浏览器中进行实际的 LESS 到 CSS 处理 您可以从 获取该脚本文件 我将回顾一些可证明 LESS 有用的场景
运行中的 LESS 变量
观察 CSS 渐变是了解 LESS 变量作用的好方法 多年以来 设计人员使用小的 GIF 文件绘制 HTML 容器的渐变背景 最近 浏览器增加了 CSS 渐变支持 这也是官方 CSS 标准的一部分 通过线性渐变语法及其变体实现 很遗憾 如果要确保尽量多的浏览器采用这种渐变 必须借助一些东西 如 图 中的代码
图 中的代码几乎不可读 更糟的是 在需要渐变的任何地方都必须重复使用这些代码 此外 如果要稍微更改一下渐变颜色(或只更改饱和度或淡化效果) 唯一的办法是在所有位置进行手动编辑 直截了当地说 这非常困难 但是 这是对于普通 CSS 唯一可行的方法
图 在多种浏览器中显示渐变的综合代码
/* Old browsers fallback */ background color: #ff background: url(images/red_gradient png)background repeat: repeat x/* Browser specific syntax */ background: moz linear gradient( left #fceabb % #fccd d % #f b % #fbdf %)background: Webkit linear gradient( left #fceabb % #fccd d % #f b % #fbdf %)background: o linear gradient( left #fceabb % #fccd d % #f b % #fbdf %)background: ms linear gradient( left #fceabb % #fccd d % #f b % #fbdf %)/* Standard syntax */ background: linear gradient( to right #fceabb % #fccd d % #f b % #fbdf %)
为找到更好的解决方案 您需要跳出 CSS 试试 LESS 在 LESS 中 您只需定义一次渐变 CSS 然后在适当的位置按名称引用即可 例如
background gradient orange { background: #fceabb } &ntainer { background gradient orange}
名为 background gradient orange 的类按名称在适当的位置嵌入到类容器和任意其他类中 而渐变定义保存在一个位置
从开发人员的角度来看 这并不是什么革命性的改变 不过 它使用了变量功能 这是 CSS 中没有的 事实上 如果将文件保存为普通样式表并引用的话 前面的语法并不可行 需要一些代码将扩展语法转换为普通 CSS 这正是 LESS JavaScript 分析器的功能 它将变量扩展为其实际 CSS 内容
变量还适用于颜色或大小等标量值 请考虑以下 LESS 代码
@black: # #main { color: @black} header { background color: @black}
分析器将 @black 变量扩展为分配的值并进行全文件替换 最终效果是 在一处更改实际颜色 整个文件中的相应内容会自动更改 运行中的 LESS Imports
如果需要 您可以将 LESS 代码拆分到多个文件 引用文件和包含的类中 例如 假设您创建一个 gradients less 文件 内容如下
background gradient orange { background: #fceabb }
在另一个 LESS 文件中 如 main less 您可以通过导入该文件引用任何渐变
@import "gradients" &ntainer { background gradient orange}
如果 gradients less(扩展名不是严格必需的)位于其他文件夹中 则应在调用中指示路径信息以便导入 LESS Mixin
我调用该 LESS 项目进行变量渐变 严格来说 这并不完全正确 在 LESS 中 一个变量包含一个单一值 一个 CSS 类容器被称为一个 mixin 这类似于函数 但不包含任何自定义逻辑 就像函数一样 LESS 可以接受和处理参数 请看看图 中演示 mixin 的代码
在图 中 一个名为 shadow 的 mixin 定义了框阴影样式 并将颜色作为外部参数公开 与之类似 text box mixin 定义输入字段的基本外观 它导入阴影定义并保持宽度为参数化形式 通过这种方式 为不同大小(mini normal 和 large)的输入字段定义三个类就非常简单了 更重要的是 它只需进行少量编辑工作 更新也非常简单(请参阅图 )
图 LESS Framework 中的 Mixin
/* Mixins */ shadow(@color) { box shadow: px px px @color } text box(@width) { shadow(# ) border: solid px # background color: #dddd padding: px width: @width } /* CSS classes */ text box mini { text box( px) } text box normal { text box( px) } text box large { text box( px) }
图 运行中的 LESS Mixin
Mixin 可以接受多个参数或可变数量的参数 此外 每个参数都支持默认值
mixin(@color: #ff ) { }
LESS 并不是富编程语言表示 它的设计缺少命令来指示条件或循环 但 mixin 的行为仍然可以根据所传递的值发生变化 假设您要对一个较大的按钮使用较粗的边框和字体 您定义一个名为 button 的参数化 mixin 使用关键字 when 将设置与条件绑定 条件必须基于一个参数
button (@size) when (@size <px) { padding: px font size: em width: @size * } button (@size) when (@size >= px) { padding: px font size: em font weight: background color: red width: @size * }
您应用不同的设置 但也可以使用基本 *** 作通过一个系数将大小扩大为数倍 然后在实际 CSS 类中使用 mixin
push button large { button( px) } push button *** all { button( px) }
运行此代码的结果如 图 所示
图 在 CSS 类中使用 LESS Mixin 的效果
LESS 附带很多可 *** 作颜色的预定义函数 您可以使用函数按百分比调整颜色亮度和饱和度 也可以按百分比设置颜色淡入和淡出 如下所示
push button { background color: fade(red %) }
有关 LESS 支持的函数的完整文档 请参阅 嵌套类
我个人觉得需要重复 CSS 块指示同级样式非常讨厌 下面是一个典型示例
#container h { } #container p { } #container p a { } #container img { }
在编写得很好的普通 CSS 中 实际上可以避免很多重复 但使用平面列表布局样式的方式并不是最好的 在这种情况下 最好使用一些层次结构 在 LESS 中 可以像这样嵌套样式规则
&ntainer { h { font size: em color: fade(# %) a { color: # &:hover {color: red} } } }
经过处理后 前面的 LESS 代码会产生下面的样式
&ntainer h &ntainer h a &ntainer h a:hover
服务器端处理
您可以原样下载 LESS 代码 在客户端通过 JavaScript 代码对其进行处理 也可以在服务器上进行预处理 然后将它作为普通 CSS 下载到客户端 在前一种情况下 完全像使用普通 CSS 文件一样 服务器端更改在下一次页面刷新时应用到客户端
如果您注重性能 处理的是大型复杂 CSS 文件 则服务器端预处理可能是更好的选择 服务器端预处理发生在您每次修改服务器上的 CSS 时 您可以在生成过程结束时手动完成额外的步骤 使用 LESS 编译器从命令行将 LESS 代码预处理为 CSS 此编译器是为服务器端工作安装的 less NuGet 软件包的一部分
不过 在 ASP NET MVC 中 可以将 LESS Framework 与捆绑机制集成 有关捆绑机制 请参阅我在 年 月的专栏 CSS 编程 捆绑和缩小 (msd/magazine/dn ) 这确保只要请求 LESS 文件 就会执行 LESS 到 CSS 的转换 还确保通过 If Modified Since 标头正确管理缓存 最后 您可以将分析和缩小混合起来 要在 ASP NET MVC 中集成 LESS 首先需要下载并安装 less NuGet 软件包 然后将以下代码添加到 BundleConfig 类
var lessBundle = new Bundle("~/myless") IncludeDirectory("~/content/less" "* less") lessBundle Transforms Add(new LessTransform()) lessBundle Transforms Add(new CssMinify()) bundles Add(lessBundle)
捆绑将打包在指定文件夹中找到的所有 less 文件 LessTransform 类负责 LESS 到 CSS 的转换 该类使用 less API 分析 LESS 脚本 LessTransform 的代码非常简单
public class LessTransform : IBundleTransform { public void Process(BundleContext context BundleResponse response) { response Content = dotless Core Less Parse(response Content) response ContentType = "text/css" } }
更多智能工具
lishixinzhi/Article/program/Web/201404/30643
本质上,LESS 包含一套自定义的语法及一个解析器,用户根据这些语法定义自己的样式规则,这些规则最终会通过解析器,编译生成对应的 CSS 文件。LESS 并没有裁剪 CSS 原有的特性,更不是用来取代 CSS 的,而是在现有 CSS 语法的基础上,为 CSS 加入程序式语言的特性。 我们可以直接在客户端使用 .less(LESS 源文件),只需要从http://lesscss.org下载 less.js 文件,然后在我们需要引入 LESS 源文件的 HTML 中加入如下代码:
<link rel=stylesheet/less type=text/css href=styles.less>
LESS 源文件的引入方式与标准 CSS 文件引入方式一样:
<link rel=stylesheet/less type=text/css href=styles.less>
需要注意的是:在引入 .less 文件时,rel 属性要设置为“stylesheet/less”。还有更重要的一点需要注意的是:LESS 源文件一定要在 less.js 引入之前引入,这样才能保证 LESS 源文件正确编译解析。 LESS 在服务器端的使用主要是借助于 LESS 的编译器,将 LESS 源文件编译生成最终的 CSS 文件,目前常用的方式是利用 node 的包管理器 (npm) 安装 LESS,安装成功后就可以在 node 环境中对 LESS 源文件进行编译。
在项目开发初期,我们无论采用客户端还是服务器端的用法,我们都需要想办法将我们要用到的 CSS 或 LESS 文件引入到我们的 HTML 页面或是桥接文件中,LESS 提供了一个我们很熟悉的功能— Importing。我们可以通过这个关键字引入我们需要的 .less 或 .css 文件。 如:
@import “variables.less”
.less 文件也可以省略后缀名,像这样:
@import “variables”
引入 CSS 同 LESS 文件一样,只是 .css 后缀名不能省略。 LESS 允许开发者自定义变量,变量可以在全局样式中使用,变量使得样式修改起来更加简单。
我们可以从下面的代码了解变量的使用及作用:
清单 3 LESS 文件 @border-color : #b5bcc7 .mythemes tableBorder{ border : 1px solid @border-color }
经过编译生成的 CSS 文件如下:
清单 4. CSS 文件 .mythemes tableBorder { border: 1px solid #b5bcc7 }
从上面的代码中我们可以看出,变量是 VALUE(值)级别的复用,可以将相同的值定义成变量统一管理起来。
该特性适用于定义主题,我们可以将背景颜色、字体颜色、边框属性等常规样式进行统一定义,这样不同的主题只需要定义不同的变量文件就可以了。当然该特性也同样适用于 CSS RESET(重置样式表),在 Web 开发中,我们往往需要屏蔽浏览器默认的样式行为而需要重新定义样式表来覆盖浏览器的默认行为,这里可以使用 LESS 的变量特性,这样就可以在不同的项目间重用样式表,我们仅需要在不同的项目样式表中,根据需求重新给变量赋值即可。
LESS 中的变量和其他编程语言一样,可以实现值的复用,同样它也有生命周期,也就是 Scope(变量范围,开发人员惯称之为作用域),简单的讲就是局部变量还是全局变量的概念,查找变量的顺序是先在局部定义中找,如果找不到,则查找上级定义,直至全局。下面我们通过一个简单的例子来解释 Scope。
清单 5. LESS 文件 @width : 20px #homeDiv { @width : 30px #centerDiv{ width : @width// 此处应该取最近定义的变量 width 的值 30px} } #leftDiv {width : @width// 此处应该取最上面定义的变量 width 的值 20px }
经过编译生成的 CSS 文件如下:
清单 6. CSS 文件 #homeDiv #centerDiv { width: 30px } #leftDiv { width: 20px } Mixins(混入)功能对用开发者来说并不陌生,很多动态语言都支持 Mixins(混入)特性,它是多重继承的一种实现,在 LESS 中,混入是指在一个 CLASS 中引入另外一个已经定义的 CLASS,就像在当前 CLASS 中增加一个属性一样。
我们先简单看一下 Mixins 在 LESS 中的使用:
清单 7. LESS 文件// 定义一个样式选择器 .roundedCorners(@radius:5px) { -moz-border-radius: @radius -webkit-border-radius: @radius border-radius: @radius } // 在另外的样式选择器中使用 #header { .roundedCorners } #footer { .roundedCorners(10px) }
经过编译生成的 CSS 文件如下:
清单 8. CSS 文件 #header { -moz-border-radius:5px -webkit-border-radius:5px border-radius:5px } #footer { -moz-border-radius:10px -webkit-border-radius:10px border-radius:10px }
从上面的代码我们可以看出:Mixins 其实是一种嵌套,它允许将一个类嵌入到另外一个类中使用,被嵌入的类也可以称作变量,简单的讲,Mixins 其实是规则级别的复用。
Mixins 还有一种形式叫做 Parametric Mixins(混入参数),LESS 也支持这一特性:
清单 9. LESS 文件// 定义一个样式选择器 .borderRadius(@radius){ -moz-border-radius: @radius -webkit-border-radius: @radius border-radius: @radius } // 使用已定义的样式选择器 #header { .borderRadius(10px)// 把 10px 作为参数传递给样式选择器 } .btn { .borderRadius(3px)// // 把 3px 作为参数传递给样式选择器 }
经过编译生成的 CSS 文件如下:
清单 10. CSS 文件 #header { -moz-border-radius: 10px -webkit-border-radius: 10px border-radius: 10px } .btn { -moz-border-radius: 3px -webkit-border-radius: 3px border-radius: 3px }
我们还可以给 Mixins 的参数定义一人默认值,如
清单 11. LESS 文件.borderRadius(@radius:5px){ -moz-border-radius: @radius -webkit-border-radius: @radius border-radius: @radius } .btn { .borderRadius }
经过编译生成的 CSS 文件如下:
清单 12. CSS 文件 .btn { -moz-border-radius: 5px -webkit-border-radius: 5px border-radius: 5px }
像 JavaScript 中arguments一样,Mixins 也有这样一个变量:@arguments。@arguments 在 Mixins 中具是一个很特别的参数,当 Mixins 引用这个参数时,该参数表示所有的变量,很多情况下,这个参数可以省去你很多代码。
清单 13. LESS 文件 .boxShadow(@x:0,@y:0,@blur:1px,@color:#000){ -moz-box-shadow: @arguments -webkit-box-shadow: @arguments box-shadow: @arguments } #header { .boxShadow(2px,2px,3px,#f36) }
经过编译生成的 CSS 文件如下:
清单 14. CSS 文件 #header { -moz-box-shadow: 2px 2px 3px #FF36 -webkit-box-shadow: 2px 2px 3px #FF36 box-shadow: 2px 2px 3px #FF36 }
Mixins 是 LESS 中很重要的特性之一,我们这里也写了很多例子,看到这些例子你是否会有这样的疑问:当我们拥有了大量选择器的时候,特别是团队协同开发时,如何保证选择器之间重名问题?如果你是 java 程序员或 C++ 程序员,我猜你肯定会想到命名空间 Namespaces,LESS 也采用了命名空间的方法来避免重名问题,于是乎 LESS 在 mixins 的基础上扩展了一下,看下面这样一段代码:
清单 15. LESS 文件 #mynamespace { .home {...} .user {...} }
这样我们就定义了一个名为 mynamespace 的命名空间,如果我们要复用 user 这个选择器的时候,我们只需要在需要混入这个选择器的地方这样使用就可以了。#mynamespace >.user。 在我们书写标准 CSS 的时候,遇到多层的元素嵌套这种情况时,我们要么采用从外到内的选择器嵌套定义,要么采用给特定元素加 CLASS 或 ID 的方式。在 LESS 中我们可以这样写:
清单 16. HTML 片段 <div id=home> <div id=top>top</div> <div id=center> <div id=left>left</div> <div id=right>right</div> </div> </div>清单 17. LESS 文件 #home{ color : blue width : 600px height : 500px border:outset #top{ border:outsetwidth : 90% } #center{ border:outsetheight : 300pxwidth : 90%#left{ border:outset float : left width : 40%} #right{ border:outset float : left width : 40%} } }
经过编译生成的 CSS 文件如下:
清单 18. CSS 文件 #home { color: blue width: 600px height: 500px border: outset } #home #top { border: outset width: 90% } #home #center { border: outset height: 300px width: 90% } #home #center #left { border: outset float: left width: 40% } #home #center #right { border: outset float: left width: 40% }
从上面的代码中我们可以看出,LESS 的嵌套规则的写法是 HTML 中的 DOM 结构相对应的,这样使我们的样式表书写更加简洁和更好的可读性。同时,嵌套规则使得对伪元素的 *** 作更为方便。
清单 19. LESS 文件a { color: red text-decoration: none &:hover {// 有 &时解析的是同一个元素或此元素的伪类,没有 &解析是后代元素 color: black text-decoration: underline } }
经过编译生成的 CSS 文件如下:
清单 20. CSS 文件 a { color: red text-decoration: none } a:hover { color: black text-decoration: underline } 在我们的 CSS 中充斥着大量的数值型的 value,比如 color、padding、margin 等,这些数值之间在某些情况下是有着一定关系的,那么我们怎样利用 LESS 来组织我们这些数值之间的关系呢?我们来看这段代码:
清单 21 . LESS 文件 @init: #111111 @transition: @init*2 .switchColor { color: @transition }
经过编译生成的 CSS 文件如下:
清单 22. CSS 文件 .switchColor { color: #222222 }
上面的例子中使用 LESS 的 operation 是 特性,其实简单的讲,就是对数值型的 value(数字、颜色、变量等)进行加减乘除四则运算。同时 LESS 还有一个专门针对 color 的 *** 作提供一组函数。
使用这些函数和 JavaScript 中使用函数一样。
清单 23 LESS 文件init: #f04615 #body { background-color: fadein(@init, 10%) }
经过编译生成的 CSS 文件如下:
清单 24. CSS 文件 #body { background-color: #f04615 }
从上面的例子我们可以发现,这组函数像极了 JavaScript 中的函数,它可以被调用和传递参数。这些函数的主要作用是提供颜色变换的功能,先把颜色转换成 HSL 色,然后在此基础上进行 *** 作,LESS 还提供了获取颜色值的方法,在这里就不举例说明了。
LESS 提供的运算及函数特性适用于实现页面组件特性,比如组件切换时的渐入渐出。 同类框架还有 SASS :与 LESS 相比,两者都属于 CSS 预处理器,功能上大同小异,都是使用类似程序式语言的方式书写 CSS, 都具有变量、混入、嵌套、继承等特性,最终目的都是方便 CSS 的书写及维护。
LESS 和 SASS 互相促进互相影响,相比之下 LESS 更接近 CSS 语法。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)