CSS预处理器
同一类物质,趋同化发展
css 预处理器定义了一种新的语言, 其基本思想是, 用一种专门的编程语言, 为 css 增加一些特性, 将 css 作为目标生成文件。
通俗的讲,用CSS预处理器的语法写,最后在编译成CSS; 因为任何浏览器都无法解析CSS预处理器的语法。
为什么要用CSS预处理器
CSS本身具有如下问题:
- 语法不够强大,比如无法嵌套书写导致模块化开发中需要书写很多重复的选择器;
- 没有变量和合理的样式复用机制,使得逻辑上相关的属性值必须以字面量的形式重复输出,导致难以维护。
这就决定了CSS预处理器要解决的问题:
- 提供 CSS 缺失的样式层复用机制、减少冗余代码,提高样式代码的可维护性。
主流的 CSS 预处理器
- Less
- Sass
- Stylus
Less 的使用
Less 是一种动态样式语言,属于 CSS 预处理器的范畴,它扩展了 CSS 语言,增加了变量、Mixin、函数等特性,使 CSS 更易维护和扩展
因为 Less 和 CSS 非常像,学习很容易。而且 Less 仅对 CSS 语言增加了少许方便的扩展,这就是 Less 如此易学的原因之一。
Less (Less编辑器 ) 是开源的,其第一个版本由 Ruby 写成,但在后续的版本当中,Ruby 逐渐被替换为 JavaScript。受益于JavaScript,LESS可以在客户端上运行(IE6+、Webkit、Firefox),也可以在服务端运行(Node.js 、Rhino)。
Less中可以直接写CSS
编译 less
<style type="text/less">
@fcolor: #900;
@bcolor: #099;
@len: 1000px;
#box {
width: @len;
height: (@len/4);
color: @fcolor;
background: @bcolor;
padding: 20px;
}
</style>
<script src="./less.js"></script>
less.js
<!doctype html>
<html lang="cn-ZH">
<head>
<meta charset="utf-8"></meta>
<title>LESS</title>
<!-- 直接在 style 标签内写 less 代码-->
<style style="text/less">
...
</style>
<!--也可以单独引入 less 文件-->
<link rel="stylesheet/less" type="text/css" href="styles.less">
<!--less.js 可以将上面的 less 编译为 css-->
<script src="https://cdn.bootcss.com/less.js/3.9.0/less.js"></script>
</head>
<body></body>
</html>
vscode 插件自动编译 less
1. vscode 安装扩展 "Easy Less"
2. 创建扩展名是 .less 的文件,在文件中写 less 代码; Easy Less 会自动编译成同名的CSS; 每次保存都会自动编译。
3. html 中使用 link 引入 css 文件
命令行安装 less
此方式需要 node 的支持
安装
npm install less -g
使用
lessc bootstrap.less bootstrap.css
Less 语法
Less 的注释
/* 这是 CSS 注释,会原样编译到 CSS 中 */
// 这是 LESS 注释,不会编译到 CSS 中
块注释和行注释都可以使用:
/* 一个块注释
* style comment! */
@var: red;
// 这一行被注释掉了!
@var: white;
Less 的变量
① 定义变量
定义变量的一般形式:
@变量名:值;
@len: 600px;
@master-red: #900;
@master-green: #080;
@sencond-red: #600;
@width: 10px;
@height: @width + 10px;
如果变量的值有特殊符号(空格短横线):
@变量名:~"值";
@min768: ~"min-width:768px";
@min992: ~"min-width:992px";
@sel02: ~".news li";
② 使用变量
1、将变量作为属性值使用(大部分应用场景):
作为普通属性值只来使用:直接使用
// 直接使用 @变量名
width: @len;
color: @master-green;
background: @master-red;
border: 1px solid @master-green;
@media (@min768) {
.container {
width: 100%;
}
}
2、将变量作为属性名或者选择器使用:
作为选择器和属性名:@{selector的值}
的形式
// @{变量名}
.box {
// 变量作为属性名
@{prop}: 10px 10px;
}
// 变量名作为选择器
@{sel01} {
width: @len;
height: (@len/2);
}
@width: 500px;
@g:grey;
@w:wrap;
@bg:background;
#@{w}{
width: @width;
height: 400px;
@{bg}: pink;
}
#header {
width: @width;
@{bg}: @g;
}
编译为:
#wrap {
width: 500px;
height: 400px;
background: pink;
}
#header {
width: 500px;
background: gray;
}
作用域:
- 首先在本地查找变量和混合函数
- 如果找不到它们,则从“父”范围继承。
延迟加载(懒加载),是作用域基础上的特性:
- 先找子元素,如果出现两个相同的变量,我们拿后边的
- 再找父元素,把子元素的东西排除掉
- 如果当前找不到这个变量,他需要到上一层去找
Less 混合 (mixins)
混合就是将一系列属性从一个规则集引入到另一个规则集的方式,类似于 JavaScript 中的函数, 目的是提高代码的重用性。
① 混合
定义混合:
.center-box01() {
position: absolute;
width: 400px;
height: 300px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -150px;
}
使用混合:
.item {
// 调用混合
.center-box01();
}
.news li {
// 调用混合
.center-box01();
// 其他样式
background: #900;
border: 1px solid #999;
}
.a {
color: red;
}
.mixin-class {
.a();
}
.mixin-id {
.a();
}
编译为:
.a {
color: red;
}
.mixin-class {
color: red;
}
.mixin-id {
color: red;
}
② 带参数的混合
定义带参数的混合:
// 定义混合 有参数
.center-box02(@width, @height) {
position: absolute;
width: @width;
height: @height;
left: 50%;
top: 50%;
margin-left: -(@width/2);
margin-top: -(@height/2);
}
使用有参数的混合:
// 调用有参数的混合 按照顺序传参数
.center-box02(600px,500px);
// 调用有参数的混合 按照名字传参
.center-box02(@height:600px, @width:700px);
.border-radius(@radius) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.border-radius(4px);
}
.button {
.border-radius(6px);
}
编译为:
#header {
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius 4px;
}
.button {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius 6px;
}
③ 参数有默认值的混合
// 定义混合 参数设置默认值
// 有默认值的参数在后面
// 可以按照顺序传参,也可以按照名字传参
.center-box03(@width, @height:800px) {
position: absolute;
width: @width;
height: @height;
left: 50%;
top: 50%;
margin-left: -(@width/2);
margin-top: -(@height/2);
}
// 有默认值的参数在前面后面都可以
// 只能按照名字传参
.center-box04(@width:1200px, @height) {
position: absolute;
width: @width;
height: @height;
left: 50%;
top: 50%;
margin-left: -(@width/2);
margin-top: -(@height/2);
}
.border-radius(@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
border-radius: @radius;
}
#header {
.border-radius();
}
.button {
.border-radius(6px);
}
编译为:
#header {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius 5px;
}
.button {
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius 6px;
}
④ @arguments
所有参数组成的列表
// @arguments 获取参数列表
.box-shadow(@x, @y, @b, @o, @color) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
-o-box-shadow: @arguments;
box-shadow: @arguments;
}
.box {
width: 400px;
height: 300px;
background: #900;
.box-shadow(3px, 10px, 15px, 0px, #ccc);
}
.box-shadow(@x: 0; @y: 0; @blur: 1px; @color: #000) {
-webkit-box-shadow: @arguments;
-moz-box-shadow: @arguments;
box-shadow: @arguments;
}
.big-block {
.box-shadow(2px; 5px);
}
编译为:
.big-block {
-webkit-box-shadow: 2px 5px 1px #000;
-moz-box-shadow: 2px 5px 1px #000;
box-shadow: 2px 5px 1px #000;
}
⑤多个参数的混合
.mixin(@color: black; @margin, @padding: 20px) {
color: @color;
margin: @margin;
padding: @padding;
}
.class1 {
.mixin(@margin: 20px; @color: #33acfe);
}
.class2 {
.mixin(#efca44; @padding: 40px);
}
编译为:
.class1 {
color: #33acfe;
margin: 20px;
padding: 20px;
}
.class2 {
color: #efca44;
margin: 10px;
padding: 40px;
}
⑥不带输出的混合
.my-mixin {
color: black;
}
// 该混合不会被输出
.my-other-mixin() {
background: white;
}
.class {
.my-mixin();
.my-other-mixin();
}
编译为:
.my-mixin {
color: black;
}
.class {
color: black;
background: white;
}
Less 条件判断
Less 可以使用 when 关键字实现条件判断
.triangle(@border-width, @color, @direction) when (@direction=up) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: transparent transparent @color transparent;
}
.triangle(@border-width, @color, @direction) when (@direction=down) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: @color transparent transparent transparent;
}
.triangle(@border-width, @color, @direction) when (@direction=left) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: transparent @color transparent transparent;
}
.triangle(@border-width, @color, @direction) when (@direction=right) {
width: 0;
height: 0;
border-style: solid;
border-width: @border-width;
border-color: transparent transparent transparent @color;
}
less条件判断案例--混合的递归调用--栅格动态响应系统
.grid(@type:xs) {
//条件判断:当数量小于栅格列数
.make-col(@num) when (@num <= @columns) {
//变量名拼接 作为类名传入
.col-@{type}-@{num} {
width: percentage((@num/@columns))
}
.make-col(@num+1);
}
.make-col(1);
}
Less 导入
导入 less 文件:
// 将 文件名.less 中的内容编译到 css 中
@import "文件名.less";
// 可以省略扩展名
@import "文件名"
导入 css 文件:
// 原样编译到 css 中
@import "文件名.css";
常用作导入变量
index.less 入口文件
// 导入变量文件
@import "variables";
// 导入重置样式表
@import "reset";
.box {
width: 500px;
color: @master-red;
}
variables.less
@master-red: #900;
@second-red: #080;
reset.less
* {
margin: 0;
padding: 0;
font-size: 16px;
}
Less 嵌套
Less 提供了使用嵌套代替层叠或与层叠结合使用的能力
① 基本使用(层级选择器)
.news {
li {} 后代选择器
>li {} 子元素选择器
+li {} 相邻兄弟选择器
~li {} 通用兄弟选择器
}
编译为:
.news {}
.news li {}
.news > li {}
.news + li {}
.news ~ li {}
② & 符号应用(交集选择器组合)
.item {
&:hover {} 交集选择器
&.active {}
}
编译为:
.item {}
.item:hover {}
.item.active {}
③ 媒体查询的嵌套
.container {
width: 100%;
margin-left: auto;
margin-right: auto;
@media (min-width:768px) {
width: 750px;
}
@media (min-width: 992px) {
width: 970px;
}
@media (min-width: 1200px) {
width: 1170px;
}
}
编译为:
.container {
width: 100%;
margin-left: auto;
margin-right: auto;
}
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 992px) {
.container {
width: 970px;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
③media 第二种嵌套方式
@min1024: ~"(min-width: 1024px)";
.element {
font-size: 15px;
@media (min-width:640px) {
font-size: 16px;
}
@media @min1024 {
font-size: 18px;
}
}
编译为:
.element {
font-size: 15px;
}
@media (min-width: 640px) {
.element {
font-size: 16px;
}
}
@media (min-width: 1024px) {
.element {
font-size: 18px;
}
}
④ 混合和嵌套结合
混合里边的变量作用域,在混合调用后才可以使用。(不重要)
.clearfix() {
&::after {
content: "";
display: block;
clear:both;
}
}
Less 运算符
算术运算 +
、-
、 *
、 /
可以对任何数字、颜色或变量进行运算。如果可能的话,数学运算在加、减或比较之前会考虑到单位并转换数字。
结果具有最左边的显式单位类型。如果转换不可能或没有意义,则忽略单位。
1. Less 可以进行 +、-、*、/ 运算
2. 除运算需要使用小括号
3. 如果两个操作数单位不一致,结果使用第一个操作数的单位
如果只有一个操作数有单位,结果就使用该单位
// numbers are converted into the same units
@conversion-1: 5cm + 10mm; // result is 6cm
@conversion-2: 2 - 3cm - 5mm; // result is -1.5cm
// conversion is impossible
@incompatible-units: 2 + 5px - 3cm; // result is 4px
// example with variables
@base: 5%;
@filler: @base * 2; // result is 10%
@other: @base + @filler; // result is 15%
Less 函数
混合(Mixins)类似于 JavaScript 中的自定义函数, 而这里的函数类似于 JavaScript 中的内置函数。
Less 内置了多种函数用于转换颜色、处理字符串、算术运算等。
可以参考 Less 中文网提供的函数手册: http://lesscss.cn/functions/#misc-functions
需要注意的是,一般我们很少会使用这些内置函数。
percentage() 计算百分比
mod() 取余运算
lighten() 颜色调高亮度
darken() 颜色调低亮度
https://less.bootcss.com/functions/
@base: #f04615;
@width: 0.5;
.class {
width: percentage(@width); // 将小数转换为百分比 returns `50%`
color: saturate(@base, 5%); // 将颜色饱和度增加 %5
background-color: spin(lighten(@base, -25%), 8); // 颜色亮度减小 25% 并且色相值增加 8
}
mod(100,6) 4
percentage(.7) 70%
lighten(#900,10%); 颜色调高亮度
darken(#900,10%); 颜色调低亮度
map
less 3.5之后,新增了 map 语法
#colors() {
primary: blue;
secondary: green;
}
.button {
color: #colors[primary];
border: 1px solid #colors[secondary];
}
编译为:
.button {
color: blue;
border: 1px solid green;
}