天天看点

系统学习——Less

文章目录

    • 概览
      • 什么是 CSS 预处理器?
      • Less 简介
      • 变量
      • 混合
      • 嵌套规则
      • 函数 & 运算
    • less的安装和使用
      • 客户端
        • 客户端使用
        • 监视模式
      • 服务端
        • 服务端安装
        • 服务器端Less的使用
    • 语法
      • 注释
      • 变量
        • 基本使用
        • 用变量名定义为变量
      • 混合
        • 基础混合
        • 带参混合
        • @arguments 变量
      • 模式匹配
        • 简单参数匹配
        • 导引
        • 常见的检测函式
        • 更多检测函式
        • 逻辑运算
      • 嵌套规则
      • 运算
      • Color 函数

概览

什么是 CSS 预处理器?

  • 定义:CSS 预处理器定义了一种新的语言,其基本思想是,用一种专门的编程语言,为 CSS 增加了一些编程的特性,将 CSS 作为目标生成文件,然后开发者就只要使用这种语言进行编码工作。
  • Less 是CSS预处理器之一。
  • 简而言之:CSS 预处理器用一种专门的

    编程语言

    ,进行 Web 页面样式设计,然后再

    编译

    成正常的 CSS 文件,以供项目使用。CSS 预处理器为 CSS 增加一些编程的特性,无需考虑浏览器的兼容性问题,例如你可以在 CSS 中使用

    变量

    简单的逻辑程序

    函数

    等等在编程语言中的一些基本特性,可以让你的 CSS 更加简洁、适应性更强、可读性更佳,更易于代码的维护等诸多好处。
  • 常见的CSS预处理器语言:LESS、Sass(SCSS)、Stylus、Turbine、Swithch CSS、CSS Cacheer、DT CSS

Less 简介

  • LESS 赋予了 CSS 动态语言的特性,如

    变量

    继承

    运算

    函数

    。LESS 既可以在 客户端 上运行 (支持IE 6+, Webkit, Firefox),也可以借助Node.js或者Rhino在服务端运行。
    /*  LESS */
    @color: #4D926F;
    
    #header {
      color: @color;
    }
    h2 {
      color: @color;
    }
     
     /* 编译为css */
     #header {
      color: #4D926F;
    }
    h2 {
      color: #4D926F;
    }
               

变量

  • 变量允许我们单独定义一系列 通用 的样式,然后在需要的时候去调用。所以在做 全局样式 调整的时候我们可能只需要修改几行代码就可以了。
    /* 定义变量 bgcolor 设置值为 #4D926F */
    @bgcolor: #4D926F; 
    
    #header {
      background: @bgcolor;
    }
    
    /* 编译为css */
    #header {
      background: #4D926F;
    }
               

混合

  • 混合可以将一个定义好的class A轻松的引入到另一个class B中,从而简单实现class B

    继承

    class A中的

    所有属性

    。我们还可以带

    参数

    地调用,就像使用函数一样。
    .rounded-corners (@radius: 5px) { // 定义函数,并设置参数默认值
      border-radius: @radius;
      -webkit-border-radius: @radius;
      -moz-border-radius: @radius;
    }
    
    #header {
      .rounded-corners; // 不传参引用
    }
    #footer {
      .rounded-corners(10px); // 传参引用
    }
    
    /* 编译为css */ 
    #header {
      border-radius: 5px;
      -webkit-border-radius: 5px;
      -moz-border-radius: 5px;
    }
    #footer {
      border-radius: 10px;
      -webkit-border-radius: 10px;
      -moz-border-radius: 10px;
    }
               

嵌套规则

  • 我们可以在一个选择器中

    嵌套

    另一个选择器来实现

    继承

    ,这样很大程度减少了代码量,并且代码看起来更加的清晰。
    #header {
      h1 {
        font-size: 26px;
        font-weight: bold;
      }
      p { font-size: 12px;
        a { text-decoration: none;
          &:hover { border-width: 1px }
        }
      }
    }
    
    /* 编译后 */
    #header h1 {
      font-size: 26px;
      font-weight: bold;
    }
    #header p {
      font-size: 12px;
    }
    #header p a {
      text-decoration: none;
    }
    #header p a:hover {
      border-width: 1px;
    }
               

函数 & 运算

  • LESS中的函数一一映射了

    JavaScript

    代码,如果愿意的话可以操作属性值。
  • 运算提供了 加,减,乘,除 操作;我们可以做

    属性值和颜色

    的运算,这样就可以实现属性值之间的复杂关系。
    @the-border: 1px;
    @base-color: #111;
    @red:        #842210;
    
    #header {
      color: @base-color * 3; // 乘法运算
      border-left: @the-border;
      border-right: @the-border * 2;
    }
    #footer { 
      color: @base-color + #003300; // 加法运算
      border-color: desaturate(@red, 10%); // 预定义颜色函数
    }
    
    /* 编译为css */
    #header {
      color: #333;
      border-left: 1px;
      border-right: 2px;
    }
    #footer { 
      color: #114411;
      border-color: #7d2717;
    }
               

less的安装和使用

客户端

客户端使用

  • 引入你的

    .less

    样式文件的时候要设置

    rel

    属性值为

    stylesheet/less

    <link rel="stylesheet/less" type="text/css" href="styles.less">
               
  • 接着 下载less.js,并在

    <head>

    标签中引入

    less.js

    <script src="less.js" type="text/javascript"></script>
    <!-- 如果不想下载就使用下面这种方式 -->
    <script src="//cdnjs.cloudflare.com/ajax/libs/less.js/2.5.3/less.min.js"></script>
               
  • 注意: 你的less样式文件一定要在引入less.js前先引入。 备注:请在服务器环境下使用!本地直接打开可能会报错!

监视模式

  • 监视模式是客户端的一个功能,这个功能允许你当你改变样式的时候,客户端将自动刷新。
  • 要使用它,只要在URL后面加上

    #!watch

    ,然后刷新页面就可以了。另外,你也可以通过在终端运行

    less.watch()

    来启动监视模式。

服务端

服务端安装

  • 最简单的方式是通过 npm(node 的包管理器)
    $ npm install less
    
    // 下载最新稳定版本的 LESS,
    $ npm install [email protected]
               

    NPM

    的全称是 Node Package Manager ,是一个 NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准。

服务器端Less的使用

  • 只要安装了 less,就可以在Node中像这样调用编译器:
    var less = require('less');
    
    less.render('.class { width: 2 + 3 }', function (e, css) {
        console.log(css);
    });
               
    输出:
    .class {
      width: 5;
    }
               
  • 也可以手动调用解析器和编译器:
    var parser = new(less.Parser);
    parser.parse('.class { width: 1 + 1 }', function (err, tree) {
        if (err) { return console.error(err) }
        console.log(tree.toCSS());
    });
               
  • 配置:向解析器传递参数
    var parser = new(less.Parser)({
        paths: ['.', './lib'], // 指定 @import 指令的搜索路径
        filename: 'style.less' // 指定文件名,以获得更好的错误消息
    });
    
    parser.parse('.class { width: 2 + 3 }', function (e, tree) {
        tree.toCSS({ compress: true }); // 开启CSS压缩
    });
               
  • 在命令行下使用

    在终端调用 LESS 解析器:

    $ lessc styles.less
               
    上面的命令会将编译后的 CSS 传递给 stdout, 你可以将它保存到一个文件中:
    $ lessc styles.less > styles.css
               

语法

注释

  • CSS注释:CSS 形式的注释在 LESS 中是依然保留的。
    /* 你好,这里是Less中的一种注释,保留CSS注释形式 */
    .class { color: black }
               
  • less注释:LESS 同样也支持双斜线的注释, 但是编译成 CSS 的时候自动过滤掉。
    // 你好我是一个单行注释, 在编译成CSS文件是我将被过滤掉
    .class { color: white }
               

变量

基本使用

  • LESS中也可以设置变量,然后通过变量可以改变整个网站的设计风格。良好的掌握LESS中变量的用法,是LESS的基础。
  • 使用方法:在“

    @

    ”后添加变量名称然后与变量值用冒号“

    :

    ”链接。
    @nice-blue: #5B83BE;
    @light-blue: @nice-blue + #111;
    
    #header { color: @light-blue; }
    
    /** 编译为css之后 **/
    #header { color: #6C94CF; }
               

用变量名定义为变量

  • 示例:
    @loen: "I am loen.";
    @var: 'loen';
    
    content: @@var;
    
    /** 编译为css之后 **/
    content: "I am loen.";
               
  • 解析:

    @@var

    中的

    @var

    编译后变为

    loen

    ,此时less代码变为

    content: @loen

    ,而

    @loen

    则被认为是另一个变量,其值为

    I am loen.

    ,所以最终的结果如上所示。
注意: LESS 中的变量为完全的 ‘常量’ ,所以只能定义一次。

混合

基础混合

  • 在 LESS 中我们可以定义一些 通用 的属性集为一个class,然后在另一个class中去调用这些属性。
    .bordered {
      border-top: dotted 1px black;
      border-bottom: solid 2px black;
    }
               
  • 如果我们现在需要在其他class中引入通用的属性集,那么我们只需要在任何class中像下面这样调用就可以了:
    #menu a {
      color: #111;
      .bordered; //引用属性集
    }
    .post a {
      color: red;
      .bordered; //引用属性集
    }
    
    /** 编译后的css **/
    #menu a {
      color: #111;
      border-top: dotted 1px black;
      border-bottom: solid 2px black;
    }
    .post a {
      color: red;
      border-top: dotted 1px black;
      border-bottom: solid 2px black;
    }
               
    任何 CSS

    class

    ,

    id

    或者

    元素

    属性集都可以以同样的方式引入.

带参混合

  • 在 LESS 中,还可以像函数一样定义一个带参数的属性集合:
    .border-radius (@radius) {
      border-radius: @radius;
      -moz-border-radius: @radius;
      -webkit-border-radius: @radius;
    }
               
  • 调用:
    #header {
      .border-radius(4px);
    }
    .button {
      .border-radius(6px);  
    }
    
    /** 编译为css **/
    #header {
      border-radius: 5px;
      -moz-border-radius: 5px;
      -webkit-border-radius: 5px;
    }
               
  • 参数数设定默认值
    .border-radius (@radius: 5px) {
      border-radius: @radius;
      -moz-border-radius: @radius;
      -webkit-border-radius: @radius;
    }
               
  • 调用:
    #header {
      .border-radius;  
    }
    
    /** 编译为css **/
    #header {
      border-radius: 5px;
      -moz-border-radius: 5px;
      -webkit-border-radius: 5px;
    }
               

@arguments 变量

  • 如果属性集合需要传进来的参数比较多, 你又不想单独处理每一个参数的话,可以使用

    @arguments

    .

    @arguments

    包含了所有传递进来的参数。类似于javascript中函数的默认参数

    argument[]

    .box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
      box-shadow: @arguments;
      -moz-box-shadow: @arguments;
      -webkit-box-shadow: @arguments;
    }
    
    #leftbox {
    .box-shadow(2px, 5px);
    }
    
    /** 编译为css后 **/
    #leftbox {
      box-shadow: 2px 5px 1px #000;
      -moz-box-shadow: 2px 5px 1px #000;
      -webkit-box-shadow: 2px 5px 1px #000;
    }
               
    @arguments 保存了所有参数通过

    空格

    隔开的字符串

模式匹配

简单参数匹配

  • 有些情况下,我们想根据传入的参数来改变混合的默认呈现:
    .mixin (dark, @color) {
      color: darken(@color, 10%); // darken 是Less自带的函数用以计算颜色的深色
    }
    .mixin (light, @color) {
      color: lighten(@color, 10%); // lighten 计算颜色的浅色
    }
    .mixin (@_, @color) {// @_ 接受任意值
      display: block;
    }
    
    @switch: light;
    
    .class {
      .mixin(@switch, #888);
    }
    
    /** 编译为css后 **/
    .class {
      color: #a2a2a2;
      display: block;
    }
               
    原理:.mixin就得到传入的是

    light

    ,第一个混合定义并未被匹配,因为它只接受

    dark

    做为首参。第二个混合定义被成功匹配,因为它只接受

    light

    。第三个混合定义被成功匹配,因为它接受任意值,只有被匹配的混合才会被使用。变量可以匹配任意的传入值,而变量以外的固定值就仅仅匹配与其相等的传入值。
    当然传参也不限定于一个,可以多个不定的参数。

导引

  • 当我们想根据 表达式 进行匹配,而非根据 值和参数 匹配时,导引就显得非常有用。
    在 c,php 等编程语言中,条件判断一般使用

    if/else

    实现 Less 为了尽可能地保留CSS的

    可声明性

    ,通过导引混合而非if/els e语句来实现条件判断,因为Less已在 @media query特性中被定义。
    //when关键字用以定义一个导引序列
    .mixin (@a) when (lightness(@a) >= 50%) {
      background-color: black;
    }
    .mixin (@a) when (lightness(@a) < 50%) {
      background-color: white;
    }
    .mixin (@a) {
      color: @a;
    }
    
    .class1 { .mixin(#ddd) }
    .class2 { .mixin(#555) }
    
    /** 编译为css后 **/
    .class1 {
      background-color: black;
      color: #ddd;
    }
    .class2 {
      background-color: white;
      color: #555;
    }
               
  • 导引中可用的全部比较运算有:

    > >= = =< <

    。此外,关键字

    true

    只表示布尔真值,下面两个混合是相同的:
    .truth (@a) when (@a) { ... }
    .truth (@a) when (@a = true) { ... }
    
    //除去关键字true以外的值都被视示布尔假:
    .class {
      .truth(40); // 将不匹配以上定义
    }
               
  • 导引序列使用逗号

    ,

    分割,只要有一个符合条件就会执行
  • 导引可以无参数,也可以对参数进行比较运算:
    @media: mobile;
    
    .mixin (@a) when (@media = mobile) { ... }
    .mixin (@a) when (@media = desktop) { ... }
    
    .max (@a, @b) when (@a > @b) { width: @a }
    .max (@a, @b) when (@a < @b) { width: @b }
               
  • 最后,如果想基于

    值的类型

    进行匹配,可以使用

    is*

    函式:
    .mixin (@a, @b: 0) when (isnumber(@b)) { ... }
    .mixin (@a, @b: black) when (iscolor(@b)) { ... }
               

常见的检测函式

  • iscolor isnumber isstring iskeyword isurl

  • 示例:
    .mixin (@a, @b: 0) when (isnumber(@b)) {
        width: @a px;
        height: @b px;
    }
    .mixin (@a, @b: black) when (iscolor(@b)) {
        color: @a;
        background-color: @b;
    }
    // 调用
    .nav {
    .mixin(100,100);
    }
    .banner {
    .mixin(#333,#efefef);
    }
    
    /** 编译为css后 **/
    .nav {
      width: 100 px;
      height: 100 px;
    }
    .banner {
      color: #333;
      background-color: #efefef;
    }
               

更多检测函式

  • ispixel ispercentage isem

  • 示例:
    .mixin (@a, @b: 0) when (ispixel(@b)) {
        width: @a;
        height: @b;
    }
    .mixin (@a, @b: 50%) when (ispercentage(@b)) {
        max-width: @a;
        max-height: @b;
    }
    // 使用
    .nav {
    .mixin(100px,100px);
    }
    .banner {
    .mixin(80%,60%);
    }
    
    /** 编译为css后 **/
    .nav {
      width: 100px;
      height: 100px;
    }
    .banner {
      max-width: 80%;
      max-height: 60%;
    }
               

逻辑运算

  • and

    运算符 ,相当于

    运算

    &&

    ,必须条件全部为 true才会执行
    .mixin (@a) when (isnumber(@a)) and (@a > 0) {
        z-index: @a;
    }
    
    .leftbox {
    .mixin(12);
    }
    
    /** 编译为css后 **/
    .leftbox {
      z-index: 12;
    }
               
  • ,

    逗号分隔符:相当于

    运算

    ||

    ,只要有一个条件为true 就会执行
    .font(@size:20px) when (@size>50px) , (@size<100px){
        font-size: @size;
    }
    
    .desc{
    	.font(6px);
    }
    /** 编译为css后 **/
    .desc{
    	font-size:6px;
    }
               
  • not

    运算符,相当于

    运算

    !

    ,进行取反操作, 所以当条件为false, 就会执行
    .mixin (@b) when not (@b > 0) {
        left: @b;
    }
    
    .gameball {
    .mixin(-15);
    }
    
    /** 编译为css后 **/
    .gameball {
      left: -15;
    }
               

嵌套规则

  • 使用嵌套规则可以使样式代码看起来更具有层次感。
    /** css代码 **/
    #header { color: black; }
    #header .navigation {
      font-size: 12px;
    }
    #header .logo { 
      width: 300px; 
    }
    #header .logo:hover {
      text-decoration: none;
    }
    
    // less
    #header {
      color: black;
    
      .navigation {
        font-size: 12px;
      }
      .logo {
        width: 300px;
        &:hover { text-decoration: none }
      }
    }
               
  • &:如果写 串联选择器 ,而不是写后代选择器,就可以用到&了。这点对伪类尤其有用如

    :hover

    :focus

    .bordered {
      &.float {
        float: left; 
      }
      .top {
        margin: 5px; 
      }
    }
    
    /** 编译为css**/
    .bordered.float {
      float: left;  
    }
    .bordered .top {
      margin: 5px;
    }
               

运算

  • 任何数字、颜色和变量都可以进行运算。
    @base: 5%;
    @filler: @base * 2;
    @other: @base + @filler;
    
    color: #888 / 4;
    background-color: @base-color + #111;
    height: 100% / 2 + @filler;
               
  • LESS 的运算已经超出了我们的期望,它能够分辨出颜色和单位。括号也同样允许使用。并且可以在复合属性中进行运算。
    @var: 1px + 5;
    /* 6px */
    
    width: (@var + 5) * 2;
    /* width:22px; */
    
    border: (@width * 2) solid black;
    /* border: 44px solid black; */
               

Color 函数

  • LESS 提供了一系列的颜色运算函数. 颜色会先被转化成 HSL 色彩空间, 然后在通道级别操作:
    lighten(@color, 10%);     // 返回比 @color 亮 10%的颜色
    darken(@color, 10%);      // 返回比 @color 暗 10%的颜色
    
    saturate(@color, 10%);    // 饱和度增加 10%
    desaturate(@color, 10%);  // 饱和度减少 10%
    
    fadein(@color, 10%);      //透明度减少 10%
    fadeout(@color, 10%);     // 透明度增加 10%
    fade(@color, 50%);        // 设置透明度 50%
    
    spin(@color, 10);         // 返回颜色比@color大10度的颜色
    spin(@color, -10);        // 返回比@color小10度的颜色
    
    mix(@color1, @color2);    // 返回 @color1 和 @color2 的混合
               
  • 在一种颜色的通道上创建另一种颜色:
    hue(@color);        // 返回@color的 hue 频道
    saturation(@color); // 返回@color的 饱和度 通道
    lightness(@color);  // 返回@color的 亮度 通道
    
    @new: hsl(hue(@old), 45%, 90%);
               

注:未完待续。