CSS - 浅析css预处理器

为什么要预处理器

css层叠样式表是一门标记语言,并不是编程语言,因此不可以自定义变量,不可以引用等,它不具备任何语法支持,它主要缺陷如下:

  • 语法不够强大,比如:无法嵌套书写,导致模块化开发中需要书写很多重复的选择器;
  • 没有变量和合理的样式复用机制,使得逻辑上相关的属性值必须以字面量的形式重复输出,导致难以维护

这就导致了我们在工作中无端增加了许多工作量。为了解决这个问题,前端开发人员会使用一种称之为 【CSS 预处理器】 的工具,提供 CSS 缺失的样式层复用机制、减少冗余代码,提高样式代码的可维护性。大大提高了前端在样式上的开发效率。

什么是CSS预处理器

CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行 CSS 的编码工作。就是“用一种专门的编程语言,进行 Web 页面样式设计,再通过编译器转化为正常的 CSS 文件,以供项目使用”。

CSS预处理器为CSS增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在CSS中使用变量、简单的逻辑程序、函数等等在编程语言中的一些基本特性,可以让你的CSS更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。

常用的CSS预处理器

  • SASS

    基于 Ruby,通过服务端处理,功能强大。解析效率高。需要学习 Ruby 语言,上手难度高于 LESS。

  • LESS

    基于 NodeJS,通过客户端处理,使用简单。功能比 SASS 简单,解析效率也低于 SASS,但在实际开发中足够了,所以我们后台人员如果需要的话,建议使用 LESS。

  • Stylus

    2010年产生,来自Node.js社区。主要用来给Node项目进行CSS预处理支持,在此社区之内有一定支持者,在广泛的意义上人气还完全不如SASS和LESS。

  • 详细比较css预处理器

LESS详解

less语法
  • 注释:less 的注释可以有两种。

    • 第一种注释:模板注释
      // 模板注释 这里的注释转换成CSS后将会删除
    

    因为 less 要转换为 css才能在浏览器中使用。转换成 css 之后,这种注释会被删除(毕竟 css 不识别这种注释)。

    • 第二种注释:CSS 注释语法
    /* CSS 注释语法 转换为CSS后让然保留 */
    

    总结:如果在less中写注释,我们推荐写第一种注释。除非是类似于版权等内容,就采用第二种注释。

  • 定义变量

    我们可以把重复使用或经常修改的值定义为变量,在需要使用的地方引用这个变量即可。这样可以避免很多重复的工作量。

    (1)在less文件中,定义一个变量的格式:

    @变量名: 变量值;        //格式
    @bgColor: #f5f5f5;      //格式举例
    

    (2)同时,在 less 文件中引用这个变量。

    最终,less文件的完整版代码如下:

    main.less:

    // 定义变量
    @bgColor: #f5f5f5;
    
    // 引用变量
    body{
        background-color: @bgColor;
    }
    

    我们将上面的less文件编译为 css 文件后(下一段讲less文件的编译),自动生成的代码如下:

    main.css:

    body{
        background-color: #f5f5f5;
    }
    
  • 使用嵌套

    在 css 中经常会用到子代选择器,效果可能是这样的:

    .container {
      width: 1024px;
    }
    
    .container > .row {
      height: 100%;
    }
    
    .container > .row a {
      color: #f40;
    }
    
    .container > .row a:hover {
      color: #f50;
    }
    

    上面的代码嵌套了很多层,写起来很繁琐。可如果用 less 的嵌套语法来写这段代码,就比较简洁。

    嵌套的举例如下:

    main.less:

    .container {
      width: @containerWidth;
    
      > .row {
        height: 100%;
        a {
          color: #f40;
    
          &:hover {
            color: #f50;
          }
    
        }
      }
    
      div {
        width: 100px;
    
        .hello {
          background-color: #00f;
        }
    
      }
    }
    

    将上面的less文件编译为 css 文件后,自动生成的代码如下:

    main.css

    .container {
        width: 1024px;
    }
    
    .container > .row {
        height: 100%;
    }
    
    .container > .row a {
        color: #f40;
    }
    
    .container > .row a:hover {
        color: #f50;
    }
    
    .container div {
        width: 100px;
    }
    
    .container div .hello {
        background-color: #00f;
    }
    
  • Mixin

    Mixin 的作用是把重复的代码放到一个类当中,每次只要引用类名,就可以引用到里面的代码了,非常方便。

    (1)在 less 文件中定义一个类:(将重复的代码放到自定义的类中)

    /* 定义一个类 */
    .roundedCorners(@radius: 5px) {
      -moz-border-radius: @radius;
      -webkit-border-radius: @radius;
      border-radius: @radius;
    }
    

    上方代码中,第一行里面,括号里的内容是参数:这个参数是缺省值

    (2)在 less 文件中引用上面这个类:

    #header {
      .roundedCorners;
    }
    #footer {
      .roundedCorners(10px);
    }
    

    上方代码中,header 中的引用没有带参数,表示参数为缺省值; footer 中的引用带了参数,那就用这个参数。

  • Import

    在开发阶段,我们可以将不同的样式放到多个文件中,最后通过@import 的方式合并。意思就是,当出现多个 less 文件时,怎么引用它们。

    css 文件可以有很多个,less文件也可以有很多个。

    (1)定义一个被引用的less文件_button.less

    .btn{
      line-height: 100px;
      color: @btnColor;
    }
    

    注意:- 被引用的less文件,我们习惯在前面加下划线,表示它是部分文件_button.less里可以引用main.css里的自定义变量

    (2)在main.css中引用上面的_button1.less

    main.css:

    @btnColor: red;
    @import url('_button.less'); //这里的路径写的是相对路径
    body{
      width: 1024px;
    }
    

    将 上面的main.less 编译为 main.css之后,自动生成的代码如下:

    .btn {
        line-height: 100px;
        color: red;
    }
    body {
        width: 1024px;
    }
    
  • 内置函数

    less 里有一些内置的函数,这里讲一下 lighten 和 darken 这两个内置函数。

    main.less:

    body{
      backgroud-color: lighten(#000, 10%); //让黑色变亮10%
      color: darken(#fff, 10%); //让白色变暗10%
    }
    

    将 上面的 main.less 编译为 main.css 之后,自动生成的代码如下:

    main.css:

    body {
      background-color: #1a1a1a;
      color: #e6e6e6;
    }
    
  • 如何引用less

    • 做法一:写完 less文件后,将其编译为 css 文件(less 的编译指的是将写好的 less 文件 生成为 css 文件。less 的编译,依赖于** NodeJS 环境**。),然后在代码中引用css文件。
    • 做法二:在代码中直接用引用 less 文件。其实是浏览器在本地在线地把 less 文件转换为 css 文件。

    产品上线后,当然是使用做法一,因为做法二会多出编译的时间。

    平时开发或演示demo的时候可以用做法二。

Stylus详解

  • 安装

    npm install stylus -g
    
  • 基本使用

    1、在安装目录下新建index.styl 文件,再新建index文件夹,在index文件夹里新建index.html;

    //css.styl文件
    div
      color:red;
      
    //index.html文件
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <link rel="stylesheet" type="text/css" href="css.css">
    </head>
    <body>
      <div>我是div</div>  
    </body>
    </html>
    

    2、输入 stylus -w index.styl -o index 进行转译成css文件 ;

    -w index.styl - 自动监测css.styl文件的变化

    -o index - 将编译后的同名的index.css文件放到index文件夹中

    3、直接在css.styl写stylus即可

  • 基本语法

    stylus中文参考文档

    • 语法自由度举例

      //index.html
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>Document</title>
          <link rel="stylesheet" type="text/css" href="index.css">
      </head>
      <body>
        <div class="div1">我是div1,我有花括号,冒号和分号</div>
        <div class="div2">我是div2,我无花括号,但有冒号和分号</div>
        <div class="div3">我是div3,我无花括号、冒号,但有分号</div>
        <div class="div4">我是div4,我无花括号、冒号、分号</div>
        <div class="div5">我是div5,我有花括号,但无冒号、分号</div>
      </body>
      </html>
      //index.styl
      //1、 有花括号,冒号和分号
      .div1 {
        color: red;
      }
      //2、 无花括号,但有冒号和分号
      .div2
        color: green;
      // 3 、无花括号、冒号,但有分号
      .div3
        color blue;
      // 4 、无花括号、冒号、分号
      .div4
        color greenyellow
      // 5 、有花括号,但无冒号、分号
      .div5{
        color rosybrown
      }
      
    • 变量

      stylus的变量名除了不能以@开头以外,其它都可以

      //html文件
      <div class="bianliang"> 变量示范 </div>
      //styl文件
      largeFontSize = 50px
      $borderStyle=solid
      
      .bianliang
        font-size largeFontSize
        border 1px $borderStyle red
      
    • 嵌套

      //html
        <div class="parent">
            <div class="child">
                <p>我是child里的p</p>
            </div>
        </div>
      //styl
      .parent {
        border 1px solid red
      
        .child {
          border 2px solid green
      
          p {
            font-size 50px
            &:hover{
              color green
            }
          }
            // hover下面的写法也可以
            //p:hover{
            //  color red
            //
            //}
        }
      }
      
    • 混入

      <div class="mixin1">混入示例1</div>
      <div class="mixin2">混入示例2</div>
      
      setBorder($borderwidth = 1px){
        border $borderwidth solid red
      }
      .mixin1{
        width 200px 
        height 200px
        setBorder()
      }
      .mixin2{
        width 100px
        height 100px
        setBorder(5px)
      }
      

      其实这里可以衍生出下面的语法

      border-radius(values){
         -webkit-border-radius: values;
            -moz-border-radius: values;
                 border-radius: values;
      }
      div{
        border-radius(10px);
      }
      
    • 继承

      有时候不同元素的一些css语句是一样的,如果不采用继承的语法,就需要将各个元素单独拎出来,然后写相同语法,这样的缺点就是,不能够在原来选择器中直接写样式,需要重新写个相同的选择器再写样式。如果使用继承语法,就不存在这种情况了。

      <div class="jicheng">
            我是继承示例
            <div class="parent1">
                我是parent1
                <div class="child1">
                    我是child1 <div>我是个没有class和id 的div</div>
                    <p>我是child1里的p--- <span>我是p里的span</span> </p>
                </div>
            </div>
      </div>
      
      .reset{
        margin 0;
        padding 0;
        border 1px solid red
      }
      .jicheng{
        @extend .reset
        color red
        .parent1{
          @extend .reset
          color green
          .child1{
            @extend .reset
            color blue
            p{
              @extend .reset
              color yellow
            }
          }
        }
      }
      

      如果我们不使用继承的话,可能需要这样写:

      .jicheng, .jicheng .parent1,.parent1 .child1,.child1 p{
        margin 0
        padding 0
        border 1px solid red
      }
      .jicheng{
        color red
        .parent1{
          color green
          .child1{
            color blue
            p{
              color yellow
            }
          }
        }
      }
      
    • 颜色

      其里面有内置的颜色函数,可以用来调整颜色亮度、饱和度等;举例

      <div class="color-function">
          颜色函数
          <div class="dark">我变暗了</div>
          <div class="baohedu">饱和度降低了</div>
      </div>
      
      colorValue=red
      .color-function{
        background-color colorValue
        .dark{
          background-color darken(colorValue,50%)
        }
        .baohedu{
          background-color desaturate(colorValue,40%)
          }
      }
      
    • 运算符

      <div class="yunsuanfu">
         运算符例子
      </div>
      
      .yunsuanfu
        font-size 30px+30px
        margin 10px+20px
      
    • 条件

      <div class="tiaojian">
          <div class="have">条件语句--有margin</div>
          <div class="have-not">条件语句--没有margin</div>
      </div>
      
      box(x,y,haveMargin=false)
        padding x y
        if haveMargin
          margin x y
      .tiaojian{
        div{
          border 1px solid red
        }
        .have{
          box(10px,10px,true)
        }
        .have-not{
          box(10px,20px,false)
        }
      }    
      
    • 迭代

      <div class="diedai">
        迭代示例
      </div>
      .diedai{
        for n in 1 2 3
        z-index n
      }
      
posted @ 2019-09-18 09:54  sunidol  阅读(193)  评论(0编辑  收藏  举报