Less

0x01 概述

(1)简介

  • Less 是 Leaner Style Sheets 的缩写
  • Less 是一种向后兼容的 CSS 语言扩展
  • Less 是语言,Less.js 是将 Less 样式转换为 CSS 样式的 Javascript 工具
  • 2024 年 4 月 Less.js 最新版本为 v4.2

(2)概念

a. 变量

  • 在单个位置控制常用值

  • Less 语言描述

    @width: 10px;
    @height: @width + 10px;
    
    div {
      width: @width;
      height: @height;
    }
    
  • 转换为 CSS

    div {
      width: 10px;
      height: 20px;
    }
    

b. 混入

  • 将一组属性从一个规则集中包含(混合进入)到另一个规则集中

    .bordered {
      border-top: 1px solid black;
      border-left: 2px solid black;
    }
    
    h1 {
      .bordered()
    }
    
    p {
      .bordered()
    }
    

c. 嵌套

  • 结合或代替级联使用

    div {
      background-color: red;
      h1 {
        color: aqua;
      }
      p {
        font-size: large;
      }
    }
    
    • @ 规则和冒泡:@ 规则放在最前面,与同一规则集中其他元素的相对顺序保持不变,称为冒泡

      body {
        width: 300px;
        @media (min-width: 768px) {
          width: 600px;
          @media  (min-resolution: 192dpi) {
            background-color: red;
          }
        }
        @media (min-width: 1280px) {
          width: 800px;
        }
      }
      

d. 操作

  • 使用算术运算对数字、颜色或变量进行运算

  • 数学运算会考虑单位并在加、减或比较之前转换数字,如果转换不可能或没有意义,则忽略单位

    // 数字被转换成相同的单位
    @conversion-1: 5cm + 10mm; // 6cm
    @conversion-2: 2 - 3cm - 5mm; // -1.5cm
    
    // 不可能转换
    @incompatible-units: 2 + 5px - 3cm; // 4px
    
    // 带有变量的示例
    @base: 5%;
    @filler: @base * 2; // 10%
    @other: @base + @filler; // 15%
    
    // 颜色计算
    @color: (#224488 / 2); // #112244
    background-color: #112244 + #111; // #223355
    
  • 乘法和除法不转换数字

    @base: 2cm * 3mm; // 6cm
    
  • v4.0 开始,除法必须在括号内执行

    @color: #222 / 2; // #222 / 2
    background-color: (#FFFFFF / 16); // #101010
    
  • v3.0 calc() 不计算数学表达式,但会计算嵌套函数中的变量和数学运算式

    @var: 50vh/2;
    width: calc(50% + (@var - 20px));  // calc(50% + (25vh - 20px))
    

e. 转义

  • 允许使用任意字符串作为属性或变量值

    // 以下写法需要 v3.5+,否则需要使用引号转义:@min768: ~"(min-width: 768px)" {...}
    @min768: (min-width: 768px);
    .element {
      @media @min768 {
        font-size: 1.2rem;
      }
    }
    

f. 函数

  • 可以转换颜色、操作字符串和进行数学运算,由 Less 提供

    @base: #f04615;
    @width: 0.5;
    
    .class {
      width: percentage(@width); // 浮点数转换为百分比
      color: saturate(@base, 5%); // 饱和度增加 5%
      background-color: spin(lighten(@base, 25%), 8); // 颜色加亮 25% 并旋转 8 度
    }
    

g. 命名空间与访问器

  • 对混入进行分组并重用或分发

    #divs {
      .button {
        border: 3px solid black;
        &:hover {	// & 代表当前选择器父级
          border: none;
        }
      }
      .p {
        // ...
      }
    }
    
    #login {
      #divs.button();	// 或写成 #divs > .button
    }
    

h. 映射

  • 使用混入和规则集作为值映射

    #colors() {
      primary: blue;
      secondary: green;
    }
    
    .button {
      color: #colors[primary];
      border: 1px solid #colors[secondary];
    }
    

i. 作用域

  • 在本地查找变量和混入,如果找不到,则从“父级”作用域继承

    @var: red;
    
    #page {
      @var: white;
      #header {
        color: @var;	// white
      }
    }
    

j. 注释

  • 块式注释(多行)和行内注释(单行)都可以使用

    /*
     * line 1
     * line 2
     */
    
    // line
    

k. 导入

  • 导入 .less 文件并使用其中的变量

    @import "main";	// main.less
    @import "style.css";
    

0x02 使用 Less.js

(1)命令行

  1. 使用命令 npm install less -g 全局安装 Less.js 以及 lessc 命令
    • 使用命令 npm install less --save-dev 项目级安装 Less.js 以及 lessc 命令
    • lessc 全称是 Less Compiler
  2. 使用命令 lessc -v 确认安装是否成功
  3. 使用命令 lessc file.less file.css 将 file.less 编译为 file.css

其他 lessc 命令:

  • lessc -h:显示帮助信息
  • lessc -M:将 makefile 导入依赖列表
  • lessc -s:停止显示任何警告

(2)浏览器

a. 引入

  1. 引入 file.less

    <head>
      <!-- ... -->
      <link rel="stylesheet/less" type="text/css" href="file.less" />
    </head>
    
  2. 下载 Less.js 并引入

    <head>
      <!-- ... -->
      <link rel="stylesheet/less" type="text/css" href="file.less" />
      <script src="./less.js" type="text/javascript"></script>
    </head>
    

    确保在引入脚本之前引入样式表

b. 配置

  • 通过编程的方式,在脚本标记之前的 less 对象上配置

    <script>
      less = {
        env: "development",
        async: false,
        fileAsync: false,
        poll: 1000,
        functions: {},
        dumpLineNumbers: "comments",
        relativeUrls: false,
        rootpath: ":/example.com/"
      };
    </script>
    <script src="less.js"></script>
    
    • 浏览器中特定于 Less.js 的配置项:

      配置项 类型 说明 默认值
      async Boolean 是否使用异步选项请求导入文件 false
      env String development:当文档的 URL 以 file:// 开头或位于本地计算机上或具有非标准接口时,为开发环境
      production:CSS 缓存在本地,消息不会在控制台输出
      根据 URL
      errorReporting String 设置编译失败时报错的方式,取值包括 html、console、function html
      fileAsync Boolean 在具有文件协议的页面中是否异步请求导入,默认 false false
      logLevel Number Javascript 控制台中日志记录量(除 production 环境) 2
      poll Integer 在监视模式下,轮询之间的时间量,单位为毫秒 1000
      relativeUrls Boolean (可选)将 URL 调整为相对的 false
      useFileCache Boolean 是否使用每个会话文件缓存 true
      v2 之前默认 false
  • 简洁起见,可以将其设置为脚本和链接标签上的属性

    <script src="less.js" data-poll="1000" data-relative-urls="false"></script>
    <link data-dump-line-numbers="all" data-global-vars='{ "myvar": "#ddffee", "mystr": "\"quoted\"" }' rel="stylesheet/less" type="text/css" href="less/styles.less">
    
  • 启用监视模式,需要选项 envdevelopment,在包含 less.js 文件后,调用 less.watch()

    <script>less = { env: 'development'};</script>
    <script src="less.js"></script>
    <script>less.watch();</script>
    
    • 通过将 #!watch 附加到 URL 来临时启用监视模式
  • 启用变量热更新,当使用新值调用时,Less 文件会在不重新加载的情况下重新编译

    <script>
      less.modifyVars({
        '@buttonFace': '#5B83AD',
        '@buttonText': '#D9EEF2'
      });
    </script>
    
  • 可以在 CSS 中输出规则,允许工具定位规则的来源

(3)Less.js 配置

  • 包含路径:lessc --include-path=PATH1;PATH2

    {
      paths: ['PATH1', 'PATH2']
    }
    
    • 如果 @import 规则中的文件在该位置不存在,则 Less 将在传递给此选项的位置查找它
  • 根路径:lessc -rp=resources/

    {
      rootpath: 'resources/'
    }
    
    • 允许在 CSS 中为每个生成的导入和 URL 添加路径
  • 重写 URL:lessc -ru=off / lessc -ru=all / lessc -ru=local

    {
      rewriteUrls: 'off'
      // rewriteUrls: 'all'
      // rewriteUrls: 'local'
    }
    
    • 允许重写导入文件中的 URL,以便 URL 始终相对于已传递给 Less 的基本文件
  • 数学计算:lessc -m=[option]

    {
      math: '[option]'
    }
    
    • 重新构建了数学计算配置项,以提供介于之前的 strictMath 设置和默认设置之间的中间特性
      • strictMath 设置:一直需要括号
      • 默认设置:在所有情况下都执行数学计算
    • [option] 取值:
      • always:v3 默认,在所有情况下都执行数学计算
      • parens-division:v4 默认,除法运算符 / 在括号外不执行除法
        • 但可以使用 ./ 运算符在括号外执行 "forced"
      • parensstrict: 所有数学计算表达式都需要括号
      • strict-legacy:v4 中删除,在某些情况下,如果无法计算表达式的任何部分,则不会作为数学计算处理
  • 严格单位:lessc-su=on

    {
      strictUnits: true
    }
    
    • 如果设置为 off,则 Less 在进行数学计算时会尝试猜测输出单位
  • 全局变量:lessc --global-var="key=value"

    {
      globalVars: {
          key: value
      }
    }
    
    • 定义了一个可以被文件引用的变量
    • 声明放在基本 Less 文件的顶部
    • 在文件中使用时,可以文件中的局部变量覆盖
  • 修改变量:lessc --modify-var="key=value"

    {
      modifyVars: {
          key: value
      }
    }
    
    • 声明放在基本 Less 文件的末尾
    • 会覆盖 Less 文件中定义的任何内容
  • 网址参数:lessc --url-args="arguments"

    {
      urlArgs: 'arguments'
    }
    
    • 允许指定一个参数以继续访问每个 URL
  • 允许从不安全的 HTTPS 主机导入:lessc --insecure

    {
      insecure : true
    }
    
  • 源映射配置

    详细方法参考官方文档

(4)预加载插件

a. 概述

  • 在 Less.js 中开始解析之前加载插件
  • 如果需要添加一个 Less.js 预处理器,那么预加载插件是必要的

b. 使用

  1. 使用命令 npm install [less-plugin-myplugin] 安装某个插件

  2. 使用命令 lessc --[myplugin] 使用安装的某个插件

    • 使用命令 lessc --plugin=[myplugin] 显式指定插件
  3. 使用命令 lessc --[myplugin]="advanced" 将配置传递给插件

  4. 在 Node 中通过 Less.js 加载插件

    var LessPlugin = require("less-plugin-myplugin");
    less.render(myCSS, { plugins: [LessPlugin] }).then(
      function (output) {},
      function (error) {}
    );
    

(5)程序化

  • less 对象的主要入口点是 less.render

    less.render(lessInput, options).then(
      function (output) {
        // output.css = string of css
        // output.map = string of sourcemap
        // output.imports = array of string filenames of the imports referenced
      },
      function (error) {}
    );
    

    less.render(css, options, function (error, output) {});
    

    其中,options 参数可选

  • 如果指定回调,则不会返回 Promise,否则返回

  • 源映射 sourceMap 配置是一个对象,支持设置子 sourceMap 配置,如 sourceMapURLsourceMapBasepathsourceMapRootpathoutputSourceFilessourceMapFileInline

    不适用于浏览器编译器中的 Less.js

    less.render(lessInput).then(function (output) {
      // output.css = string of css
      // output.map = undefined
    });
    less.render(lessInput, { sourceMap: {} }).then(function (output) {
      // output.css = string of css
      // output.map = string of sourcemap
    });
    
  • 可以添加日志监听器

    less.logger.addListener({
      debug: function (msg) {},
      info: function (msg) {},
      warn: function (msg) {},
      error: function (msg) {},
    });
    
    • 错误不会被记录,而是被传递回 less.render 中的回调函数或 Promise

0x03 函数

(1)逻辑函数

if

  • 作用:根据条件返回两个值之一

  • 语法:if(condition, value1, value2)

    • condition 参数支持的布尔表达式与守卫声明相同

    • 在 Less v3.6 之前需要给 condition 参数添加括号

      div {
        margin: if((1<2), 1px, 0);
      }
      
  • 举例:

    • Less

      div {
        margin: if(1<2, 1px, 0);
      }
      
    • CSS

      div {
        margin: 1px;
      }
      

boolean

  • 作用:进行逻辑判断并存储结果布尔值,以供后续在守卫或 if 函数中使用

  • 语法:boolean(condition)

  • 举例:

    @condition: boolean(1 < 2);
    
    div {
      margin: if(@condition, 1px, 0);
    }
    

(2)字符串函数

escape

  • 作用:将输入字符串中的特殊字符使用 URL 编码,特殊字符包括空格括号

  • 语法:escape(string)

  • 举例:

    • Less

      div {
        value: escape('a=1');
      }
      
    • CSS

      div {
        value: a%3D1;
      }
      

e

  • 作用:字符串转义,将字符串作为参数并按原样返回其内容,但不带引号

  • 语法:e(string)

  • 举例:

    • Less

      @mscode: "ms:alwaysHasItsOwnSyntax.For.Stuff()" ;
      
      div {
        filter: e(@mscode);
      }
      
    • CSS

      div {
        filter: ms:alwaysHasItsOwnSyntax.For.Stuff();
      }
      

%

  • 作用:格式化一个字符串

  • 语法:%(string, args ...)

    • string:带占位符的字符串
      • 占位符 d, D, a, A 可以替换为任何类型的参数,如果将与字符串结合,则引入整个字符串
        • 引号会保留在字符串中,它们不会被转义
      • 占位符 s, S 可以用任何表达式替换,如果与字符串结合,则仅引入字符串的值
        • 此时引号会被省略
    • args ...:替换占位符的值,可多个
  • 举例:

    • Less

      div {
        ad: %("value1: %a, value2: %d", 1+1, "http://example.com");
        AD: %("value1: %A, value2: %D", 1+1, "http://example.com");
        ss: %("value1: %s, value2: %s", 1+1, "http://example.com");
        SS: %("value1: %S, value2: %S", 1+1, "http://example.com");
      }
      
    • CSS

      div {
        ad: "value1: 2, value2: "http://example.com"";
        AD: "value1: 2, value2: %22http%3A%2F%2Fexample.com%22";
        ss: "value1: 2, value2: http://example.com";
        SS: "value1: 2, value2: http%3A%2F%2Fexample.com";
      }
      

replace

  • 作用:替换字符串中的文本

  • 语法:replace(string, pattern, replacement[, flags])

    • string:需要处理的字符串
    • pattern:需要匹配的字符串或正则表达式
    • replacement:替换内容
    • flags:(可选)正则表达式标志
  • 举例:

    • Less

      div {
        value1: replace("Hello, World!", "World\?", "Less");
        value2: replace("one + one = 2", "one", "1", "gi");
        value3: replace('This is a string.', "(string)\.$", "new $1.");
        value4: replace(~"value-1", '1', '2');
      }
      
    • CSS

      div {
        value1: "Hello, World!";
        value2: "1 + 1 = 2";
        value3: 'This is a new string.';
        value4: value-2;
      }
      

(3)列表函数

length

  • 作用:返回列表长度

  • 语法:length(list)

    • list:逗号或空格分隔的值组成的列表
  • 举例:

    • Less

      @list: "item1", "item2", "item3";
      
      div {
        value1: length(1px solid #123);
        value2: length(@list);
      }
      
    • CSS

      div {
        value1: 3;
        value2: 3;
      }
      

extract

  • 作用:返回列表中指定位置的值

  • 语法:extract(list, index)

    • list:列表
    • index:指定位置
  • 举例:

    • Less

      @list: "item1", "item2", "item3";
      
      div {
        value: extract(@list, 2);
      }
      
    • CSS

      div {
        value: "item2";
      }
      

range

  • 作用:生成范围内的系列值

  • 语法:range([start, ]end[, step])

    • start:(可选)起始值
    • end:终止值
    • step:(可选)步长
  • 举例:

    • Less

      div {
        value1: range(5);
        value2: range(1, 3);
        value3: range(1px, 10px, 2);
      }
      
    • CSS

      div {
        value1: 1 2 3 4 5;
        value2: 1 2 3;
        value3: 1px 3px 5px 7px 9px;
      }
      

each

  • 作用:遍历列表并根据规则集处理每项

  • 语法:each(list, rules)

    • list:列表
    • rules:规则集
  • 举例:

    • Less

      @enum: {
        red: #f55;
        green: #5f5;
        blue: #55f;
      }
      
      div {
        each(@enum, {
          @{key}-@{index}: @value;
        });
      }
      
    • CSS

      div {
        red-1: #f55;
        green-2: #5f5;
        blue-3: #55f;
      }
      
  • 其他特性:

    • 可以设置变量名称

      @enum: {
        red: #f55;
        green: #5f5;
        blue: #55f;
      }
      
      div {
        each(@enum, .(@v, @k, @i){
          @{k}-@{i}: @v;
        });
      }
      
    • 结合 range 模拟 for 循环

      • Less

        each(range(4), {
          div:nth-child(@{value}){
            width: (@value * 50px);
          }
        })
        
      • CSS

        div:nth-child(1) {
          width: 50px;
        }
        div:nth-child(2) {
          width: 100px;
        }
        div:nth-child(3) {
          width: 150px;
        }
        div:nth-child(4) {
          width: 200px;
        }
        

(4)数学函数

ceil

  • 作用:向上取整
  • 语法:ceil(float)

floor

  • 作用:向下取整
  • 语法:floor(float)

percentage

  • 作用:浮点数转换百分比
  • 语法:percentage(float)

round

  • 作用:四舍五入
  • 语法:round(float, integer)
  • 参数说明:
    • float:需要舍入的浮点数
    • integer:保留小数位数

sqrt

  • 作用:求平方根
  • 语法:sqrt(number)

abs

  • 作用:取绝对值,单位不变
  • 语法:abs(number)

三角函数

包括 sincostan,以下以正弦 sin 为例

  • 作用:求正弦值
  • 语法:sin(number)

反三角函数

包括 asinacosatan,以下以反正弦 asin 为例

  • 作用:求反正弦值
  • 语法:asin(float)
  • atan 外,float 取值范围为 \([-1, 1]\)

pi

  • 作用:获取圆周率值
  • 语法:pi()

pow

  • 作用:求乘方
  • 语法:pow(base, exponent)

mod

  • 作用:求模
  • 语法:mod(number1, number2)
    • number1 % number2

min

  • 作用:求最小值
  • 语法:min(args...)
    • args 之间使用逗号隔开

max

  • 作用:求最大值
  • 语法:max(args...)
    • args 之间使用逗号隔开

(5)类型函数

  • 作用:判断值是否为某个类型,并返回布尔值

  • 类型函数包括:

    函数 说明
    isnumber(value) 数字类型判断
    isstring(value) 字符串类型判断
    iscolor(value) 颜色类型判断
    iskeyword(value) 关键字类型判断
    isurl(value) URL 类型判断
    ispixel(value) 像素单位数字类型判断
    isem(value) em 单位数字类型判断
    ispercentage(value) 百分比数字类型判断
    isunit(value, unit) 指定单位数字类型判断
    isruleset(value) 规则集类型判断
    isdeined(value) 已定义变量类型判断

(6)杂项函数

color

  • 作用:解析颜色
  • 语法:color(string)
    • string:指定颜色的字符串

image-size

  • 作用:获取图片尺寸(宽高)
  • 语法:image-size("[filename.jpg/png/...]")

image-width

  • 作用:获取图片宽度
  • 语法:image-width("filename.jpg/png/...")

image-height

  • 作用:获取图片高度
  • 语法:image-height("filename.jpg/png/...")

convert

  • 作用:数字单位转换
  • 语法:convert(number, unit)
    • number:数字,可带单位
    • unit:目标单位

data-uri

  • 作用:

    • 如果没有 MIME,则该函数会从文件名后缀猜测它
    • 如果用户提供了 MIME,并且 MIME 以 ;base64 结尾,则该函数将使用 base64
  • 语法:data-uri([mimetype, ]url)

    • mimetype:(可选)MIME 类型字符串
    • url:需要内联的文件的 URL
  • 举例:

    • Less

      div {
        url1: data-uri('./image.png');
        url2: data-uri('image/png;base64', './image.png');
        url3: data-uri('image/png;UTF-8', './image.png');
      }
      
    • CSS

      div {
        url1: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAACXBIWXMAABJNAAASTQHzl8SnAAAAEXRFWHRTb2Z0d2FyZQBTbmlwYXN0ZV0Xzt0AAAAMSURBVAiZYxBT9wEAAOAAim1ZO2sAAAAASUVORK5CYII=");
        url2: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAACXBIWXMAABJNAAASTQHzl8SnAAAAEXRFWHRTb2Z0d2FyZQBTbmlwYXN0ZV0Xzt0AAAAMSURBVAiZYxBT9wEAAOAAim1ZO2sAAAAASUVORK5CYII=");
        url3: url("data:image/png;UTF-8,%EF%BF%BDPNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%00%01%00%00%00%01%08%02%00%00%00%EF%BF%BDwS%EF%BF%BD%00%00%00%09pHYs%00%00%12M%00%00%12M%01%EF%BF%BD%C4%A7%00%00%00%11tEXtSoftware%00Snipaste%5D%17%EF%BF%BD%EF%BF%BD%00%00%00%0CIDAT%08%EF%BF%BDc%10S%EF%BF%BD%01%00%00%EF%BF%BD%00%EF%BF%BDmY%3Bk%00%00%00%00IEND%EF%BF%BDB%60%EF%BF%BD");
      }
      

default

  • 作用:仅在守卫条件内可用,仅当没有其他 mixin 匹配时才返回 true,否则返回 false

  • 语法:(default())

  • 举例:

    • Less

      .mixin(1)                   {x: 10}
      .mixin(2)                   {y: 20}
      .mixin(@x) when (default()) {z: @x}
      
      .div1 {
        .mixin(1);
      }
      
      .div2 {
        .mixin(10);
      }
      
    • CSS

      .div1 {
        x: 10;
      }
      .div2 {
        z: 10;
      }
      
  • 其他特性:

    • 可以将 default 返回的值与守卫运算符一起使用

      .mixin(@value) when (ispixel(@value)) {width: @value}
      .mixin(@value) when not(default()) {height: (@value / 5)}
      
      .div1 {
        .mixin(100px);
      }
      
      .div2 {
        .mixin(100%);
      }
      
    • 允许在相同的保护条件下,或在具有相同名称的 mixin 的不同条件下,进行多个 default() 调用

      div {
        .m(@x) when (default()), not(default())    {always: @x}
        .m(@x) when (default()) and not(default()) {never:  @x}
      
        .m(1);
      }
      
    • 如果 Less 检测到使用 default() 的多个 mixin 定义之间存在潜在冲突,则会抛出错误

      div {
        .m(@x) when (default())    {}
        .m(@x) when not(default()) {}
      
        .m(1);
      }
      
    • 仅在保护表达式内可用作 Less 内置函数,否则被解释为常规 CSS 值

      div {
        value: default();
      }
      

unit

  • 作用:删除或更改单位
  • 语法:unit(number, unit)
    • number:数字,可带单位
    • unit:(可选)目标单位,省略则删除单位

get-unit

  • 作用:获取数字单位
  • 语法:get-unit(number)

svg-gradient

  • 作用:生成 svg 渐变

  • 语法:svg-gradient(to direction, color1 [percentage1], color2 [percentage2], ...)

    • 必须至少有三个参数
    • to direction:指定渐变类型和方向
    • 其余参数列出颜色及其位置
      • 第一个和最后一个指定颜色的位置是可选的,其余颜色必须指定位置(即百分比)
  • 举例:

    • Less

      .div1 {
        @list: red, green 30%, blue;
        background-image: svg-gradient(to right, @list);
      }
      
      .div2 {
        background-image: svg-gradient(to right, red, green 30%, blue);
      }
      
    • CSS

      .div1 {
        background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201%201%22%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23ff0000%22%2F%3E%3Cstop%20offset%3D%2230%25%22%20stop-color%3D%22%23008000%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%230000ff%22%2F%3E%3C%2FlinearGradient%3E%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22url(%23g)%22%20%2F%3E%3C%2Fsvg%3E');
      }
      .div2 {
        background-image: url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%201%201%22%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%25%22%20y1%3D%220%25%22%20x2%3D%22100%25%22%20y2%3D%220%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%23ff0000%22%2F%3E%3Cstop%20offset%3D%2230%25%22%20stop-color%3D%22%23008000%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22%230000ff%22%2F%3E%3C%2FlinearGradient%3E%3Crect%20x%3D%220%22%20y%3D%220%22%20width%3D%221%22%20height%3D%221%22%20fill%3D%22url(%23g)%22%20%2F%3E%3C%2Fsvg%3E');
      }
      

(7)颜色定义函数

rgb

  • 作用:根据红色、绿色和蓝色十进制值创建不透明颜色对象

  • 语法:rgb(red, green, blue)

    • 每个参数取值范围为 \(0-255\)\(0-100%\)
  • 举例:

    • Less

      div {
        color: rgb(255, 50%, 0);
      }
      
    • CSS

      div {
        color: #ff8000;
      }
      

rgba

  • 作用:以十进制的红色、绿色和蓝色值创建透明颜色对象
  • 语法:rgb(red, green, blue, alpha)
    • 每个颜色参数取值范围为 \(0-255\)\(0-100%\)
    • alpha:透明度参数,取值范围为 \(0-1\)\(0-100%\)

argb

  • 作用:与 rgba 类似,透明度为第一参数
  • 语法:argb(alpha, red, green, blue)
  • 说明:适用于 IE、.NET、Android 开发

hsl

  • 作用:根据色调、饱和度和亮度值创建不透明颜色对象
  • 语法:hsl(hue, saturation, lightness)
    • hue:色调参数,取值范围 \(0-360\)
    • 饱和度参数和亮度参数取值范围为 \(0-1\)\(0-100%\)

hsla

  • 作用:根据色调、饱和度和亮度值创建透明颜色对象
  • 语法:hsl(hue, saturation, lightness, alpha)

hsv

  • 作用:根据色调、饱和度和明度值创建不透明颜色对象
  • 语法:hsl(hue, saturation, value)
    • hue:色调参数,取值范围 \(0-360\)
    • 饱和度参数和明度参数取值范围为 \(0-1\)\(0-100%\)

hsva

  • 作用:根据色调、饱和度和明度值创建透明颜色对象
  • 语法:hsl(hue, saturation, value, alpha)

(8)颜色通道函数

  • 颜色通道函数包括:

    函数 说明
    alpha(color) 提取颜色对象的 Alpha 通道
    red(color) 提取颜色对象的红色通道
    green(color) 提取颜色对象的绿色通道
    blue(color) 提取颜色对象的蓝色通道
    hue(color) 提取 HSL 颜色空间内颜色对象的色调通道
    saturation(color) 提取 HSL 颜色空间内颜色对象的饱和度通道
    lightness(color) 提取 HSL 颜色空间内颜色对象的亮度通道
    hsvhue(color) 提取 HSV 颜色空间内颜色对象的色调通道
    hsvsaturation(color) 提取 HSV 颜色空间内颜色对象的饱和度通道
    hsvvalue(color) 提取 HSV 颜色空间内颜色对象的明度通道
    luma(color) 计算颜色对象的 luma(感知亮度)
    luminance(color) 计算没有 gamma 校正的 luma 值

(9)颜色运算函数

a. 透明度运算函数

  • fade(color, amount):设置颜色对象的绝对不透明度
  • fadeout(color, amount[, method]):增加颜色对象的透明度
  • fadein(color, amount[, method]):降低颜色对象的透明度
  • 参数说明:
    • color:颜色对象
    • amount:变化量,取值范围 \(0-100%\)
    • method:(可选)设置为 relative 可以相对于当前值进行调整,默认为绝对调整

b. HSL 色调运算函数 spin

  • 作用:沿某一方向旋转颜色的色调角度
  • 语法:spin(color, angle)
    • color:颜色对象
    • angle:色调旋转角度,使用正负号控制方向,取值范围为 \(0-360\)

c. HSL 饱和度运算函数

  • saturate(color, amount[, method]):增加 HSL 颜色空间内颜色对象的饱和度
  • desaturate(color, amount[, method]):减少 HSL 颜色空间内颜色对象的饱和度
  • geryscale(color):去除饱和度,相当于 desaturate(@color, 100%)

d. HSL 亮度运算函数

  • lighten(color, amount[, method]):增加 HSL 颜色空间内颜色对象的亮度
  • darken(color, amount[, method]):减少 HSL 颜色空间内颜色对象的亮度

e. 比例混合运算函数

  • mix(color1, color2[, weight]):将两种颜色按可变比例混合在一起
    • weight:(可选),颜色间平衡点,取值范围 \(0-100%\),默认 50%
  • tint(color[, weight]):与白色混合,相当于 mix(#fff, @color[, @weight])
  • shade(color[, weight]):与黑色混合,相当于 mix(#000, @color[, @weight])

f. 对比色运算函数 contrast

  • 作用:选择两种颜色中哪一种颜色与另一种颜色形成最大对比

  • 语法:contrast(color, dark, light, threshold)

    • color:需要处理的颜色对象
    • dark:指定深色,默认黑色
    • light:指定浅色,默认白色
    • threshold:指定从 darklight 的过渡位置,取值范围 \(0-100%\),默认 43%
  • 举例:

    • Less

      div {
        color1: contrast(#bbbbbb);
        color2: contrast(#222222, #101010);
        color3: contrast(#222222, #101010, #dddddd);
        color4: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 30%);
        color5: contrast(hsl(90, 100%, 50%), #000000, #ffffff, 80%);
      }
      
    • CSS

      div {
        color1: #000000;
        color2: #ffffff;
        color3: #dddddd;
        color4: #000000;
        color5: #ffffff;
      }
      

(10)颜色混合函数

multiply

  • 作用:将两种颜色相乘,即将两种颜色中各自相应的 RGB 通道相乘并除以 255,生成的颜色较暗
  • 语法:multiply(color1, color2)

screen

  • 作用:与 multiply 类似,区别在于生成的颜色更亮
  • 语法:screen(color1, color2)

overlay

  • 作用:与 multiplyscreen 类似,区别在于生成颜色的亮暗与第一个颜色对象(基色)相关
  • 语法:overlay(color1, color2)

softlight

  • 作用:与 overlay 类似,区别在于可以避免纯黑或纯白
  • 语法:softlight(color1, color2)

hardlight

  • 作用:与 overlay 类似,区别在于第二个颜色对象为基色
  • 语法:hardlight(color1, color2)

difference

  • 作用:将两种颜色相减,即第一种颜色减去第二种颜色中相应的 RGB 通道
  • 语法:difference(color1, color2)

exclusion

  • 作用:与 difference 类似,区别在于对比度更低
  • 语法:exclusion(color1, color2)

average

  • 作用:计算两种颜色的平均值
  • 语法:average(color1, color2)

negation

  • 作用:对 difference 执行相反的操作
  • 语法:negation(color1, color2)

0x04 高级

(1)变量

  • 变量是一种从单个位置控制重复出现的值的方法,从而使代码更易于维护

a. 可变插值

  • 选择器

    @selector: content;
    
    .@{selector} {
      width: 500px;
      height: 500px;
    }
    
  • URL

    @images: "./assets/images";
    
    body {
      background-image: url("@{images}/image.png");
    }
    
  • 导入语句 @import

    @source: "./src";
    
    @import "@{source}/style.less";
    
  • 属性 @property

    @property: color;
    
    body {
      @{property}: #f00;
      background-@{property}: #0f0;
    }
    

b. 可变变量

  • 可以使用另一个变量定义一个变量的名称

  • 举例:

    • Less

      @green: #5f5;
      
      div {
        @color: green;
        button {
          color: @@color;
        }
      }
      
    • CSS

      div button {
        color: #5f5;
      }
      

c. 延迟加载

  • 变量在使用前不必声明

    div {
      width: @size;
    }
    
    @size: 10px;
    
  • 两次定义变量时,使用变量的最后定义,从当前作用域向上搜索

d. 属性变量

  • 使用 $ 将属性视为变量

    div {
      color: #00f;
      background-color: $color;
    }
    
  • v3.0.0 开始可用

e. 默认变量

  • 仅当变量尚未设置时才设置该变量

  • 举例:

    • lib.less

      @base-color: green;
      @dark-color: darken(@base-color, 10%);
      
    • demo.less

      @import "lib.less";
      @base-color: red;
      
      div {
        color: @dark-color;
      }
      
    • CSS

      div {
        color: #cc0000;
      }
      

    由于延迟加载,@base-color 被覆盖,@dark-color 为深红色

(2)父级选择器

  • & 运算符表示嵌套规则的父级选择器,可以修改类或伪类应用于现有选择器

    button {
      color: red;
      &:hover {
        color: green;
      }
    }
    
  • 也可以用于生成重复的类名

    .container {
      &-left {
        color: red;
      }
      &-main {
        color: green;
      }
      &-right {
        color: blue;
      }
    }
    
  • 可以重复引用父级选择器而不重复命名

    .container {
      & + & {
        color: red;
      }
      & & {
        color: green;
      }
      && {
        color: blue;
      }
      &, &-x {
        color: cyan;
      }
    }
    
  • 将选择器添加到继承的(父级)选择器之前

    • Less

      main {
        div {
          color: red;
          button & {
            color: green;
          }
        }
      }
      
    • CSS

      main div {
        color: red;
      }
      button main div {
        color: green;
      }
      
  • 也可以在逗号分隔列表中生成选择器的所有可能排列

    header, main, footer {
      & + & {
        color: red;
      }
    }
    

(3)@import 规则

  • @import 可以从其他样式表导入样式
  • 相比 CSS,Less 中的 @import 不一定须要放在所有规则之前

a. 文件扩展名

  • 扩展名为 .css 时,会被视为 CSS 并保持 @import 语句原样

    @import "style.css";
    
  • 扩展名为 .less 时,会被视为 Less 并导入

    @import "library.less";
    
  • 如果扩展名不存在,或不是 .css.less 其中之一,也会被视为 Less 并导入

    @import "lib";
    @import "lib.php"
    

b. 导入功能配置

  • 语法:@import (config) "*.*"
  • config 取值说明:
    • reference:使用 Less 文件但不输出它
    • inline:在输出中包含源文件但不处理它
    • less:将文件视为 Less 文件,无论文件扩展名是什么
    • css:将文件视为 CSS 文件,无论文件扩展名是什么
    • once:(默认)只包含文件一次
    • multiple:包含文件多次
    • optional:找不到文件时继续编译

*(4)继承

(5)合并属性

  • 允许将来自多个属性的值聚合到单个属性下的逗号或空格分隔列表中

  • 逗号举例:

    • Less

      .mixin() {
        value+: 1 2 3;
      }
      
      div {
        .mixin();
        value+: a b c;
      }
      
    • CSS

      div {
        value: 1 2 3, a b c;
      }
      
  • 空格举例:

    • Less

      .mixin() {
        value+_: 1 2 3;
      }
      
      div {
        .mixin();
        value+_: a b c;
      }
      
    • CSS

      div {
        value: 1 2 3 a b c;
      }
      

*(6)混入

(7)分离规则集

a. 概述

  • 分离的规则集是一组 CSS 属性、嵌套规则集、媒体声明或存储在变量中的任何其他内容

    • Less

      @ruleset: {
        background-image: url(./image.png);
        background-attachment: fixed;
        background-position: center center;
        background-repeat: no-repeat;
        background-size: cover;
      }
      
      body {
        @ruleset();
      }
      
    • CSS

      body {
        background-image: url(./image.png);
        background-attachment: fixed;
        background-position: center center;
        background-repeat: no-repeat;
        background-size: cover;
      }
      
  • 可以定义一个混入来抽象出封装媒体查询中的一段代码或不支持的浏览器类名

    • Less

      .desktop-and-old-ie(@rules) {
        @media screen and (min-width: 1200px) { @rules(); }
        html.lt-ie9 & { @rules(); }
      }
      
      header {
        background-color: blue;
      
        .desktop-and-old-ie({
          background-color: red;
        });
      }
      
    • CSS

      header {
        background-color: blue;
      }
      @media screen and (min-width: 1200px) {
        header {
          background-color: red;
        }
      }
      html.lt-ie9 header {
        background-color: red;
      }
      

b. 作用域

  • 分离的规则集可以在定义和调用的地方使用所有可访问的变量和混入

  • 声明作用域是定义分离规则集主体的作用域

  • 定义和调用者作用域可见性

    • 一个分离的规则集可以看到调用者的变量和混合
  • 引用不会修改分离的规则集作用域

    • 规则集不会仅仅通过在此处被引用而获得对新作用域的访问权限
  • 解锁将修改分离的规则集作用域

    • 分离的规则集通过在作用域内解锁(导入)来获得访问权限

c. 访问器

  • 从 Less 3.5 开始,可以使用属性或变量访问器从变量分离的规则集中选择一个值

    • Less

      @config: {
        option1: true;
        option2: false;
      }
      
      .mixin() when (@config[option1] = true) {
        selected: value;
      }
      
      div {
        .mixin();
      }
      
    • CSS

      div {
        selected: value;
      }
      
  • 如果查找返回的是另一个分离的规则集,则可以使用第二个查找来获取该值

    • Less

      @config: {
        @colors: {
          blue: #55f;
        }
      }
      
      div {
        color: @config[@colors][blue];
      }
      
    • CSS

      div {
        color: #55f;
      }
      
  • 返回的查找值本身可以是可变的

    • Less

      @config: {
        @dark: {
          color: darkblue;
        }
        @light: {
          color: lightblue;
        }
      }
      
      div {
        @lookup: dark;
        color: @config[@@lookup][color];
      }
      
    • CSS

      div {
        color: darkblue;
      }
      

(8)映射

  • 通过将命名空间与查找 [] 语法相结合,可以将规则集混入转换为映射

  • 规则集

    • 举例:

      • Less

        @map: {
          key1: value1;
          key2: value2;
        }
        
        div {
          value: @map[key2];
        }
        
      • CSS

        div {
          value: value2;
        }
        
    • 如果查找值生成另一个规则集,你可以附加第二个 [] 查找

      @grand: {
        @parent: {
          child: true
        }
      }
      
      & when (@grand[@parent][child] = true) {
        div {
          color: red;
        }
      }
      
  • 由于命名空间和重载混入的能力,混入比映射更通用

    • 举例:

      • Less

        #lib() {
          .colors() {
            red: #f55;
            green: #5f5;
          }
        }
        
        #lib() {
          .colors() { red: #faa; }
        }
        
        .button {
          color: #lib.colors[red];
          background-color: #lib.colors[green];
        }
        
      • CSS

        .button {
          color: #faa;
          background-color: #5f5;
        }
        
    • 也可以通过混入别名方法简化上述代码

      .button {
        @colors: #lib.colors();
        color: @colors[red];
        background-color: @colors[green];
      }
      
  • 如果希望键名本身是可变的,可以使用可变变量 @@variable 语法

    • Less

      .grand() {
        @parent: 123;
      }
      
      @child: parent;
      
      div {
        value: .grand[@@child];
      }
      
    • CSS

      div {
        value: 123;
      }
      

(9)CSS 守卫

  • 将守卫应用于 CSS 选择器,是声明 mixin 后立即调用它的语法糖

    div when (@my-option = true) {
      color: red;
    }
    
  • 通过将其与 & 功能相结合来实现 if 类型声明,从而实现对多个守卫进行分组

    & when (@my-option = true) {
      header {
        color: red;
      }
      footer {
        color: green;
      }
    }
    

(10)@plugin 规则

  • 导入 Javascript 插件以添加 Less.js 功能和特性

详细功能参考官方文档,包括:编写插件、插件作用域、空函数、Less.js 插件对象、预加载插件等

posted @ 2024-04-12 20:22  SRIGT  阅读(45)  评论(0编辑  收藏  举报