SkillAgentSearch skills...

Mcss

writing modular css witch mcss

Install / Use

/learn @leeluolee/Mcss
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Writing abstract and modular CSS with MCSS

MCSS是一个CSS Preprocessor, 语法上基于CSS3 Syntax的超集, 提供 Nested Ruleset, Variable, first-class function(or mixin), custom atrule(@extend、@import、@abstract...)等等特性来填补原生CSS的抽象能力弱的缺陷, 帮助我们书写抽象化的CSS

MCSS是有丰富的语言特性的一个DSL, 它甚至允许扩展@atrule自定义解释策略; 与此同时MCSS是一个易用使用的CSS Parser, 并提供便利化的方式去操作树形结构, 以实现csscomb、prefixr等CSS工具.

MCSS完全使用javascript构建, 你可以分别在browser(ES5 support needed)和nodejs中使用它

目前主页正在建设中,这是临时性介绍页, 你可以先 动手试试

有兴趣可以查看下mcss的实例函数库(类似compass),你会发现几乎所有在mcss中都可以封装成函数的形势,如果你愿意

安装

Nodejs

npm install -g mcss

Browser

<script src="https://github.com/leeluolee/mcss/blob/master/dist/mcss-latest.js"></script>

需要支持ES5的浏览器,绝对只建议在线上环境使用compile后的css文件,而不是即时compile;

使用

API请参考(API使用指南)

命令行

一般就输入 mcss 输入目录或文件 -o 输出目录或文件 -w即可开启监听并编译了, 其他参数请参考mcss -h

ubuntu-10:12 ~ $ mcss -h

  Usage: mcss [options] <file>

  Options:

    -h, --help                print usage information
    -v, --version             print the version number
    -f, --format <n>          the outport format, 1: common | 2: compress | 3:online
    -c, --config <file>          the config filepath. [optional]
    ..........省略请输入 mcss -h 查看详情............

注意: 当file参数为文件夹时, 会compile目录下的所有.mcss文件, 此时outport参数会视为是一个文件夹, 并将所有css输入到此文件夹

####配置文件

当参数略多时,你会感觉筋疲力竭, 这时你可以建立一个配置的JSON文件, 其中JSON中的input参数代表输入文件 file, 其它与命令行打印的__参数全名__(比如format)一致 并使用-c 参数指定这个配置文件,默认情况下mcss会寻找 当前路径下的mcss.json 作为配置文件, 配置文件与命令的参数会进行合并(命令行优先)

{
  "input": "./",  //代表输入文件或目录
  "outport": "../css",  //输出目录(如果输入为单文件可以是一个具体的文件名)
  "format": 1,
  "watch": 2, //检测文件变化并build,并有报警声(1监听但无报警), 0为不watch
  "exclude": "(\/|\\\\)_|^_|include"
}

注意: 使用config文件之后,程序的current word dir 切换到config文件的所在目录!!!

浏览器端

Browser环境时, 除了可以使用对应的API, mcss还会自动解释在mcss.js所在script标签前的所有style[type='text/mcss']link[rel='stylesheet/mcss']的标签, 而其后的mcss文件不会生效. 如:

<link rel="stylesheet/mcss" href="test.mcss"/>
<style type = 'text/mcss'>
  $color = #fff;
  $border-radius = ($radius = 5px){
    -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    border-radius: 5px;
  }
  p{
    border: 2px solid hsla(10, 90%, 21%, 0.1);
    $border-radius: 5px; 
  }
</style>
<script src="../../dist/mcss-0.0.1.js"></script>
<link rel="stylesheet/mcss" href="test2.mcss"/>

其中test2.mcss不会生效

语言特性描述

了解特性之前,需要了解下mcss的基本数据类型(与css syntax对应) MCSS的数据类型

有时也需要了解下选择器的基本概念, 可以去nes的选择器科普页了解下

需要注意的是,由于mcss是css的超集, __ 标准css即标准mcss__

nested ruleset

mcss支持层级嵌套的ruleset以及 & (父引用符号)

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

输出

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

mcss支持另外一种预置符%, 代表除最外层选择器之外的选择器序列 如:

.ms-form{
    // 真不想重复写这么多啊
    input[type="text"],
    input[type="password"],
    input[type="email"],
    input[type="url"],
    input[type="date"],
    input[type="month"],
    input[type="time"],
    input[type="range"],
    select{
      display: inline-block;
      .ms-form-stack %{
        display: block;
      }
    }
    // other ruleset
}

输出

.ms-form input[type="text"],.ms-form input[type="password"],.ms-form input[type="email"],.ms-form input[type="url"],.ms-form input[type="date"],.ms-form input[type="month"],.ms-form input[type="time"],.ms-form input[type="range"],.ms-form 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"],.ms-form-stack  input[type="date"],.ms-form-stack  input[type="month"],.ms-form-stack  input[type="time"],.ms-form-stack  input[type="range"],.ms-form-stack  select{
  display:block;
}

和类似NEC的解决方案相契合

赋值操作

mcss中的variable与以 $ 开头(与SCSS一致如$length), 这也是mcss引入的唯一一个非css规范的词法类型, 目的是 防止潜在冲突视觉上更易识别 mcss支持三种赋值操作^=, =?=, 其中?= 只在变量未赋值或null时生效, 所有的值类型都可以被赋值,包括函数, ^= 表示将赋值操作提升到全局作用域,

// $variable has scope
$a = 10px;
$a ?= 20px;

body{
    left: $a; // exports left: 10px;
}

// override before
$a = 30px;

body{
    left: $a; // exports left: 30px;
}

// function is also a value can be assigned
$fn ?= ($name) {
    left: $name;
}

输出

body{
  left:10px;
}
body{
  left:30px;
}

由于mcss有严格作用域划分,所以有时候你想跳脱作用域限制时'^='这个赋值符可以解决一些封装的问题, 让几乎所有形式的组件都可以封装成函数的形式,比如

$import-raw = false;

$reset-var = (){
  $import-raw ^= true; //这个会影响到外层
}

$reset-var();//调用

body{
  left: $import-raw;
}

输出:

body{
  left:true;
}

强大的function (mixin)

函数是mcss中除了css syntax中定义的值类型之外, 引入的唯一一种数据类型, 与js一样 mcss中的函数, 可以传递给函数,也可以在函数中被返回, 并保留定义时的作用域链(所谓的闭包)。

mcss中函数可以是一个block, 它可以有参数列表也可以没有

1. 作为mixin混入使用

当function没有返回值时,函数成为一个mixin, 会将解释后的 function block输出,实现SCSS中的@include, 这也是最常用的方式

// 带参数
$size = ($width, $height){
    $height ?= $width;
    height: $height; 
    width: $width; 
}
// 不带参数, 可视为一个block模版  
$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;
}

2. 作为函数使用

在解释function block时, 遇到了 @return 语句, 则中断返回. 注意返回值可以是另外一个函数. mcss 函数本质上与mcss的javascript实现的内建函数是一致的,优势是 不需要树节点操作 。并且维护在mcss file中更易模块化。

$abs = ($value){
    @if $value < 0 {
        @return -$value; }
    @return $value;
}
$min = (){
    $res = index($arguments, 0);
    @for $item of $arguments{
        @if $item < $res {
            $res = $item; }}
    @return $res;
}
@debug $min(1, 2, 3, 4, 0); // -> 0

@debug $abs(-100px);   // 100px

3. transparent call

mcss支持类似 stylus 的transparent call (只适用于作为mixin使用的function)的调用方式

$border-radius = ($args...){
    @if !len($args) { 
        error('$border-radius Requires at least one paramete')}
    $value = join($args, ' / ');
    -webkit-border-radius: $value;
       -moz-border-radius: $value;
            border-radius: $value;
}
body{
    $border-radius: 10px 20px;
    $border-radius: 10px 20px 100% , 20px; 
}

输出为

body{
  -webkit-border-radius:10px 20px;
  -moz-border-radius:10px 20px;
  border-radius:10px 20px;
  -webkit-border-radius:10px 20px 100% / 20px;
  -moz-border-radius:10px 20px 100% / 20px;
  border-radius:10px 20px 100% / 20px;
}

4. 参数

mcss支持丰富的参数类型: rest param 以及 default paramnamed param;


// 缺省值
$default-param = ($left, $right = 30px ){
    default-param: $right;
}
// named param 一般用在大量default 只需要传入部分参数的情况下
$named-param = ($color = 30px, $named){
    named: $named;
}

$rest-at-middle = ($left, $middle... , $right){
    rest-at-middle: $middle;
}
$rest-at-left = ($left... , $right){
    rest-at-left: $left;
}
$rest-at-right = ($left,$right...){
    rest-at-right: $right;
}

body{
    $named-param($named = 30px);
    $default-param(10px);
    $rest-at-middle(1, 2, 3, 4);
    $rest-at-left(1, 2, 3, 4);
    $rest-at-right(1, 2, 3, 4);
}

输出 :

body{
  named: 30px;
  default-param:30px;
  rest-at-middle:2,3;
  rest-at-left:1,2,3;
  rest-at-right:2,3,4;
}

注意rest param 不能有默认值, 在参数有named param时 这个参数会被从参数列表中剔除,剩余的参数再进行赋值

5. 作为一种数据类型的函数

函数可以被传入函数, 也可以被函数返回. 并且保留当前完整作用域链

函数可以被返回:

$pos = ($position, $top, $left){
    @if len($arguments) == 1{
        // 返回函数
        @return ($top, $left){
            $pos($position, $top, $left);
        }
    }
    position: $position;
    left: $left;
    top: $top;
}

$relative = $pos(relative);
$fixed = $pos(fixed);
$absolute = $pos(absolute);

body{
    $absolute(10px, 20px);
    // ==   $pos(relative, 10px, 20px);
}

输出:

body{
  position:absolute;
  left:20px;
  top:10px;
}

6. $arguments以及其他

在进入function block时, mcss会在当前作用域定义一个变量叫$arguments(Type: valueslist), 代表传入的所有参数

mcss不支持类似arguments[0]下标操作, 不过你可以通过内建函数 args(0)来得到同样的效果

$foo = {
  first: args(0);
  seconed: args(1);
  arguments: $arguments
}
body{
    $foo: 10px, 20px
}

输出

body{
  first:10px;
  seconed:20px;
  arguments:10px,20px;
}

注释

支持行注释// 和块注释/**/

Atrule

除了变量之外,所有的功能扩展,mcss都采用扩展@atkeyword的方式, 对于规范外的atrule(SCSS称之为directive)并且mcss也未定义, 开发者如果传入了对应的函数则根据传入函数的策略解释这个片段(), 否则按css基本规则输出(比如mcss中的-moz-document、charset等都没有进行定义 但是仍可以正确输出)

以下介绍: mcss中定义了的atruleset

@extend

继承由输入的complexselector指定的base ruleset, 表现为在在另一个base ruleset中组合进的selector.

@extend是css preprocessor中另一个较重要的特性,可以帮助我们缓解在html写入过多类名的泥潭

mcss中的@extend 有以下特性:

1. 需完整描述complex selector

这样做首先是为了避免歧义, 如:

.class-1 span{
    name: class-1;
}
.body-1{
    // need specify the full complex selector
    // if only `span` will not work( but work in scss)
    @extend .class-1 span;
}

输出:

.class-1 span,.body-1{
  name:class-1;
}

2. 有作用域

与参数一样, 会优先获取内层作用域的的base ruleset, 并且只能使用定义过的base ruleset(也就是说无法后向引用), 这个是为了规避循环@extend;

class-1{
    name: class-1 in global;
}

div.body-4, .other-body{
    cl
View on GitHub
GitHub Stars152
CategoryContent
Updated7mo ago
Forks17

Languages

CSS

Security Score

87/100

Audited on Aug 24, 2025

No findings