LESS+to+MCSS

此文已由作者郑海波授权网易云社区发布。

欢迎访问网易云社区,了解更多网易技术产品运营经验


一、前言

虽然首页没有开始做,昨天仍决定将[MCSS](https://github.com/NetEaseWD/mcss)从身边的基友们开始向杭研推广了,从开始做这个直到现在推广遇到最多的问题是:

> __不是有LESS了吗?__

这个问题回答了很多遍了,但是觉得回答的都不够好,所以觉得写一篇文章解释一下。其实很多答案也都可以从基于MCSS封装的函数库[mass](https://github.com/leeluolee/mass)中得到解答,本文针对MCSS的例子都可以在这个[Try-Page](http://leeluolee.github.io/mcss/)中进行尝试。

<!-- more -->

-------------------

 

二、LESS特性在MCSS中的对应

首先解答下LESS的特性在MCSS中的对应,这几乎也囊括了在实际生产使用时的80%的功能(实际生产并不包含基础类库封装)

1. 嵌套

MCSS与LESS等其它预处理器的嵌套规则完全一致,支持`&`占位符,例如:

```

.m-home{display: block;div, ul{+ div{margin-top: 20px;}border: 2px solid #ccc;> a{color: #fff;&:hover{text-decoration: none;}~ span{display: block;}}}
}
```


MCSS同时支持另一个占位符`%`,与`&`类似,但它不包含顶级的选择器

比如有时候,我们需要在`.ms-form`的扩展类`.ms-form-stack`中修改某层节点的样式,这时我们不需要重新重复一次书写,例如

 

```
.ms-form{input[type="text"],input[type="password"],input[type="email"],input[type="url"],select{display: inline-block;.ms-form-stack %{display: block;}}// other ruleset
}```
__outport__```css
.ms-form input[type="text"],
.ms-form input[type="password"],
.ms-form input[type="email"],
.ms-form input[type="url"],
select{display:inline-block;
}
.ms-form-stack  input[type="text"],
.ms-form-stack  input[type="password"],
.ms-form-stack  input[type="email"],
.ms-form-stack  input[type="url"],
select{display:block;
}
```

__另外MCSS也可以进行`@media`的条件嵌套__

 

 

2. 变量

 

变量是CSS Preprocessor的最基本功能,LESS的变量占用了CSS规范中的[at-keyword](http://dev.w3.org/csswg/css-syntax/#at-rule-diagram) (例如`@name`)并以`:`作为分隔, 例如

```

@name: 10px;

```

而在MCSS中,变量的声明是以为`dollar-name`(如`$name`)作为标志 

```

$name = 10px;

```

__WHY?__


1. __避免冲突__:

  LESS由于占用`@`, 达到了在词法上与css一致,成就了它看起来最像CSS的美誉,事实上从语法角度讲,LESS可以说是最不规范的,因为它占用了`@at-keyword`, 在css中@at-keyword是作为[`@at-rule`](http://dev.w3.org/csswg/css-syntax/#at-rule-diagram)开始的标志, 这就有潜在冲突的可能性,并且也不利于未来功能的扩展(mcss中所有的功能扩展都是通过自定义@atrule)

 

2. __赋值符扩展__:

  除了`=`,MCSS中有另外两种赋值符号:

  1. `?=`: 赋值操作只在变量不存在时进行,例如:

 ```

    $effect-outport = true;$effect-outport ?= false;```

    此时第二个赋值无效

  2. `^=`: 它可以将赋值定义在全局作用域,MCSS与LESS一样有作用域,所以有时候需要跳脱作用域限制时,这个赋值符就起作用了

 ```

    $global = 10px;p{$global ^= 20px;}```

以上两个赋值符其实都在函数封装时会常用到。

###3. mixin函数
LESS中的`mixin`跟`ruleset`是一致的,不过可以带上操作,例如
```
.size(@width, @height){width: @width
}
//使用时
p{
.size(20px, 40px);
}
```

而在MCSS中,函数可以达到同样效果。首先了解下MCSS中函数的书写方式,与LESS的mixin一样,一个函数可以有参数,也可以没有,同时在MCSS中,函数是一种值类型,同样可以通过赋值操作进行定义,例如:

```
// 带参数
size=(width, $height){height?=width; // ?= 操作符的作用场景一height: $height;width: $width;
}
// 不带参数
$clearfix = {*zoom: 1;&:before, &:after {display: table;content: "";line-height: 0;}&:after {clear: both;}
}
```

使用时候,你可以用类似的括号来调用,也可以用所谓的`隐式调用`, 比如:

```
body{$clearfix(); //正常调用$size: 5px;  //设置宽高的隐式调用
}
```

__输出__

 

```
body{*zoom:1;height:5px;width:5px;
}
body:before,body:after{display:table;content:"";line-height:0;
}
body:after{clear:both;
}``

__需要注意的是,MCSS中的函数是一种真正的值类型,它可以被传递进函数,也可以被函数返回(或用`^=`操作符定义在全局),并保留作用域——所谓闭包__,这不仅仅是个语法糖,使得MCSS拥有其它预处理器没有封装能力!。比较近的例子可以查看MCSS的官方函数库[mass的effect.mcss](https://github.com/leeluolee/mass#effect),利用它,你可以封装出类似`$swing`的函数,并且可以传入参数进行效果调整。

```
@import 'https://rawgithub.com/leeluolee/mass/master/mass/effect.mcss';
$swing(24deg);
```
__Outport__
```css
body{-webkit-backface-visibility:hidden;
}
.animated{-webkit-animation-duration:1s;-moz-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;animation-fill-mode:both;
}
@-webkit-keyframes swing{20%,40%,60%,80%,100%{-webkit-transform-origin:top center;}20%{-webkit-transform:rotate(24deg);}40%{-webkit-transform:rotate(-16deg);}60%{-webkit-transform:rotate(8deg);}80%{-webkit-transform:rotate(-8deg);}100%{-webkit-transform:rotate(0deg);}
}
@-moz-keyframes swing{20%{-moz-transform:rotate(24deg);}40%{-moz-transform:rotate(-16deg);}60%{-moz-transform:rotate(8deg);}80%{-moz-transform:rotate(-8deg);}100%{-moz-transform:rotate(0deg);}
}
@-o-keyframes swing{20%{-o-transform:rotate(24deg);}-o-transform:rotate(-16deg);}60%{-o-transform:rotate(8deg);}80%{-o-transform:rotate(-8deg);}100%{-o-transform:rotate(0deg);}
}
@keyframes swing{20%{transform:rotate(24deg);}40%{transform:rotate(-16deg);}60%{transform:rotate(8deg);}80%{transform:rotate(-8deg);}100%{transform:rotate(0deg);}
}
.animated.swing{-webkit-animation-name:swing;-moz-animation-name:swing;animation-name:swing;-webkit-transform-origin:top center;-moz-transform-origin:top center;-ms-transform-origin:top center;-o-transform-origin:top center;transform-origin:top center;
}
```

这个不仅仅是LESS,是所有其它预处理器没有的能力!

 

4. 颜色函数

mcss支持hsl以及hsla的色值格式,最终会被输出为rgba或者`#ccc`

与LESS不同的是,MCSS不提供类似`lighten`等动词的函数,统一为rgb概念中的red、green、 blue 和 hsl概念中 的hue、saturation、lightness 以及alpha 这7个通道的调节,函数名分别为`r-adjust`,`g-adjust`,`b-adjust`,`h-adjust`,`s-adjust`,`l-adjust`,`a-adjust` 全部支持相对和绝对调节

比如LESS中`lighten`、`darken`其实就是lightness的相对调节

```
@color1: lighten(#ccc, 10%);
@color2: darken(#ccc, 10%);
```

在MCSS其实就是

```
$color1 = l-adjust(#ccc, 10%); //往亮调
$color2 = l-adjust(#ccc, -10%); // 往暗调节
```

所以MCSS的色值函数需要你对hsl颜色格式有一定的了解(前端开发应该这是必备的基础概念吧)

 

5. 操作符

MCSS支持所有LESS的操作符(或者说其实MCSS支持JS中的二元以及以下的所有操作符,并且优先级与JS完全一致)

 

三、一些LESS所欠缺的能力

 

1.逻辑控制`@for`、`@if、@elseif、@else`

由于LESS占用了`@at-keyword`,所以很难提供类似的语言功能。LESS提供一个在选择器上的扩展`when`但是能力仍然有限。

 

2.`@extend`

mixin函数可以帮助我们实现代码片的复用,但是有个巨大的问题就是,mixin会让代码变得庞大(可以看看基于less的bootstrap的重复样式),当有明显的派生关系时,我们可以使用`@extend`,`@extend`是一个源于SASS的概念,它会将派生类的选择器添加到基础类之后。

 

```
.u-ipt {padding: 5px 10px;box-shadow: inset 1px 1px 3px rgba(0,0,0,0.3);
}
.m-form{input[type="text"],input[type="password"]{@extend .u-ipt;}
}
```
__Outport__
```
.u-ipt,
.m-form input[type="text"],
.m-form input[type="password"]padding:5px 10px;box-shadow:inset 1px 1px 3px rgba(0,0,0,0.3);
}
```

没有参数的`mixin`其实都可以用`@extend`来实现(但`@extend`一般用在有明显派生关系的ruleset),MCSS支持多重`@extend`以及嵌套`@extend`,具体请查看MCSS主页


3.`@abstract`

由于组件封装时,我们无法知道后续是否需要某个ruleset,`@abstract`这个@atrule的作用是,将一个或多个ruleset标记为不输出,但是仍然可以被派生。

 

```
//标记一个ruleset
@abstract btn{left: 10px
}
//标记一整个块
@abstract {.btn{}.fbtn{}
}
```

你也可以抽象一整个文件, 它是`@import` 的抽象版

```
@abstract 'ui.mcss';
```

比如在团队开发时,`ui.mcss`已经被公有样式`base.mcss` import了(即会被所有页面所共用),但是后续的页面中仍然需要使用ui.mcss的变量、函数或者ruleset,此时`@abstract出现了`;__ui.mcss__

 

```
// btn的mixin函数
$btn = {padding: 10px
}
// ui中的ruleset
.u-btn{
}
```

__base.mcss__

使用`@import` 会引入`ui.mcss`中的样式

```
@import ui.mcss```

__page1.mcss__

使用`@absctract`,你不会引入任何样式, __但是你仍然可以使用文件中的变量、函数和派生`ui.mcss`中的ruleset__

```
@abstract 'ui.mcss';
.u-btn-2{@extend .u-btn; // 仍然可以@extend$btn();         // 仍然可以使用变量、函数
}
```

这样可以解决团队开发中的问题。一套代码完全取决于`@import`、`@abstract`和`@media`三者的调用会有不同的表现。

 

4.更好的出错信息以及sourcemap

 

在出现语法错误时,MCSS会给你更精确的信息

![error图](https://github-camo.global.ssl.fastly.net/9b3c4a1accf639b9dffbc877275e3e6cca9360c7/687474703a2f2f6c65656c756f6c65652e6769746875622e696f2f6d6373732f696d672f6572726f722e706e67)

同时sourcemap v3格式开始被chrome的developer tool的支持,MCSS也支持(需开启MCSS sourcemap选项,并在chrome的开发者工具的实验特性)

![sourcemap](https://github-camo.global.ssl.fastly.net/8933d6c727f1461fbab5592eb48e0e3d778d324c/687474703a2f2f6c65656c756f6c65652e6769746875622e696f2f6d6373732f696d672f736d2e706e67)


5. MCSS命令行工具

 

相对于其他预处理器MCSS的命令行工具参数很简单,并且提供了代码的多种输出格式,以及自动编译的功能,基本上你已经无需其它工具的支持。具体请`npm install -g mcss` 并且`mcss -h` 一下

-----------------------------

 

四、结尾感言

 

LESS的成功来源于它的`简单`,成功的阐述了`82法则`,同时也起到了普及CSS预处理器的作用,事实上接触并且熟悉了LESS的那些概念之后,接受MCSS或者SCSS都是比较轻松的事情。

如果觉得LESS无法满足你的需求时

> __npm install -g mcss__ 尝试一下吧!

_同时MCSS是个易用的CSS Parser哦_

<br/>


免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请点击。


相关文章:
【推荐】 流式处理框架storm浅析(下篇)
【推荐】 细嚼慢咽 Mongoose 5

转载于:https://www.cnblogs.com/zyfd/p/10063524.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364742.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

jmeter找不到java.dll_Windows下Jmeter安装出现Not able to find Java executable or version问题解决方案...

最近在做一个开放接口平台性能测试 , 指标是最少达到1000/s的并发 , 接口鉴权 百万级的表 在1s内完成..在众多压测工具中 ,,选择了Apache的jmeter ,于官网下载了最新版本http://jmeter.apache.org/download_jmeter.cgi (jmeter下载地址)由于jmeter运行是基于java的,所以需要…

localStorage/cookie 用法分析与简单封装

本地存储是HTML5中提出来的概念&#xff0c;分localStorage和sessionStorage。通过本地存储&#xff0c;web应用程序能够在用户浏览器中对数据进行本地的存储。与 cookie 不同&#xff0c;存储限制要大得多&#xff08;至少5MB&#xff09;&#xff0c;并且信息不会被传输到服务…

使用Lucene的搜索服务器搜索Jira问题

您可能还记得我的第一篇博客文章&#xff0c;其中描述了Lucene开发人员如何使用Lucene搜索应用程序查找我们的Jira问题来食用我们自己的狗食。 该应用程序已成为许多Lucene现代功能的强大展示&#xff0c;例如侧向钻取和动态范围刻面&#xff0c; 基于中缀匹配的新建议 &#…

迭代加深搜索 C++解题报告 :[SCOI2005]骑士精神

题目 此题根据题目可知是迭代加深搜索。 首先应该枚举空格的位置&#xff0c;让空格像一个马一样移动。 但迭代加深搜索之后时间复杂度还是非常的高&#xff0c;根本过不了题。 感觉也想不出什么减枝&#xff0c;于是便要用到了乐观估计函数&#xff08;Optimistic Estimation …

一个web项目web.xml的配置中context-param配置作用

<context-param>的作用:web.xml的配置中<context-param>配置作用1. 启动一个WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> 和 <context-param></context-param>2.紧接着,容器创建一个Servl…

JavA持有类_关于继承:Java持有对象的超类的类型

本问题已经有最佳答案&#xff0c;请猛点这里访问。我有两个类动物和狗。因为你可以从动物身上延伸出来。我可以毫无问题地编写这些类&#xff0c;但我注意到我可以像这样创建一个新的dog对象&#xff1a;Dog firstDog new Dog("rocky");没关系&#xff0c;但是当我…

CSS3 选择器用法小结

表单选择器&#xff1a; /*:enabled 可用的 :disabled 被禁用的 :focus 获取了焦点的 多用在表单元素上*/ input:enabled {...} input:disabled {...} input:focus {...} 属性选择器&#xff1a; /*[attribute] [attributevalue] 选择具有对应属性的元素 即使此属性没有实际作…

Postgres和Oracle与Hibernate的兼容性

在某些情况下&#xff0c;您的JEE应用程序需要支持Postgres和Oracle作为数据库。 Hibernate应该在这里完成工作&#xff0c;但是有些细节值得一提。 在为已经运行Oracle的应用程序启用Postgres时&#xff0c;我遇到了以下棘手的部分&#xff1a; BLOBs支持&#xff0c; CLO…

Ubuntu|ython3 :ImportError: cannot import name 'main'

1、问题 rootstephen-K55VD:/usr/bin# pip3 Traceback (most recent call last):File "/usr/bin/pip3", line 9, in <module>from pip import main ImportError: cannot import name main2、解决办法 编辑/usr/bin/pip3&#xff0c;修改代码 from pip._interna…

51Nod 1362 搬箱子 —— 组合数(非质数取模) (差分TLE)

题目&#xff1a;http://www.51nod.com/Challenge/Problem.html#!#problemId1362 首先&#xff0c;\( f[i][j] \) 是一个 \( i \) 次多项式&#xff1b; 如果考虑差分&#xff0c;用一个列向量维护 0 次差分到 \( n \) 次差分即可&#xff0c;在第 \( n \) 次上差分数组已经是一…

java星座查询系统_星座查询示例代码

package api.jisuapi.astro;import api.util.HttpUtil;import net.sf.json.JSONArray;import net.sf.json.JSONObject;public class All {public static final String APPKEY "your_appkey_here";// 你的appkeypublic static final String URL "https://api.j…

Java 8 Friday Goodies:轻松派本地缓存

在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 &#xff0c;现在我们觉得是时候开始一个新的博客系列了…

【JS】使用变量作为object的key-方法汇总

1、方法一 1 var a id; 2 var str {a : 12} 3 var obj eval("("str")"); 结果&#xff1a; 1 obj{id:12} 2、方法二 1 var aname; 2 var obj{}; 3 obj[a]jack; 结果&#xff1a; 1 obj{name:jack} 3、方法三 1 var aage; 2 var obj{[a]:23}; 结果&…

JS数组与对象的遍历方法大全

本文简单解析各种数组和对象属性的遍历方法&#xff1a; 原生for循环、for-in及forEachES6 for-of方法遍历类数组集合Object.key()返回键名的集合jQuery的$.each()underscore的_.each() 文中的范例基于以下数组和对象。 var arrTmp ["value1","value2",&…

coordin.h与coordin.h

如果文件包含在尖括号中&#xff0c;则C编译器将在存储标准文件的主机系统的文件系统中查找&#xff1b; 如果文件名包含在双引号中&#xff0c;则编译器将首先查找当前的工作目录或源代码目录。如果没有在那里找到头文件&#xff0c;则将在标准位置查找。转载于:https://www.c…

java二嗨租车项目_Java入门第二季6-1租车项目代码

一共有5个类Car类 //作为父类package com.imooc;public class Car {public int ID;public String name;public int rent;public int PersonCapacity;public int GoodsCapacity;}2.passengerCar //客车public class passengerCar extends Car{public passengerCar(int newID,Str…

go语言基础知识笔记(二)之数组和切片

数组和切片知识用的也是比较多&#xff0c;的给我们工作带来很大的便利 &#xff08;一&#xff09; 数组 定义&#xff1a;在golang中数组的长度是不可变&#xff0c;数组存放要求是同一种数据类型 //golang中数组定义的四种方法1.先声明&#xff0c;后赋值  var arr1 [2]in…

错误处理在Spring Integration中如何工作

1.引言 这篇文章的目标是向您展示将消息传递系统与Spring Integration结合使用时如何处理错误。 您将看到同步和异步消息传递之间的错误处理有所不同。 和往常一样&#xff0c;我将跳过聊天并继续进行一些示例。 您可以在github上获取源代码。 2&#xff0c;样品申请 我将使用…

原生js、jQuery实现选项卡功能

在大家在网上平常浏览网页的时候&#xff0c;想必各位都会看到选项卡功能&#xff0c;在这里给大家详解一下用原生js、jQuery如何来写一些基本的选项卡 话不多说&#xff0c;先给各位看一下功能图&#xff1a; 好了&#xff0c;下边开始写代码了&#xff1a; HTML代码&#x…

.NET core2.0 发布至IIS中

.NET CORE和asp.net 发布时不太一样&#xff0c;ASP.NET Core不再是由IIS工作进程&#xff08;w3wp.exe&#xff09;托管&#xff0c;而是使用自托管Web服务器&#xff08;Kestrel&#xff09;运行&#xff0c;IIS则是作为反向代理的角色转发请求到Kestrel不同端口的ASP.NET Co…