预编译器基本原理

  1. 编写 css 时,受限于 css 语言本身,常常难以处理一些问题:
    1. 重复的样式值:例如常用颜色、常用尺寸;
    2. 重复的代码段:例如绝对定位居中、清除浮动;
    3. 重复的嵌套书写;
  2. 由于官方迟迟不对 css 语言本身做出改进,一些第三方机构开始想办法来解决这些问题,其中一种方案便是 预编译器,预编译器的原理很简单,即使用一种更加优雅的方式来书写样式代码,通过一个编译器,将其转换为可被浏览器识别的传统 css 代码;
  3. 目前,最流行的预编译器有 LESSSASS

less 的使用

less 安装、编译

  1. 安装:

    # LESS 编译器是基于 node 开发的,可以通过 npm 下载安装
    npm i -D less
    
  2. 编译方法一:在 nodejs 环境中使用 less

    lessc styles.less styles.css
    
  3. 编译方法二:在浏览器环境中使用 less

    <link rel="stylesheet/less" type="text/css" href="styles.less" />
    <script src="http://cdnjs.cloudflare.com/ajax/libs/less.js/2.5.3/less.min.js"></script>
    
  4. 编译方法三:考拉 编译工具

  5. 编译方法四:vscode 插件 easy less

less 的基本使用

变量: 符号@

less
css
@selector: #header; /* 选择器 作为变量 */
@m: margin;         /* 样式名 作为变量 */ 
@width: 10px;       /* 样式值 作为变量 */ 

@{selector} {
    @{m}: 20px;
    width: @width;
    background-color: red;
}
/* less 转换成 css */
#header {
  margin: 20px;
  width: 10px;
  background-color: red;
}

嵌套

less
css
#header {
  color: black;

  /* 父子关系 */
  .logo {
      width: 300px;
  }
}

.clearfix {
  display: block;
  zoom: 1;

  /* & 同级 */
  &:after {
      content: " ";
      display: block;
      font-size: 0;
      height: 0;
      clear: both;
      visibility: hidden;
  }
}

.component {
  width: 300px;

  @media (min-width: 768px) {
      width: 600px;

      @media (min-resolution: 192dpi) {
          background-image: url(/img/retina2x.png);
      }
  }

  @media (min-width: 1280px) {
      width: 800px;
  }
}
/* less 转换成 css */
#header {
  color: black;
}
/* 父子关系 */
#header .logo {
  width: 300px;
}

.clearfix {
  display: block;
  zoom: 1;
}
/* & 同级 */
.clearfix:after {
  content: " ";
  display: block;
  font-size: 0;
  height: 0;
  clear: both;
  visibility: hidden;
}

.component {
  width: 300px;
}
@media (min-width: 768px) {
  .component {
    width: 600px;
  }
}
@media (min-width: 768px) and (min-resolution: 192dpi) {
  .component {
    background-image: url(/img/retina2x.png);
  }
}
@media (min-width: 1280px) {
  .component {
    width: 800px;
  }
}

混合

less
css
.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}
#menu {
  color: antiquewhite;
  .bordered();
}
.post  {
  color: red;
  .bordered();
}
/* less 转换成 css */
.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}
#menu {
  color: antiquewhite;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}
.post {
  color: red;
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

扩展:会把重复的代码抽离出去

less
css
@w: 200px;
@h: 200px;

.block {
    width: @w;
    height: @h;
    border: 10px solid #ccc;
}

.box1:extend(.block) {
    background: red;
}

.box2:extend(.block) {
    background: green;
}
/* less 转换成 css */
.block,
.box1,
.box2 {
  width: 200px;
  height: 200px;
  border: 10px solid #ccc;
}

.box1 {
  background: red;
}

.box2 {
  background: green;
}

命名空间:类似 js 对象.方法

less
css
#bundle() {
  .button {
      display: block;
      border: 1px solid black;
      background-color: grey;
      &:hover {
          background-color: white;
      }
  }
  .tab {
      color: red;
  }
  .citation {
      color: green;
  }
}

#header a {
    color: orange;
    /* 还可以书写为 #bundle > .button 形式 */
    #bundle.button(); 
}
/* less 转换成 css */
#header a {
  color: orange;
  display: block;
  border: 1px solid black;
  background-color: grey;
}
#header a:hover {
  background-color: white;
}

映射

less
css
#colors() {
  primary: blue;
  secondary: green;
}
.button {
  color: #colors[primary];
  border: 1px solid #colors[secondary];
}
/* less 转换成 css */
.button {
  color: blue;
  border: 1px solid green;
}

作用域,先在本级作用域查找,找不到向上查找

less
css
@var: red;

#page {
  #header {
    color: @var;
  }
  @var: white;
}
/* less 转换成 css */
#page #header {
  color: white;
}

循环

less
css
.gen-col(@n) when (@n > 0) {
  /* 递归调用自身 */
  .gen-col(@n - 1);
  .col-@{n} {
      width: 1000px/12*@n;
  }
}

.gen-col(3);
/* less 转换成 css */
.col-1 {
  width: 1000px/12*1;
}
.col-2 {
  width: 1000px/12*2;
}
.col-3 {
  width: 1000px/12*3;
}

导入 import

less
css
/* variable.less */
@themeColor: blue;
@fontSize: 14px;

/* module1.less */
.module1 {
    .box {
        font-size: @fontSize + 2px;
        color: @themeColor;
    }
}

/* module2.less */
.module2 {
    .box {
        font-size: @fontSize + 4px;
        color: @themeColor;
    }
}

/* importing.less */
@import "./variable.less";
@import "./module1.less";
@import "./module2.less";
/* less 转换成 css */
.module1 .box {
  font-size: 16px;
  color: blue;
}

.module2 .box {
  font-size: 18px;
  color: blue;
}

sass 的使用

sass 安装、编译

  1. 安装

    npm i -D sass
    
  2. 编译方法一:命令编译

    sass --watch styles.scss styles.css 
    
  3. 编译方法二:GUI 界面工具编译

    1. Koala - 推荐
    2. Compass.app
    3. Scout
    4. CodeKit - 推荐
    5. Prepros
  4. 编译方法三:自动化编译 (利用 Grunt、Gulp、webpack)

sass 的基本使用

sass 变量: 符号$

scss
css
$nav-color: #F90;
nav {
  $width: 100px;
  width: $width;
  color: $nav-color;
}

/* 将局部变量转换为全局变量可以添加 !global 声明 */ 
#main {
  $width: 5em !global;
  width: $width;
}
#sidebar {
  width: $width;
}
/* scss 转换成 css */
nav {
  width: 100px;
  color: #F90;
}

#main {
  width: 5em;
}
#sidebar {
  width: 5em;
}

sass 嵌套

scss
css
#content {
  article {
    h1 {
      color: #333
    }
    p {
      margin-bottom: 1.4em
    }
  }
  aside {
    background-color: #EEE
  }
}
/* scss 转换成 css */
#content article h1 {
  color: #333;
}

#content article p {
  margin-bottom: 1.4em;
}

#content aside {
  background-color: #EEE;
}

sass 混入: @mixin声明/@include调用

scss
css
/* 公用代码 */ 
@mixin rounded-corners {
    -moz-border-radius: 5px;
    -webkit-border-radius: 5px;
    border-radius: 5px;
}
.notice {
    background-color: green;
    border: 2px solid #00aa00;
    @include rounded-corners;
}

/* 给混合器传参 */
@mixin link-colors($normal, $hover, $visited) {
    color: $normal;
    &:hover { color: $hover; }
    &:visited { color: $visited; }
}
a {
    @include link-colors(blue, red, green);
}
/* scss 转换成 css */
/* 公用代码 */
.notice {
  background-color: green;
  border: 2px solid #00aa00;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
}

/* 给混合器传参 */
a { color: blue; }
a:hover { color: red; }
a:visited { color: green; }

sass 扩展: @extend

scss
css
.error {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  @extend .error;
  border-width: 3px;
}
/* scss 转换成 css */
.error, .seriousError {
  border: 1px #f00;
  background-color: #fdd;
}
.seriousError {
  border-width: 3px;
}

sass 循环

scss
css
/***
  * @for $i from <start> through/to <end>
  *   $i 表示变量
  *   start 表示起始值
  *   end 表示结束值
  *   through 表示包括 end 这个数
  *   to 则不包括 end 这个数
  */
@for $i from 1 through 2 {    
  .col-#{$i} {
      width: 1000px/12*$i;
  }
}
/* scss 转换成 css */
.col-1 {
  width: 83.33333px;
}
.col-2 {
  width: 166.66667px;
}

sass 导入

scss
css
/* variable.scss */
$themeColor: blue;
$fontSize: 14px;

/* module1.scss */
.module1 {
    .box {
        font-size: $fontSize + 2px;
        color: $themeColor;
    }
    .tips {
        font-size: $fontSize;
        color: lighten($themeColor, 40%);
    }
}

/* module2.scss */
.module2 {
    .box {
        font-size: $fontSize + 4px;
        color: $themeColor;
    }
    .tips {
        font-size: $fontSize + 2px;
        color: lighten($themeColor, 20%);
    }
}

/* importing.less */
@import "./variable.scss";
@import "./module1.scss";
@import "./module2.scss";
/* scss 转换成 css */
.module1 .box {
  font-size: 16px;
  color: blue;
}

.module1 .tips {
  font-size: 14px;
  color: #ccccff;
}

.module2 .box {
  font-size: 18px;
  color: blue;
}

.module2 .tips {
  font-size: 16px;
  color: #6666ff;
}

webpack 中使用 less、scss

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    mode: "development",
    devServer: {
        open: true
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ["style-loader", 'css-loader'],
            },
            {
                test: /\.less$/,
                use: ["style-loader", 'css-loader', 'less-loader'],
            },
            {
                test: /\.s[ac]ss$/,
                use: ["style-loader", 'css-loader', 'sass-loader'],
            },
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./public/index.html"
        })
    ]
}
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 预编译器基本原理
  2. 2. less 的使用
    1. 2.1. less 安装、编译
    2. 2.2. less 的基本使用
      1. 2.2.1. 变量: 符号@
      2. 2.2.2. 嵌套
      3. 2.2.3. 混合
      4. 2.2.4. 扩展:会把重复的代码抽离出去
      5. 2.2.5. 命名空间:类似 js 对象.方法
      6. 2.2.6. 映射
      7. 2.2.7. 作用域,先在本级作用域查找,找不到向上查找
      8. 2.2.8. 循环
      9. 2.2.9. 导入 import
  3. 3. sass 的使用
    1. 3.1. sass 安装、编译
    2. 3.2. sass 的基本使用
      1. 3.2.1. sass 变量: 符号$
      2. 3.2.2. sass 嵌套
      3. 3.2.3. sass 混入: @mixin声明/@include调用
      4. 3.2.4. sass 扩展: @extend
      5. 3.2.5. sass 循环
      6. 3.2.6. sass 导入
  4. 4. webpack 中使用 less、scss