maiktom 2012-08-30
学习LESS源于一次分享的要求。之前一直没有使用,是因为使用这种以“敏捷开发”为目标而诞生的语言在一开始总是需要一些时间来变换思维,以及随之而来的“如何让CSS也具有结构性”的思考负担。其实这些思考都是应该有的,只是在项目时间比较紧的时候,往往更希望通过“加快打字速度”来提高效率。。。。
言归正传。。。LESS的语法和使用在中国社区已经描述的很清楚了,所以我只从自己学习使用的角度记录些需要注意的问题。
客户端使用
1. 直接打开html文件,IE下报“SCRIPT5:拒绝访问”的错误
按照手册中的说法创建完相应的less、html文件,加载完js,在firefox下直接打开html文件,运行正常;但是在IE下打开,则会报“SCRIPT5: 拒绝访问。 less-1.1.3.min.js ”,这个是跨域错误,file协议的跨域判断和http不一样,而没标准规定各个浏览器的file协议怎么算同域。解决方法就是把文件部署在服务器上,用http访问。。。
2. 页面顶部出现大大的“参数无效”红色提示
好好检查less文件吧,有地方语法写错了。也不知道这种风格的提示好还是不好,虽然够醒目,但是未免太霸气了点儿。。。
3. “混合”在浏览器兼容上的应用
这个是LESS中我比较喜欢的一个语法。它使得我们可以将一些通用的属性归集到一个class中,然后在不同的地方调用这个class。在我的某个网页中,我用这个语法首先解决的一个问题就是“拥有float属性的元素的margin在IE浏览器下比其它浏览器多2px”的兼容问题。兼容margin代码如下:
.margin (@top:10px, @right:10px, @bottom:10px, @left:10px) { margin: @arguments; *margin-top: @top - 2px; /* IE7 and below */ *margin-right: @right - 2px; /* IE7 and below */ *margin-left: @left - 2px; /* IE7 and below */ *margin-bottom: @bottom - 2px; /* IE7 and below */ }
这样我就不用在每次给元素增加margin属性的时候都需要加一大串的兼容代码。如:
.red-button { background-color: @my_red; .button; .margin(); } .medium-red-button { background-color: @my_red; .button(100px, 40px, 10px, 5px); .margin(15px, 15px, 15px, 15px); } .big-red-button { background-color: @my_red; .button(100px, 40px, 10px, 5px); .margin(15px, 20px); }
写这段的时候出现过一个问题,因为使用@arguments来避免单独处理每一个参数,所以起初是以为可以直接使用.margin;来调用该属性,但是没有生效,后来改成了.margin();就可以了。 但是如果不使用@arguments,则可以直接用.margin; 这种调用方式。
另外我上面的top,right的兼容代码这些都是分开写的,因为我还没在手册里看到如果和表达式罗列的写在一起,比如这样。
margin: (@top-2px) @right @bottom @left;
翻到后面,发现不是人家没罗列,是我写错了,如果要在复合属性中做计算,运算符号与变量之间要保留一个空格,并用空号包起。即
margin: (@top - 2) @right @bottom @left;
切记!!!
4. “模式匹配”的惯性思维
第一次看模式匹配的语法,想当然的把switch case的思维惯用上了,写出了如下样子的代码
.mixin (press, @color) { background: darken(@color, 10%); } .mixin (hover, @color) { background: lighten(@color, 10%); } .mixin (@_, @color) { background: @color; }
想象的结果是当按钮是press状态时是加深背景色,hover状态时是淡化背景色,其余情况都是正常背景色。真实结果明眼人都知道了,所有状态都是正常背景色。。。原因很简单,参数匹配成功后,下面的匹配仍然继续进行,且@_接受任何参数,最后背景色就都被这个设置覆盖了。正常的switch case是有break强制停止匹配的,LESS中没有,所以带@_参数的类在LESS语法中应该起到的是一个对公用属性的统一配置的作用。
5. “嵌套规则”挺好用
写CSS的时候最郁闷的就是为了保证属性不冲突,要从父元素到子元素的写一串儿选择器,“嵌套规则”解决了这个问题
#header { color: black; .navigation { font-size: 12px } .logo { width: 300px; &:hover { text-decoration: none } } }
6. 再也不用写一堆url前缀啦~~
LESS的“字符串插值”功能允许将变量插入字符串中,这个最直接的应用当然就是image url的定义了。如果在配合之前的几种语法,那些应用image sprite中图标定义也会简单很多。
汗,我写到这里以后,本来打算写一段实例代码,比如
@base-url: "http://img.t.sinajs.cn/t4/style/images/common"; @icon-image-url: "ico.png?id=1341302813656"; .icon (@index) { background-image: url("@{base-url}/@{icon-image-url}"); background-position: 0px (0 - (10 * @index)); } .icon (@_) { width: 50px; height: 50px; } #icon1 { .icon (1); } #icon2 { .icon (2); } #icon3 { .icon (3); }
结果实际输出的css让我大为“惊喜”
#icon3 { background-image: url("http://localhost:8080/dont_commit/http://img.t.sinajs.cn/t4/style/images/common/ico.png?id=1341302813656"); background-position: 0 -130px; height: 50px; width: 50px; }
LESS似乎给我的url前面强行增加了个root,之后我改成../这种相对路径也是这样,我想这应该是less的一个bug吧,一会儿去看看有没有解决方法。
7. LESS的浏览器兼容性
LESS的js本身目前来看是对各浏览器都兼容的,但是考虑到LESS的本质——就是把一种格式的语言解析正常规CSS,应该算是直译,而没有顺路增加些浏览器的兼容hack代码,因此,如果你的代码里出现了一些只有某些浏览器支持的属性,那出来的CSS代码依然只支持那些浏览器。
比如,LESS提供的色彩函数:fadein(@color, 10%) 这个最后生成的是 rgba格式的色彩,IE6不支持,所以这个函数在IE6下并没有效果。
8. LESS生成的CSS与一般CSS文件的优先级
实验代码时,在普通CSS文件和LESS文件中同时定义了两个相同的选择器,只是属性各有不同;并把CSS放在LESS之后加载(有两种方式:1. 在LESS的最后@import 2. 在html中直接在LESS之后引用)。但是输出到浏览器上以后,对于使用@import的,此段CSS被自动调到了代码首部;对于html直接引用的,也变成在LESS之前引入。最后的结果就是CSS中的定义被LESS中的覆盖。因此,在这里先冒昧的下个结论:LESS生成的CSS优先级高于一般CSS文件。
问题和注意的话暂时我就总结出来这么多,其余的LESS提供的一些自带函数,以及引入javascript表达式也是很便利的功能。另外,我觉得在平时的开发中,最好不要让LESS成为开发思想的包袱,不要写什么都要花一天想想怎么转成LESS代码,LESS就是一个工具,需要的时候用,不需要的时候舍,这样才比较健康。